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/MipsABIFlagsSection.h"
11 #include "MCTargetDesc/MipsABIInfo.h"
12 #include "MCTargetDesc/MipsBaseInfo.h"
13 #include "MCTargetDesc/MipsMCExpr.h"
14 #include "MCTargetDesc/MipsMCTargetDesc.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCAsmParser.h"
31 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/SubtargetFeature.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/CommandLine.h"
43 #include "llvm/Support/Compiler.h"
44 #include "llvm/Support/Debug.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/MathExtras.h"
47 #include "llvm/Support/SMLoc.h"
48 #include "llvm/Support/SourceMgr.h"
49 #include "llvm/Support/TargetRegistry.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include <algorithm>
52 #include <cassert>
53 #include <cstdint>
54 #include <memory>
55 #include <string>
56 #include <utility>
57
58 using namespace llvm;
59
60 #define DEBUG_TYPE "mips-asm-parser"
61
62 namespace llvm {
63
64 class MCInstrInfo;
65
66 } // end namespace llvm
67
68 extern cl::opt<bool> EmitJalrReloc;
69
70 namespace {
71
72 class MipsAssemblerOptions {
73 public:
MipsAssemblerOptions(const FeatureBitset & Features_)74 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
75
MipsAssemblerOptions(const MipsAssemblerOptions * Opts)76 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
77 ATReg = Opts->getATRegIndex();
78 Reorder = Opts->isReorder();
79 Macro = Opts->isMacro();
80 Features = Opts->getFeatures();
81 }
82
getATRegIndex() const83 unsigned getATRegIndex() const { return ATReg; }
setATRegIndex(unsigned Reg)84 bool setATRegIndex(unsigned Reg) {
85 if (Reg > 31)
86 return false;
87
88 ATReg = Reg;
89 return true;
90 }
91
isReorder() const92 bool isReorder() const { return Reorder; }
setReorder()93 void setReorder() { Reorder = true; }
setNoReorder()94 void setNoReorder() { Reorder = false; }
95
isMacro() const96 bool isMacro() const { return Macro; }
setMacro()97 void setMacro() { Macro = true; }
setNoMacro()98 void setNoMacro() { Macro = false; }
99
getFeatures() const100 const FeatureBitset &getFeatures() const { return Features; }
setFeatures(const FeatureBitset & Features_)101 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
102
103 // Set of features that are either architecture features or referenced
104 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
105 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
106 // The reason we need this mask is explained in the selectArch function.
107 // FIXME: Ideally we would like TableGen to generate this information.
108 static const FeatureBitset AllArchRelatedMask;
109
110 private:
111 unsigned ATReg = 1;
112 bool Reorder = true;
113 bool Macro = true;
114 FeatureBitset Features;
115 };
116
117 } // end anonymous namespace
118
119 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
120 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
121 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
122 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
123 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
124 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
125 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
126 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
127 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
128 };
129
130 namespace {
131
132 class MipsAsmParser : public MCTargetAsmParser {
getTargetStreamer()133 MipsTargetStreamer &getTargetStreamer() {
134 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
135 return static_cast<MipsTargetStreamer &>(TS);
136 }
137
138 MipsABIInfo ABI;
139 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
140 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
141 // nullptr, which indicates that no function is currently
142 // selected. This usually happens after an '.end func'
143 // directive.
144 bool IsLittleEndian;
145 bool IsPicEnabled;
146 bool IsCpRestoreSet;
147 int CpRestoreOffset;
148 unsigned CpSaveLocation;
149 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
150 bool CpSaveLocationIsRegister;
151
152 // Map of register aliases created via the .set directive.
153 StringMap<AsmToken> RegisterSets;
154
155 // Print a warning along with its fix-it message at the given range.
156 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
157 SMRange Range, bool ShowColors = true);
158
159 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
160
161 #define GET_ASSEMBLER_HEADER
162 #include "MipsGenAsmMatcher.inc"
163
164 unsigned
165 checkEarlyTargetMatchPredicate(MCInst &Inst,
166 const OperandVector &Operands) override;
167 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
168
169 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
170 OperandVector &Operands, MCStreamer &Out,
171 uint64_t &ErrorInfo,
172 bool MatchingInlineAsm) override;
173
174 /// Parse a register as used in CFI directives
175 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
176
177 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
178
179 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
180
181 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
182
183 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
184 SMLoc NameLoc, OperandVector &Operands) override;
185
186 bool ParseDirective(AsmToken DirectiveID) override;
187
188 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
189 OperandMatchResultTy
190 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
191 StringRef Identifier, SMLoc S);
192 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
193 const AsmToken &Token,
194 SMLoc S);
195 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
196 SMLoc S);
197 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
198 OperandMatchResultTy parseImm(OperandVector &Operands);
199 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
200 OperandMatchResultTy parseInvNum(OperandVector &Operands);
201 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
202
203 bool searchSymbolAlias(OperandVector &Operands);
204
205 bool parseOperand(OperandVector &, StringRef Mnemonic);
206
207 enum MacroExpanderResultTy {
208 MER_NotAMacro,
209 MER_Success,
210 MER_Fail,
211 };
212
213 // Expands assembly pseudo instructions.
214 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
215 MCStreamer &Out,
216 const MCSubtargetInfo *STI);
217
218 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
219 const MCSubtargetInfo *STI);
220
221 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
222 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
223 MCStreamer &Out, const MCSubtargetInfo *STI);
224
225 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
226 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
227 MCStreamer &Out, const MCSubtargetInfo *STI);
228
229 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
230
231 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
232 MCStreamer &Out, const MCSubtargetInfo *STI);
233
234 bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
235 SMLoc IDLoc, MCStreamer &Out,
236 const MCSubtargetInfo *STI);
237
238 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
239 const MCOperand &Offset, bool Is32BitAddress,
240 SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI);
242
243 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245
246 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI, bool IsLoad);
248
249 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
250 const MCSubtargetInfo *STI);
251
252 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
254
255 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
257
258 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI);
260
261 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI, const bool IsMips64,
263 const bool Signed);
264
265 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
266 MCStreamer &Out, const MCSubtargetInfo *STI);
267
268 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
270
271 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
273
274 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI);
276
277 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
278 MCStreamer &Out, const MCSubtargetInfo *STI);
279 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
281 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
282 const MCSubtargetInfo *STI);
283 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
284 const MCSubtargetInfo *STI);
285
286 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
287 const MCSubtargetInfo *STI);
288
289 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
290 const MCSubtargetInfo *STI);
291
292 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
294
295 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
297
298 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
300
301 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI, bool IsLoad);
303
304 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI);
306
307 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308 const MCSubtargetInfo *STI);
309
310 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
312
313 bool reportParseError(Twine ErrorMsg);
314 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
315
316 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
317
318 bool isEvaluated(const MCExpr *Expr);
319 bool parseSetMips0Directive();
320 bool parseSetArchDirective();
321 bool parseSetFeature(uint64_t Feature);
322 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
323 bool parseDirectiveCpLoad(SMLoc Loc);
324 bool parseDirectiveCpRestore(SMLoc Loc);
325 bool parseDirectiveCPSetup();
326 bool parseDirectiveCPReturn();
327 bool parseDirectiveNaN();
328 bool parseDirectiveSet();
329 bool parseDirectiveOption();
330 bool parseInsnDirective();
331 bool parseRSectionDirective(StringRef Section);
332 bool parseSSectionDirective(StringRef Section, unsigned Type);
333
334 bool parseSetAtDirective();
335 bool parseSetNoAtDirective();
336 bool parseSetMacroDirective();
337 bool parseSetNoMacroDirective();
338 bool parseSetMsaDirective();
339 bool parseSetNoMsaDirective();
340 bool parseSetNoDspDirective();
341 bool parseSetReorderDirective();
342 bool parseSetNoReorderDirective();
343 bool parseSetMips16Directive();
344 bool parseSetNoMips16Directive();
345 bool parseSetFpDirective();
346 bool parseSetOddSPRegDirective();
347 bool parseSetNoOddSPRegDirective();
348 bool parseSetPopDirective();
349 bool parseSetPushDirective();
350 bool parseSetSoftFloatDirective();
351 bool parseSetHardFloatDirective();
352 bool parseSetMtDirective();
353 bool parseSetNoMtDirective();
354 bool parseSetNoCRCDirective();
355 bool parseSetNoVirtDirective();
356 bool parseSetNoGINVDirective();
357
358 bool parseSetAssignment();
359
360 bool parseDirectiveGpWord();
361 bool parseDirectiveGpDWord();
362 bool parseDirectiveDtpRelWord();
363 bool parseDirectiveDtpRelDWord();
364 bool parseDirectiveTpRelWord();
365 bool parseDirectiveTpRelDWord();
366 bool parseDirectiveModule();
367 bool parseDirectiveModuleFP();
368 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
369 StringRef Directive);
370
371 bool parseInternalDirectiveReallowModule();
372
373 bool eatComma(StringRef ErrorStr);
374
375 int matchCPURegisterName(StringRef Symbol);
376
377 int matchHWRegsRegisterName(StringRef Symbol);
378
379 int matchFPURegisterName(StringRef Name);
380
381 int matchFCCRegisterName(StringRef Name);
382
383 int matchACRegisterName(StringRef Name);
384
385 int matchMSA128RegisterName(StringRef Name);
386
387 int matchMSA128CtrlRegisterName(StringRef Name);
388
389 unsigned getReg(int RC, int RegNo);
390
391 /// Returns the internal register number for the current AT. Also checks if
392 /// the current AT is unavailable (set to $0) and gives an error if it is.
393 /// This should be used in pseudo-instruction expansions which need AT.
394 unsigned getATReg(SMLoc Loc);
395
396 bool canUseATReg();
397
398 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
399 const MCSubtargetInfo *STI);
400
401 // Helper function that checks if the value of a vector index is within the
402 // boundaries of accepted values for each RegisterKind
403 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
404 bool validateMSAIndex(int Val, int RegKind);
405
406 // Selects a new architecture by updating the FeatureBits with the necessary
407 // info including implied dependencies.
408 // Internally, it clears all the feature bits related to *any* architecture
409 // and selects the new one using the ToggleFeature functionality of the
410 // MCSubtargetInfo object that handles implied dependencies. The reason we
411 // clear all the arch related bits manually is because ToggleFeature only
412 // clears the features that imply the feature being cleared and not the
413 // features implied by the feature being cleared. This is easier to see
414 // with an example:
415 // --------------------------------------------------
416 // | Feature | Implies |
417 // | -------------------------------------------------|
418 // | FeatureMips1 | None |
419 // | FeatureMips2 | FeatureMips1 |
420 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
421 // | FeatureMips4 | FeatureMips3 |
422 // | ... | |
423 // --------------------------------------------------
424 //
425 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
426 // FeatureMipsGP64 | FeatureMips1)
427 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
selectArch(StringRef ArchFeature)428 void selectArch(StringRef ArchFeature) {
429 MCSubtargetInfo &STI = copySTI();
430 FeatureBitset FeatureBits = STI.getFeatureBits();
431 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
432 STI.setFeatureBits(FeatureBits);
433 setAvailableFeatures(
434 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
435 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
436 }
437
setFeatureBits(uint64_t Feature,StringRef FeatureString)438 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
439 if (!(getSTI().getFeatureBits()[Feature])) {
440 MCSubtargetInfo &STI = copySTI();
441 setAvailableFeatures(
442 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
443 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
444 }
445 }
446
clearFeatureBits(uint64_t Feature,StringRef FeatureString)447 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
448 if (getSTI().getFeatureBits()[Feature]) {
449 MCSubtargetInfo &STI = copySTI();
450 setAvailableFeatures(
451 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
452 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
453 }
454 }
455
setModuleFeatureBits(uint64_t Feature,StringRef FeatureString)456 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
457 setFeatureBits(Feature, FeatureString);
458 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
459 }
460
clearModuleFeatureBits(uint64_t Feature,StringRef FeatureString)461 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
462 clearFeatureBits(Feature, FeatureString);
463 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
464 }
465
466 public:
467 enum MipsMatchResultTy {
468 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
469 Match_RequiresDifferentOperands,
470 Match_RequiresNoZeroRegister,
471 Match_RequiresSameSrcAndDst,
472 Match_NoFCCRegisterForCurrentISA,
473 Match_NonZeroOperandForSync,
474 Match_NonZeroOperandForMTCX,
475 Match_RequiresPosSizeRange0_32,
476 Match_RequiresPosSizeRange33_64,
477 Match_RequiresPosSizeUImm6,
478 #define GET_OPERAND_DIAGNOSTIC_TYPES
479 #include "MipsGenAsmMatcher.inc"
480 #undef GET_OPERAND_DIAGNOSTIC_TYPES
481 };
482
MipsAsmParser(const MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)483 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
484 const MCInstrInfo &MII, const MCTargetOptions &Options)
485 : MCTargetAsmParser(Options, sti, MII),
486 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
487 sti.getCPU(), Options)) {
488 MCAsmParserExtension::Initialize(parser);
489
490 parser.addAliasForDirective(".asciiz", ".asciz");
491 parser.addAliasForDirective(".hword", ".2byte");
492 parser.addAliasForDirective(".word", ".4byte");
493 parser.addAliasForDirective(".dword", ".8byte");
494
495 // Initialize the set of available features.
496 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
497
498 // Remember the initial assembler options. The user can not modify these.
499 AssemblerOptions.push_back(
500 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
501
502 // Create an assembler options environment for the user to modify.
503 AssemblerOptions.push_back(
504 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
505
506 getTargetStreamer().updateABIInfo(*this);
507
508 if (!isABI_O32() && !useOddSPReg() != 0)
509 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
510
511 CurrentFn = nullptr;
512
513 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
514
515 IsCpRestoreSet = false;
516 CpRestoreOffset = -1;
517
518 const Triple &TheTriple = sti.getTargetTriple();
519 IsLittleEndian = TheTriple.isLittleEndian();
520
521 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
522 report_fatal_error("microMIPS64R6 is not supported", false);
523
524 if (!isABI_O32() && inMicroMipsMode())
525 report_fatal_error("microMIPS64 is not supported", false);
526 }
527
528 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
hasEightFccRegisters() const529 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
530
isGP64bit() const531 bool isGP64bit() const {
532 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
533 }
534
isFP64bit() const535 bool isFP64bit() const {
536 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
537 }
538
getABI() const539 const MipsABIInfo &getABI() const { return ABI; }
isABI_N32() const540 bool isABI_N32() const { return ABI.IsN32(); }
isABI_N64() const541 bool isABI_N64() const { return ABI.IsN64(); }
isABI_O32() const542 bool isABI_O32() const { return ABI.IsO32(); }
isABI_FPXX() const543 bool isABI_FPXX() const {
544 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
545 }
546
useOddSPReg() const547 bool useOddSPReg() const {
548 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
549 }
550
inMicroMipsMode() const551 bool inMicroMipsMode() const {
552 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
553 }
554
hasMips1() const555 bool hasMips1() const {
556 return getSTI().getFeatureBits()[Mips::FeatureMips1];
557 }
558
hasMips2() const559 bool hasMips2() const {
560 return getSTI().getFeatureBits()[Mips::FeatureMips2];
561 }
562
hasMips3() const563 bool hasMips3() const {
564 return getSTI().getFeatureBits()[Mips::FeatureMips3];
565 }
566
hasMips4() const567 bool hasMips4() const {
568 return getSTI().getFeatureBits()[Mips::FeatureMips4];
569 }
570
hasMips5() const571 bool hasMips5() const {
572 return getSTI().getFeatureBits()[Mips::FeatureMips5];
573 }
574
hasMips32() const575 bool hasMips32() const {
576 return getSTI().getFeatureBits()[Mips::FeatureMips32];
577 }
578
hasMips64() const579 bool hasMips64() const {
580 return getSTI().getFeatureBits()[Mips::FeatureMips64];
581 }
582
hasMips32r2() const583 bool hasMips32r2() const {
584 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
585 }
586
hasMips64r2() const587 bool hasMips64r2() const {
588 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
589 }
590
hasMips32r3() const591 bool hasMips32r3() const {
592 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
593 }
594
hasMips64r3() const595 bool hasMips64r3() const {
596 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
597 }
598
hasMips32r5() const599 bool hasMips32r5() const {
600 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
601 }
602
hasMips64r5() const603 bool hasMips64r5() const {
604 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
605 }
606
hasMips32r6() const607 bool hasMips32r6() const {
608 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
609 }
610
hasMips64r6() const611 bool hasMips64r6() const {
612 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
613 }
614
hasDSP() const615 bool hasDSP() const {
616 return getSTI().getFeatureBits()[Mips::FeatureDSP];
617 }
618
hasDSPR2() const619 bool hasDSPR2() const {
620 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
621 }
622
hasDSPR3() const623 bool hasDSPR3() const {
624 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
625 }
626
hasMSA() const627 bool hasMSA() const {
628 return getSTI().getFeatureBits()[Mips::FeatureMSA];
629 }
630
hasCnMips() const631 bool hasCnMips() const {
632 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
633 }
634
inPicMode()635 bool inPicMode() {
636 return IsPicEnabled;
637 }
638
inMips16Mode() const639 bool inMips16Mode() const {
640 return getSTI().getFeatureBits()[Mips::FeatureMips16];
641 }
642
useTraps() const643 bool useTraps() const {
644 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
645 }
646
useSoftFloat() const647 bool useSoftFloat() const {
648 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
649 }
hasMT() const650 bool hasMT() const {
651 return getSTI().getFeatureBits()[Mips::FeatureMT];
652 }
653
hasCRC() const654 bool hasCRC() const {
655 return getSTI().getFeatureBits()[Mips::FeatureCRC];
656 }
657
hasVirt() const658 bool hasVirt() const {
659 return getSTI().getFeatureBits()[Mips::FeatureVirt];
660 }
661
hasGINV() const662 bool hasGINV() const {
663 return getSTI().getFeatureBits()[Mips::FeatureGINV];
664 }
665
666 /// Warn if RegIndex is the same as the current AT.
667 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
668
669 void warnIfNoMacro(SMLoc Loc);
670
isLittle() const671 bool isLittle() const { return IsLittleEndian; }
672
createTargetUnaryExpr(const MCExpr * E,AsmToken::TokenKind OperatorToken,MCContext & Ctx)673 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
674 AsmToken::TokenKind OperatorToken,
675 MCContext &Ctx) override {
676 switch(OperatorToken) {
677 default:
678 llvm_unreachable("Unknown token");
679 return nullptr;
680 case AsmToken::PercentCall16:
681 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
682 case AsmToken::PercentCall_Hi:
683 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
684 case AsmToken::PercentCall_Lo:
685 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
686 case AsmToken::PercentDtprel_Hi:
687 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
688 case AsmToken::PercentDtprel_Lo:
689 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
690 case AsmToken::PercentGot:
691 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
692 case AsmToken::PercentGot_Disp:
693 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
694 case AsmToken::PercentGot_Hi:
695 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
696 case AsmToken::PercentGot_Lo:
697 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
698 case AsmToken::PercentGot_Ofst:
699 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
700 case AsmToken::PercentGot_Page:
701 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
702 case AsmToken::PercentGottprel:
703 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
704 case AsmToken::PercentGp_Rel:
705 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
706 case AsmToken::PercentHi:
707 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
708 case AsmToken::PercentHigher:
709 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
710 case AsmToken::PercentHighest:
711 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
712 case AsmToken::PercentLo:
713 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
714 case AsmToken::PercentNeg:
715 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
716 case AsmToken::PercentPcrel_Hi:
717 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
718 case AsmToken::PercentPcrel_Lo:
719 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
720 case AsmToken::PercentTlsgd:
721 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
722 case AsmToken::PercentTlsldm:
723 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
724 case AsmToken::PercentTprel_Hi:
725 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
726 case AsmToken::PercentTprel_Lo:
727 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
728 }
729 }
730 };
731
732 /// MipsOperand - Instances of this class represent a parsed Mips machine
733 /// instruction.
734 class MipsOperand : public MCParsedAsmOperand {
735 public:
736 /// Broad categories of register classes
737 /// The exact class is finalized by the render method.
738 enum RegKind {
739 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
740 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
741 /// isFP64bit())
742 RegKind_FCC = 4, /// FCC
743 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
744 RegKind_MSACtrl = 16, /// MSA control registers
745 RegKind_COP2 = 32, /// COP2
746 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
747 /// context).
748 RegKind_CCR = 128, /// CCR
749 RegKind_HWRegs = 256, /// HWRegs
750 RegKind_COP3 = 512, /// COP3
751 RegKind_COP0 = 1024, /// COP0
752 /// Potentially any (e.g. $1)
753 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
754 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
755 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
756 };
757
758 private:
759 enum KindTy {
760 k_Immediate, /// An immediate (possibly involving symbol references)
761 k_Memory, /// Base + Offset Memory Address
762 k_RegisterIndex, /// A register index in one or more RegKind.
763 k_Token, /// A simple token
764 k_RegList, /// A physical register list
765 } Kind;
766
767 public:
MipsOperand(KindTy K,MipsAsmParser & Parser)768 MipsOperand(KindTy K, MipsAsmParser &Parser)
769 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
770
~MipsOperand()771 ~MipsOperand() override {
772 switch (Kind) {
773 case k_Memory:
774 delete Mem.Base;
775 break;
776 case k_RegList:
777 delete RegList.List;
778 break;
779 case k_Immediate:
780 case k_RegisterIndex:
781 case k_Token:
782 break;
783 }
784 }
785
786 private:
787 /// For diagnostics, and checking the assembler temporary
788 MipsAsmParser &AsmParser;
789
790 struct Token {
791 const char *Data;
792 unsigned Length;
793 };
794
795 struct RegIdxOp {
796 unsigned Index; /// Index into the register class
797 RegKind Kind; /// Bitfield of the kinds it could possibly be
798 struct Token Tok; /// The input token this operand originated from.
799 const MCRegisterInfo *RegInfo;
800 };
801
802 struct ImmOp {
803 const MCExpr *Val;
804 };
805
806 struct MemOp {
807 MipsOperand *Base;
808 const MCExpr *Off;
809 };
810
811 struct RegListOp {
812 SmallVector<unsigned, 10> *List;
813 };
814
815 union {
816 struct Token Tok;
817 struct RegIdxOp RegIdx;
818 struct ImmOp Imm;
819 struct MemOp Mem;
820 struct RegListOp RegList;
821 };
822
823 SMLoc StartLoc, EndLoc;
824
825 /// Internal constructor for register kinds
CreateReg(unsigned Index,StringRef Str,RegKind RegKind,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)826 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
827 RegKind RegKind,
828 const MCRegisterInfo *RegInfo,
829 SMLoc S, SMLoc E,
830 MipsAsmParser &Parser) {
831 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
832 Op->RegIdx.Index = Index;
833 Op->RegIdx.RegInfo = RegInfo;
834 Op->RegIdx.Kind = RegKind;
835 Op->RegIdx.Tok.Data = Str.data();
836 Op->RegIdx.Tok.Length = Str.size();
837 Op->StartLoc = S;
838 Op->EndLoc = E;
839 return Op;
840 }
841
842 public:
843 /// Coerce the register to GPR32 and return the real register for the current
844 /// target.
getGPR32Reg() const845 unsigned getGPR32Reg() const {
846 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
847 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
848 unsigned ClassID = Mips::GPR32RegClassID;
849 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
850 }
851
852 /// Coerce the register to GPR32 and return the real register for the current
853 /// target.
getGPRMM16Reg() const854 unsigned getGPRMM16Reg() const {
855 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
856 unsigned ClassID = Mips::GPR32RegClassID;
857 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
858 }
859
860 /// Coerce the register to GPR64 and return the real register for the current
861 /// target.
getGPR64Reg() const862 unsigned getGPR64Reg() const {
863 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
864 unsigned ClassID = Mips::GPR64RegClassID;
865 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
866 }
867
868 private:
869 /// Coerce the register to AFGR64 and return the real register for the current
870 /// target.
getAFGR64Reg() const871 unsigned getAFGR64Reg() const {
872 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
873 if (RegIdx.Index % 2 != 0)
874 AsmParser.Warning(StartLoc, "Float register should be even.");
875 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
876 .getRegister(RegIdx.Index / 2);
877 }
878
879 /// Coerce the register to FGR64 and return the real register for the current
880 /// target.
getFGR64Reg() const881 unsigned getFGR64Reg() const {
882 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
883 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
884 .getRegister(RegIdx.Index);
885 }
886
887 /// Coerce the register to FGR32 and return the real register for the current
888 /// target.
getFGR32Reg() const889 unsigned getFGR32Reg() const {
890 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
891 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
892 .getRegister(RegIdx.Index);
893 }
894
895 /// Coerce the register to FGRH32 and return the real register for the current
896 /// target.
getFGRH32Reg() const897 unsigned getFGRH32Reg() const {
898 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
899 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
900 .getRegister(RegIdx.Index);
901 }
902
903 /// Coerce the register to FCC and return the real register for the current
904 /// target.
getFCCReg() const905 unsigned getFCCReg() const {
906 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
907 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
908 .getRegister(RegIdx.Index);
909 }
910
911 /// Coerce the register to MSA128 and return the real register for the current
912 /// target.
getMSA128Reg() const913 unsigned getMSA128Reg() const {
914 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
915 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
916 // identical
917 unsigned ClassID = Mips::MSA128BRegClassID;
918 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
919 }
920
921 /// Coerce the register to MSACtrl and return the real register for the
922 /// current target.
getMSACtrlReg() const923 unsigned getMSACtrlReg() const {
924 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
925 unsigned ClassID = Mips::MSACtrlRegClassID;
926 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
927 }
928
929 /// Coerce the register to COP0 and return the real register for the
930 /// current target.
getCOP0Reg() const931 unsigned getCOP0Reg() const {
932 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
933 unsigned ClassID = Mips::COP0RegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
935 }
936
937 /// Coerce the register to COP2 and return the real register for the
938 /// current target.
getCOP2Reg() const939 unsigned getCOP2Reg() const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
941 unsigned ClassID = Mips::COP2RegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
943 }
944
945 /// Coerce the register to COP3 and return the real register for the
946 /// current target.
getCOP3Reg() const947 unsigned getCOP3Reg() const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
949 unsigned ClassID = Mips::COP3RegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
951 }
952
953 /// Coerce the register to ACC64DSP and return the real register for the
954 /// current target.
getACC64DSPReg() const955 unsigned getACC64DSPReg() const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
957 unsigned ClassID = Mips::ACC64DSPRegClassID;
958 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
959 }
960
961 /// Coerce the register to HI32DSP and return the real register for the
962 /// current target.
getHI32DSPReg() const963 unsigned getHI32DSPReg() const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
965 unsigned ClassID = Mips::HI32DSPRegClassID;
966 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
967 }
968
969 /// Coerce the register to LO32DSP and return the real register for the
970 /// current target.
getLO32DSPReg() const971 unsigned getLO32DSPReg() const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
973 unsigned ClassID = Mips::LO32DSPRegClassID;
974 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
975 }
976
977 /// Coerce the register to CCR and return the real register for the
978 /// current target.
getCCRReg() const979 unsigned getCCRReg() const {
980 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
981 unsigned ClassID = Mips::CCRRegClassID;
982 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
983 }
984
985 /// Coerce the register to HWRegs and return the real register for the
986 /// current target.
getHWRegsReg() const987 unsigned getHWRegsReg() const {
988 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
989 unsigned ClassID = Mips::HWRegsRegClassID;
990 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
991 }
992
993 public:
addExpr(MCInst & Inst,const MCExpr * Expr) const994 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
995 // Add as immediate when possible. Null MCExpr = 0.
996 if (!Expr)
997 Inst.addOperand(MCOperand::createImm(0));
998 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
999 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1000 else
1001 Inst.addOperand(MCOperand::createExpr(Expr));
1002 }
1003
addRegOperands(MCInst & Inst,unsigned N) const1004 void addRegOperands(MCInst &Inst, unsigned N) const {
1005 llvm_unreachable("Use a custom parser instead");
1006 }
1007
1008 /// Render the operand to an MCInst as a GPR32
1009 /// Asserts if the wrong number of operands are requested, or the operand
1010 /// is not a k_RegisterIndex compatible with RegKind_GPR
addGPR32ZeroAsmRegOperands(MCInst & Inst,unsigned N) const1011 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1012 assert(N == 1 && "Invalid number of operands!");
1013 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1014 }
1015
addGPR32NonZeroAsmRegOperands(MCInst & Inst,unsigned N) const1016 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1017 assert(N == 1 && "Invalid number of operands!");
1018 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1019 }
1020
addGPR32AsmRegOperands(MCInst & Inst,unsigned N) const1021 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1022 assert(N == 1 && "Invalid number of operands!");
1023 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1024 }
1025
addGPRMM16AsmRegOperands(MCInst & Inst,unsigned N) const1026 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1027 assert(N == 1 && "Invalid number of operands!");
1028 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1029 }
1030
addGPRMM16AsmRegZeroOperands(MCInst & Inst,unsigned N) const1031 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1032 assert(N == 1 && "Invalid number of operands!");
1033 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1034 }
1035
addGPRMM16AsmRegMovePOperands(MCInst & Inst,unsigned N) const1036 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1037 assert(N == 1 && "Invalid number of operands!");
1038 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1039 }
1040
addGPRMM16AsmRegMovePPairFirstOperands(MCInst & Inst,unsigned N) const1041 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1042 assert(N == 1 && "Invalid number of operands!");
1043 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1044 }
1045
addGPRMM16AsmRegMovePPairSecondOperands(MCInst & Inst,unsigned N) const1046 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1047 unsigned N) const {
1048 assert(N == 1 && "Invalid number of operands!");
1049 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1050 }
1051
1052 /// Render the operand to an MCInst as a GPR64
1053 /// Asserts if the wrong number of operands are requested, or the operand
1054 /// is not a k_RegisterIndex compatible with RegKind_GPR
addGPR64AsmRegOperands(MCInst & Inst,unsigned N) const1055 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1056 assert(N == 1 && "Invalid number of operands!");
1057 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1058 }
1059
addAFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1060 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1061 assert(N == 1 && "Invalid number of operands!");
1062 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1063 }
1064
addStrictlyAFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1065 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1066 assert(N == 1 && "Invalid number of operands!");
1067 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1068 }
1069
addStrictlyFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1070 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1071 assert(N == 1 && "Invalid number of operands!");
1072 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1073 }
1074
addFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1075 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1076 assert(N == 1 && "Invalid number of operands!");
1077 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1078 }
1079
addFGR32AsmRegOperands(MCInst & Inst,unsigned N) const1080 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1081 assert(N == 1 && "Invalid number of operands!");
1082 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1083 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1084 // FIXME: This should propagate failure up to parseStatement.
1085 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1086 AsmParser.getParser().printError(
1087 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1088 "registers");
1089 }
1090
addStrictlyFGR32AsmRegOperands(MCInst & Inst,unsigned N) const1091 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1094 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1095 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1096 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1097 "registers");
1098 }
1099
addFGRH32AsmRegOperands(MCInst & Inst,unsigned N) const1100 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1101 assert(N == 1 && "Invalid number of operands!");
1102 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1103 }
1104
addFCCAsmRegOperands(MCInst & Inst,unsigned N) const1105 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1106 assert(N == 1 && "Invalid number of operands!");
1107 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1108 }
1109
addMSA128AsmRegOperands(MCInst & Inst,unsigned N) const1110 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1111 assert(N == 1 && "Invalid number of operands!");
1112 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1113 }
1114
addMSACtrlAsmRegOperands(MCInst & Inst,unsigned N) const1115 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1116 assert(N == 1 && "Invalid number of operands!");
1117 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1118 }
1119
addCOP0AsmRegOperands(MCInst & Inst,unsigned N) const1120 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1121 assert(N == 1 && "Invalid number of operands!");
1122 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1123 }
1124
addCOP2AsmRegOperands(MCInst & Inst,unsigned N) const1125 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1126 assert(N == 1 && "Invalid number of operands!");
1127 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1128 }
1129
addCOP3AsmRegOperands(MCInst & Inst,unsigned N) const1130 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1131 assert(N == 1 && "Invalid number of operands!");
1132 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1133 }
1134
addACC64DSPAsmRegOperands(MCInst & Inst,unsigned N) const1135 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1136 assert(N == 1 && "Invalid number of operands!");
1137 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1138 }
1139
addHI32DSPAsmRegOperands(MCInst & Inst,unsigned N) const1140 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1141 assert(N == 1 && "Invalid number of operands!");
1142 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1143 }
1144
addLO32DSPAsmRegOperands(MCInst & Inst,unsigned N) const1145 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1146 assert(N == 1 && "Invalid number of operands!");
1147 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1148 }
1149
addCCRAsmRegOperands(MCInst & Inst,unsigned N) const1150 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1151 assert(N == 1 && "Invalid number of operands!");
1152 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1153 }
1154
addHWRegsAsmRegOperands(MCInst & Inst,unsigned N) const1155 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1156 assert(N == 1 && "Invalid number of operands!");
1157 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1158 }
1159
1160 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
addConstantUImmOperands(MCInst & Inst,unsigned N) const1161 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1162 assert(N == 1 && "Invalid number of operands!");
1163 uint64_t Imm = getConstantImm() - Offset;
1164 Imm &= (1ULL << Bits) - 1;
1165 Imm += Offset;
1166 Imm += AdjustOffset;
1167 Inst.addOperand(MCOperand::createImm(Imm));
1168 }
1169
1170 template <unsigned Bits>
addSImmOperands(MCInst & Inst,unsigned N) const1171 void addSImmOperands(MCInst &Inst, unsigned N) const {
1172 if (isImm() && !isConstantImm()) {
1173 addExpr(Inst, getImm());
1174 return;
1175 }
1176 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1177 }
1178
1179 template <unsigned Bits>
addUImmOperands(MCInst & Inst,unsigned N) const1180 void addUImmOperands(MCInst &Inst, unsigned N) const {
1181 if (isImm() && !isConstantImm()) {
1182 addExpr(Inst, getImm());
1183 return;
1184 }
1185 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1186 }
1187
1188 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
addConstantSImmOperands(MCInst & Inst,unsigned N) const1189 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1190 assert(N == 1 && "Invalid number of operands!");
1191 int64_t Imm = getConstantImm() - Offset;
1192 Imm = SignExtend64<Bits>(Imm);
1193 Imm += Offset;
1194 Imm += AdjustOffset;
1195 Inst.addOperand(MCOperand::createImm(Imm));
1196 }
1197
addImmOperands(MCInst & Inst,unsigned N) const1198 void addImmOperands(MCInst &Inst, unsigned N) const {
1199 assert(N == 1 && "Invalid number of operands!");
1200 const MCExpr *Expr = getImm();
1201 addExpr(Inst, Expr);
1202 }
1203
addMemOperands(MCInst & Inst,unsigned N) const1204 void addMemOperands(MCInst &Inst, unsigned N) const {
1205 assert(N == 2 && "Invalid number of operands!");
1206
1207 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1208 ? getMemBase()->getGPR64Reg()
1209 : getMemBase()->getGPR32Reg()));
1210
1211 const MCExpr *Expr = getMemOff();
1212 addExpr(Inst, Expr);
1213 }
1214
addMicroMipsMemOperands(MCInst & Inst,unsigned N) const1215 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1216 assert(N == 2 && "Invalid number of operands!");
1217
1218 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1219
1220 const MCExpr *Expr = getMemOff();
1221 addExpr(Inst, Expr);
1222 }
1223
addRegListOperands(MCInst & Inst,unsigned N) const1224 void addRegListOperands(MCInst &Inst, unsigned N) const {
1225 assert(N == 1 && "Invalid number of operands!");
1226
1227 for (auto RegNo : getRegList())
1228 Inst.addOperand(MCOperand::createReg(RegNo));
1229 }
1230
isReg() const1231 bool isReg() const override {
1232 // As a special case until we sort out the definition of div/divu, accept
1233 // $0/$zero here so that MCK_ZERO works correctly.
1234 return isGPRAsmReg() && RegIdx.Index == 0;
1235 }
1236
isRegIdx() const1237 bool isRegIdx() const { return Kind == k_RegisterIndex; }
isImm() const1238 bool isImm() const override { return Kind == k_Immediate; }
1239
isConstantImm() const1240 bool isConstantImm() const {
1241 int64_t Res;
1242 return isImm() && getImm()->evaluateAsAbsolute(Res);
1243 }
1244
isConstantImmz() const1245 bool isConstantImmz() const {
1246 return isConstantImm() && getConstantImm() == 0;
1247 }
1248
isConstantUImm() const1249 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1250 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1251 }
1252
isSImm() const1253 template <unsigned Bits> bool isSImm() const {
1254 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1255 }
1256
isUImm() const1257 template <unsigned Bits> bool isUImm() const {
1258 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1259 }
1260
isAnyImm() const1261 template <unsigned Bits> bool isAnyImm() const {
1262 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1263 isUInt<Bits>(getConstantImm()))
1264 : isImm();
1265 }
1266
isConstantSImm() const1267 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1268 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1269 }
1270
isConstantUImmRange() const1271 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1272 return isConstantImm() && getConstantImm() >= Bottom &&
1273 getConstantImm() <= Top;
1274 }
1275
isToken() const1276 bool isToken() const override {
1277 // Note: It's not possible to pretend that other operand kinds are tokens.
1278 // The matcher emitter checks tokens first.
1279 return Kind == k_Token;
1280 }
1281
isMem() const1282 bool isMem() const override { return Kind == k_Memory; }
1283
isConstantMemOff() const1284 bool isConstantMemOff() const {
1285 return isMem() && isa<MCConstantExpr>(getMemOff());
1286 }
1287
1288 // Allow relocation operators.
1289 // FIXME: This predicate and others need to look through binary expressions
1290 // and determine whether a Value is a constant or not.
1291 template <unsigned Bits, unsigned ShiftAmount = 0>
isMemWithSimmOffset() const1292 bool isMemWithSimmOffset() const {
1293 if (!isMem())
1294 return false;
1295 if (!getMemBase()->isGPRAsmReg())
1296 return false;
1297 if (isa<MCTargetExpr>(getMemOff()) ||
1298 (isConstantMemOff() &&
1299 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1300 return true;
1301 MCValue Res;
1302 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1303 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1304 }
1305
isMemWithPtrSizeOffset() const1306 bool isMemWithPtrSizeOffset() const {
1307 if (!isMem())
1308 return false;
1309 if (!getMemBase()->isGPRAsmReg())
1310 return false;
1311 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1312 if (isa<MCTargetExpr>(getMemOff()) ||
1313 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1314 return true;
1315 MCValue Res;
1316 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1317 return IsReloc && isIntN(PtrBits, Res.getConstant());
1318 }
1319
isMemWithGRPMM16Base() const1320 bool isMemWithGRPMM16Base() const {
1321 return isMem() && getMemBase()->isMM16AsmReg();
1322 }
1323
isMemWithUimmOffsetSP() const1324 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1325 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1326 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1327 }
1328
isMemWithUimmWordAlignedOffsetSP() const1329 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1330 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1331 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1332 && (getMemBase()->getGPR32Reg() == Mips::SP);
1333 }
1334
isMemWithSimmWordAlignedOffsetGP() const1335 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1336 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1337 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1338 && (getMemBase()->getGPR32Reg() == Mips::GP);
1339 }
1340
1341 template <unsigned Bits, unsigned ShiftLeftAmount>
isScaledUImm() const1342 bool isScaledUImm() const {
1343 return isConstantImm() &&
1344 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1345 }
1346
1347 template <unsigned Bits, unsigned ShiftLeftAmount>
isScaledSImm() const1348 bool isScaledSImm() const {
1349 if (isConstantImm() &&
1350 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1351 return true;
1352 // Operand can also be a symbol or symbol plus
1353 // offset in case of relocations.
1354 if (Kind != k_Immediate)
1355 return false;
1356 MCValue Res;
1357 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1358 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1359 }
1360
isRegList16() const1361 bool isRegList16() const {
1362 if (!isRegList())
1363 return false;
1364
1365 int Size = RegList.List->size();
1366 if (Size < 2 || Size > 5)
1367 return false;
1368
1369 unsigned R0 = RegList.List->front();
1370 unsigned R1 = RegList.List->back();
1371 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1372 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1373 return false;
1374
1375 int PrevReg = *RegList.List->begin();
1376 for (int i = 1; i < Size - 1; i++) {
1377 int Reg = (*(RegList.List))[i];
1378 if ( Reg != PrevReg + 1)
1379 return false;
1380 PrevReg = Reg;
1381 }
1382
1383 return true;
1384 }
1385
isInvNum() const1386 bool isInvNum() const { return Kind == k_Immediate; }
1387
isLSAImm() const1388 bool isLSAImm() const {
1389 if (!isConstantImm())
1390 return false;
1391 int64_t Val = getConstantImm();
1392 return 1 <= Val && Val <= 4;
1393 }
1394
isRegList() const1395 bool isRegList() const { return Kind == k_RegList; }
1396
getToken() const1397 StringRef getToken() const {
1398 assert(Kind == k_Token && "Invalid access!");
1399 return StringRef(Tok.Data, Tok.Length);
1400 }
1401
getReg() const1402 unsigned getReg() const override {
1403 // As a special case until we sort out the definition of div/divu, accept
1404 // $0/$zero here so that MCK_ZERO works correctly.
1405 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1406 RegIdx.Kind & RegKind_GPR)
1407 return getGPR32Reg(); // FIXME: GPR64 too
1408
1409 llvm_unreachable("Invalid access!");
1410 return 0;
1411 }
1412
getImm() const1413 const MCExpr *getImm() const {
1414 assert((Kind == k_Immediate) && "Invalid access!");
1415 return Imm.Val;
1416 }
1417
getConstantImm() const1418 int64_t getConstantImm() const {
1419 const MCExpr *Val = getImm();
1420 int64_t Value = 0;
1421 (void)Val->evaluateAsAbsolute(Value);
1422 return Value;
1423 }
1424
getMemBase() const1425 MipsOperand *getMemBase() const {
1426 assert((Kind == k_Memory) && "Invalid access!");
1427 return Mem.Base;
1428 }
1429
getMemOff() const1430 const MCExpr *getMemOff() const {
1431 assert((Kind == k_Memory) && "Invalid access!");
1432 return Mem.Off;
1433 }
1434
getConstantMemOff() const1435 int64_t getConstantMemOff() const {
1436 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1437 }
1438
getRegList() const1439 const SmallVectorImpl<unsigned> &getRegList() const {
1440 assert((Kind == k_RegList) && "Invalid access!");
1441 return *(RegList.List);
1442 }
1443
CreateToken(StringRef Str,SMLoc S,MipsAsmParser & Parser)1444 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1445 MipsAsmParser &Parser) {
1446 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1447 Op->Tok.Data = Str.data();
1448 Op->Tok.Length = Str.size();
1449 Op->StartLoc = S;
1450 Op->EndLoc = S;
1451 return Op;
1452 }
1453
1454 /// Create a numeric register (e.g. $1). The exact register remains
1455 /// unresolved until an instruction successfully matches
1456 static std::unique_ptr<MipsOperand>
createNumericReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1457 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1458 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1459 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1460 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1461 }
1462
1463 /// Create a register that is definitely a GPR.
1464 /// This is typically only used for named registers such as $gp.
1465 static std::unique_ptr<MipsOperand>
createGPRReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1466 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1467 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1468 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1469 }
1470
1471 /// Create a register that is definitely a FGR.
1472 /// This is typically only used for named registers such as $f0.
1473 static std::unique_ptr<MipsOperand>
createFGRReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1474 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1475 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1476 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1477 }
1478
1479 /// Create a register that is definitely a HWReg.
1480 /// This is typically only used for named registers such as $hwr_cpunum.
1481 static std::unique_ptr<MipsOperand>
createHWRegsReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1482 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1483 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1484 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1485 }
1486
1487 /// Create a register that is definitely an FCC.
1488 /// This is typically only used for named registers such as $fcc0.
1489 static std::unique_ptr<MipsOperand>
createFCCReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1490 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1491 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1492 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1493 }
1494
1495 /// Create a register that is definitely an ACC.
1496 /// This is typically only used for named registers such as $ac0.
1497 static std::unique_ptr<MipsOperand>
createACCReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1498 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1499 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1500 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1501 }
1502
1503 /// Create a register that is definitely an MSA128.
1504 /// This is typically only used for named registers such as $w0.
1505 static std::unique_ptr<MipsOperand>
createMSA128Reg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1506 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1507 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1508 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1509 }
1510
1511 /// Create a register that is definitely an MSACtrl.
1512 /// This is typically only used for named registers such as $msaaccess.
1513 static std::unique_ptr<MipsOperand>
createMSACtrlReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1514 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1515 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1516 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1517 }
1518
1519 static std::unique_ptr<MipsOperand>
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E,MipsAsmParser & Parser)1520 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1521 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1522 Op->Imm.Val = Val;
1523 Op->StartLoc = S;
1524 Op->EndLoc = E;
1525 return Op;
1526 }
1527
1528 static std::unique_ptr<MipsOperand>
CreateMem(std::unique_ptr<MipsOperand> Base,const MCExpr * Off,SMLoc S,SMLoc E,MipsAsmParser & Parser)1529 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1530 SMLoc E, MipsAsmParser &Parser) {
1531 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1532 Op->Mem.Base = Base.release();
1533 Op->Mem.Off = Off;
1534 Op->StartLoc = S;
1535 Op->EndLoc = E;
1536 return Op;
1537 }
1538
1539 static std::unique_ptr<MipsOperand>
CreateRegList(SmallVectorImpl<unsigned> & Regs,SMLoc StartLoc,SMLoc EndLoc,MipsAsmParser & Parser)1540 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1541 MipsAsmParser &Parser) {
1542 assert(Regs.size() > 0 && "Empty list not allowed");
1543
1544 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1545 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1546 Op->StartLoc = StartLoc;
1547 Op->EndLoc = EndLoc;
1548 return Op;
1549 }
1550
isGPRZeroAsmReg() const1551 bool isGPRZeroAsmReg() const {
1552 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1553 }
1554
isGPRNonZeroAsmReg() const1555 bool isGPRNonZeroAsmReg() const {
1556 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1557 RegIdx.Index <= 31;
1558 }
1559
isGPRAsmReg() const1560 bool isGPRAsmReg() const {
1561 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1562 }
1563
isMM16AsmReg() const1564 bool isMM16AsmReg() const {
1565 if (!(isRegIdx() && RegIdx.Kind))
1566 return false;
1567 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1568 || RegIdx.Index == 16 || RegIdx.Index == 17);
1569
1570 }
isMM16AsmRegZero() const1571 bool isMM16AsmRegZero() const {
1572 if (!(isRegIdx() && RegIdx.Kind))
1573 return false;
1574 return (RegIdx.Index == 0 ||
1575 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1576 RegIdx.Index == 17);
1577 }
1578
isMM16AsmRegMoveP() const1579 bool isMM16AsmRegMoveP() const {
1580 if (!(isRegIdx() && RegIdx.Kind))
1581 return false;
1582 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1583 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1584 }
1585
isMM16AsmRegMovePPairFirst() const1586 bool isMM16AsmRegMovePPairFirst() const {
1587 if (!(isRegIdx() && RegIdx.Kind))
1588 return false;
1589 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1590 }
1591
isMM16AsmRegMovePPairSecond() const1592 bool isMM16AsmRegMovePPairSecond() const {
1593 if (!(isRegIdx() && RegIdx.Kind))
1594 return false;
1595 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1596 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1597 }
1598
isFGRAsmReg() const1599 bool isFGRAsmReg() const {
1600 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1601 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1602 }
1603
isStrictlyFGRAsmReg() const1604 bool isStrictlyFGRAsmReg() const {
1605 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1606 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1607 }
1608
isHWRegsAsmReg() const1609 bool isHWRegsAsmReg() const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1611 }
1612
isCCRAsmReg() const1613 bool isCCRAsmReg() const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1615 }
1616
isFCCAsmReg() const1617 bool isFCCAsmReg() const {
1618 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1619 return false;
1620 return RegIdx.Index <= 7;
1621 }
1622
isACCAsmReg() const1623 bool isACCAsmReg() const {
1624 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1625 }
1626
isCOP0AsmReg() const1627 bool isCOP0AsmReg() const {
1628 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1629 }
1630
isCOP2AsmReg() const1631 bool isCOP2AsmReg() const {
1632 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1633 }
1634
isCOP3AsmReg() const1635 bool isCOP3AsmReg() const {
1636 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1637 }
1638
isMSA128AsmReg() const1639 bool isMSA128AsmReg() const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1641 }
1642
isMSACtrlAsmReg() const1643 bool isMSACtrlAsmReg() const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1645 }
1646
1647 /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const1648 SMLoc getStartLoc() const override { return StartLoc; }
1649 /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const1650 SMLoc getEndLoc() const override { return EndLoc; }
1651
print(raw_ostream & OS) const1652 void print(raw_ostream &OS) const override {
1653 switch (Kind) {
1654 case k_Immediate:
1655 OS << "Imm<";
1656 OS << *Imm.Val;
1657 OS << ">";
1658 break;
1659 case k_Memory:
1660 OS << "Mem<";
1661 Mem.Base->print(OS);
1662 OS << ", ";
1663 OS << *Mem.Off;
1664 OS << ">";
1665 break;
1666 case k_RegisterIndex:
1667 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1668 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1669 break;
1670 case k_Token:
1671 OS << getToken();
1672 break;
1673 case k_RegList:
1674 OS << "RegList< ";
1675 for (auto Reg : (*RegList.List))
1676 OS << Reg << " ";
1677 OS << ">";
1678 break;
1679 }
1680 }
1681
isValidForTie(const MipsOperand & Other) const1682 bool isValidForTie(const MipsOperand &Other) const {
1683 if (Kind != Other.Kind)
1684 return false;
1685
1686 switch (Kind) {
1687 default:
1688 llvm_unreachable("Unexpected kind");
1689 return false;
1690 case k_RegisterIndex: {
1691 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1692 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1693 return Token == OtherToken;
1694 }
1695 }
1696 }
1697 }; // class MipsOperand
1698
1699 } // end anonymous namespace
1700
1701 namespace llvm {
1702
1703 extern const MCInstrDesc MipsInsts[];
1704
1705 } // end namespace llvm
1706
getInstDesc(unsigned Opcode)1707 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1708 return MipsInsts[Opcode];
1709 }
1710
hasShortDelaySlot(MCInst & Inst)1711 static bool hasShortDelaySlot(MCInst &Inst) {
1712 switch (Inst.getOpcode()) {
1713 case Mips::BEQ_MM:
1714 case Mips::BNE_MM:
1715 case Mips::BLTZ_MM:
1716 case Mips::BGEZ_MM:
1717 case Mips::BLEZ_MM:
1718 case Mips::BGTZ_MM:
1719 case Mips::JRC16_MM:
1720 case Mips::JALS_MM:
1721 case Mips::JALRS_MM:
1722 case Mips::JALRS16_MM:
1723 case Mips::BGEZALS_MM:
1724 case Mips::BLTZALS_MM:
1725 return true;
1726 case Mips::J_MM:
1727 return !Inst.getOperand(0).isReg();
1728 default:
1729 return false;
1730 }
1731 }
1732
getSingleMCSymbol(const MCExpr * Expr)1733 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1734 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1735 return &SRExpr->getSymbol();
1736 }
1737
1738 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1739 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1740 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1741
1742 if (LHSSym)
1743 return LHSSym;
1744
1745 if (RHSSym)
1746 return RHSSym;
1747
1748 return nullptr;
1749 }
1750
1751 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1752 return getSingleMCSymbol(UExpr->getSubExpr());
1753
1754 return nullptr;
1755 }
1756
countMCSymbolRefExpr(const MCExpr * Expr)1757 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1758 if (isa<MCSymbolRefExpr>(Expr))
1759 return 1;
1760
1761 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1762 return countMCSymbolRefExpr(BExpr->getLHS()) +
1763 countMCSymbolRefExpr(BExpr->getRHS());
1764
1765 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1766 return countMCSymbolRefExpr(UExpr->getSubExpr());
1767
1768 return 0;
1769 }
1770
processInstruction(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)1771 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1772 MCStreamer &Out,
1773 const MCSubtargetInfo *STI) {
1774 MipsTargetStreamer &TOut = getTargetStreamer();
1775 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1776 bool ExpandedJalSym = false;
1777
1778 Inst.setLoc(IDLoc);
1779
1780 if (MCID.isBranch() || MCID.isCall()) {
1781 const unsigned Opcode = Inst.getOpcode();
1782 MCOperand Offset;
1783
1784 switch (Opcode) {
1785 default:
1786 break;
1787 case Mips::BBIT0:
1788 case Mips::BBIT032:
1789 case Mips::BBIT1:
1790 case Mips::BBIT132:
1791 assert(hasCnMips() && "instruction only valid for octeon cpus");
1792 LLVM_FALLTHROUGH;
1793
1794 case Mips::BEQ:
1795 case Mips::BNE:
1796 case Mips::BEQ_MM:
1797 case Mips::BNE_MM:
1798 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1799 Offset = Inst.getOperand(2);
1800 if (!Offset.isImm())
1801 break; // We'll deal with this situation later on when applying fixups.
1802 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1803 return Error(IDLoc, "branch target out of range");
1804 if (OffsetToAlignment(Offset.getImm(),
1805 1LL << (inMicroMipsMode() ? 1 : 2)))
1806 return Error(IDLoc, "branch to misaligned address");
1807 break;
1808 case Mips::BGEZ:
1809 case Mips::BGTZ:
1810 case Mips::BLEZ:
1811 case Mips::BLTZ:
1812 case Mips::BGEZAL:
1813 case Mips::BLTZAL:
1814 case Mips::BC1F:
1815 case Mips::BC1T:
1816 case Mips::BGEZ_MM:
1817 case Mips::BGTZ_MM:
1818 case Mips::BLEZ_MM:
1819 case Mips::BLTZ_MM:
1820 case Mips::BGEZAL_MM:
1821 case Mips::BLTZAL_MM:
1822 case Mips::BC1F_MM:
1823 case Mips::BC1T_MM:
1824 case Mips::BC1EQZC_MMR6:
1825 case Mips::BC1NEZC_MMR6:
1826 case Mips::BC2EQZC_MMR6:
1827 case Mips::BC2NEZC_MMR6:
1828 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1829 Offset = Inst.getOperand(1);
1830 if (!Offset.isImm())
1831 break; // We'll deal with this situation later on when applying fixups.
1832 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1833 return Error(IDLoc, "branch target out of range");
1834 if (OffsetToAlignment(Offset.getImm(),
1835 1LL << (inMicroMipsMode() ? 1 : 2)))
1836 return Error(IDLoc, "branch to misaligned address");
1837 break;
1838 case Mips::BGEC: case Mips::BGEC_MMR6:
1839 case Mips::BLTC: case Mips::BLTC_MMR6:
1840 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1841 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1842 case Mips::BEQC: case Mips::BEQC_MMR6:
1843 case Mips::BNEC: case Mips::BNEC_MMR6:
1844 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1845 Offset = Inst.getOperand(2);
1846 if (!Offset.isImm())
1847 break; // We'll deal with this situation later on when applying fixups.
1848 if (!isIntN(18, Offset.getImm()))
1849 return Error(IDLoc, "branch target out of range");
1850 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1851 return Error(IDLoc, "branch to misaligned address");
1852 break;
1853 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1854 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1855 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1856 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1857 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1858 Offset = Inst.getOperand(1);
1859 if (!Offset.isImm())
1860 break; // We'll deal with this situation later on when applying fixups.
1861 if (!isIntN(18, Offset.getImm()))
1862 return Error(IDLoc, "branch target out of range");
1863 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1864 return Error(IDLoc, "branch to misaligned address");
1865 break;
1866 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1867 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1868 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1869 Offset = Inst.getOperand(1);
1870 if (!Offset.isImm())
1871 break; // We'll deal with this situation later on when applying fixups.
1872 if (!isIntN(23, Offset.getImm()))
1873 return Error(IDLoc, "branch target out of range");
1874 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1875 return Error(IDLoc, "branch to misaligned address");
1876 break;
1877 case Mips::BEQZ16_MM:
1878 case Mips::BEQZC16_MMR6:
1879 case Mips::BNEZ16_MM:
1880 case Mips::BNEZC16_MMR6:
1881 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1882 Offset = Inst.getOperand(1);
1883 if (!Offset.isImm())
1884 break; // We'll deal with this situation later on when applying fixups.
1885 if (!isInt<8>(Offset.getImm()))
1886 return Error(IDLoc, "branch target out of range");
1887 if (OffsetToAlignment(Offset.getImm(), 2LL))
1888 return Error(IDLoc, "branch to misaligned address");
1889 break;
1890 }
1891 }
1892
1893 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1894 // We still accept it but it is a normal nop.
1895 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1896 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1897 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1898 "nop instruction");
1899 }
1900
1901 if (hasCnMips()) {
1902 const unsigned Opcode = Inst.getOpcode();
1903 MCOperand Opnd;
1904 int Imm;
1905
1906 switch (Opcode) {
1907 default:
1908 break;
1909
1910 case Mips::BBIT0:
1911 case Mips::BBIT032:
1912 case Mips::BBIT1:
1913 case Mips::BBIT132:
1914 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1915 // The offset is handled above
1916 Opnd = Inst.getOperand(1);
1917 if (!Opnd.isImm())
1918 return Error(IDLoc, "expected immediate operand kind");
1919 Imm = Opnd.getImm();
1920 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1921 Opcode == Mips::BBIT1 ? 63 : 31))
1922 return Error(IDLoc, "immediate operand value out of range");
1923 if (Imm > 31) {
1924 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1925 : Mips::BBIT132);
1926 Inst.getOperand(1).setImm(Imm - 32);
1927 }
1928 break;
1929
1930 case Mips::SEQi:
1931 case Mips::SNEi:
1932 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1933 Opnd = Inst.getOperand(2);
1934 if (!Opnd.isImm())
1935 return Error(IDLoc, "expected immediate operand kind");
1936 Imm = Opnd.getImm();
1937 if (!isInt<10>(Imm))
1938 return Error(IDLoc, "immediate operand value out of range");
1939 break;
1940 }
1941 }
1942
1943 // Warn on division by zero. We're checking here as all instructions get
1944 // processed here, not just the macros that need expansion.
1945 //
1946 // The MIPS backend models most of the divison instructions and macros as
1947 // three operand instructions. The pre-R6 divide instructions however have
1948 // two operands and explicitly define HI/LO as part of the instruction,
1949 // not in the operands.
1950 unsigned FirstOp = 1;
1951 unsigned SecondOp = 2;
1952 switch (Inst.getOpcode()) {
1953 default:
1954 break;
1955 case Mips::SDivIMacro:
1956 case Mips::UDivIMacro:
1957 case Mips::DSDivIMacro:
1958 case Mips::DUDivIMacro:
1959 if (Inst.getOperand(2).getImm() == 0) {
1960 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1961 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1962 Warning(IDLoc, "dividing zero by zero");
1963 else
1964 Warning(IDLoc, "division by zero");
1965 }
1966 break;
1967 case Mips::DSDIV:
1968 case Mips::SDIV:
1969 case Mips::UDIV:
1970 case Mips::DUDIV:
1971 case Mips::UDIV_MM:
1972 case Mips::SDIV_MM:
1973 FirstOp = 0;
1974 SecondOp = 1;
1975 LLVM_FALLTHROUGH;
1976 case Mips::SDivMacro:
1977 case Mips::DSDivMacro:
1978 case Mips::UDivMacro:
1979 case Mips::DUDivMacro:
1980 case Mips::DIV:
1981 case Mips::DIVU:
1982 case Mips::DDIV:
1983 case Mips::DDIVU:
1984 case Mips::DIVU_MMR6:
1985 case Mips::DIV_MMR6:
1986 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1987 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1988 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1989 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1990 Warning(IDLoc, "dividing zero by zero");
1991 else
1992 Warning(IDLoc, "division by zero");
1993 }
1994 break;
1995 }
1996
1997 // For PIC code convert unconditional jump to unconditional branch.
1998 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1999 inPicMode()) {
2000 MCInst BInst;
2001 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2002 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2003 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2004 BInst.addOperand(Inst.getOperand(0));
2005 Inst = BInst;
2006 }
2007
2008 // This expansion is not in a function called by tryExpandInstruction()
2009 // because the pseudo-instruction doesn't have a distinct opcode.
2010 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2011 inPicMode()) {
2012 warnIfNoMacro(IDLoc);
2013
2014 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2015
2016 // We can do this expansion if there's only 1 symbol in the argument
2017 // expression.
2018 if (countMCSymbolRefExpr(JalExpr) > 1)
2019 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2020
2021 // FIXME: This is checking the expression can be handled by the later stages
2022 // of the assembler. We ought to leave it to those later stages.
2023 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2024
2025 // FIXME: Add support for label+offset operands (currently causes an error).
2026 // FIXME: Add support for forward-declared local symbols.
2027 // FIXME: Add expansion for when the LargeGOT option is enabled.
2028 if (JalSym->isInSection() || JalSym->isTemporary() ||
2029 (JalSym->isELF() &&
2030 cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2031 if (isABI_O32()) {
2032 // If it's a local symbol and the O32 ABI is being used, we expand to:
2033 // lw $25, 0($gp)
2034 // R_(MICRO)MIPS_GOT16 label
2035 // addiu $25, $25, 0
2036 // R_(MICRO)MIPS_LO16 label
2037 // jalr $25
2038 const MCExpr *Got16RelocExpr =
2039 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2040 const MCExpr *Lo16RelocExpr =
2041 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2042
2043 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2044 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2045 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2046 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2047 } else if (isABI_N32() || isABI_N64()) {
2048 // If it's a local symbol and the N32/N64 ABIs are being used,
2049 // we expand to:
2050 // lw/ld $25, 0($gp)
2051 // R_(MICRO)MIPS_GOT_DISP label
2052 // jalr $25
2053 const MCExpr *GotDispRelocExpr =
2054 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2055
2056 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2057 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2058 STI);
2059 }
2060 } else {
2061 // If it's an external/weak symbol, we expand to:
2062 // lw/ld $25, 0($gp)
2063 // R_(MICRO)MIPS_CALL16 label
2064 // jalr $25
2065 const MCExpr *Call16RelocExpr =
2066 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2067
2068 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2069 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2070 }
2071
2072 MCInst JalrInst;
2073 if (IsCpRestoreSet && inMicroMipsMode())
2074 JalrInst.setOpcode(Mips::JALRS_MM);
2075 else
2076 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2077 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2078 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2079
2080 if (EmitJalrReloc) {
2081 // As an optimization hint for the linker, before the JALR we add:
2082 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2083 // tmplabel:
2084 MCSymbol *TmpLabel = getContext().createTempSymbol();
2085 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2086 const MCExpr *RelocJalrExpr =
2087 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2088 getContext(), IDLoc);
2089
2090 TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2091 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2092 RelocJalrExpr, IDLoc, *STI);
2093 TOut.getStreamer().EmitLabel(TmpLabel);
2094 }
2095
2096 Inst = JalrInst;
2097 ExpandedJalSym = true;
2098 }
2099
2100 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2101 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2102 // Check the offset of memory operand, if it is a symbol
2103 // reference or immediate we may have to expand instructions.
2104 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2105 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2106 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2107 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2108 MCOperand &Op = Inst.getOperand(i);
2109 if (Op.isImm()) {
2110 int64_t MemOffset = Op.getImm();
2111 if (MemOffset < -32768 || MemOffset > 32767) {
2112 // Offset can't exceed 16bit value.
2113 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2114 return getParser().hasPendingError();
2115 }
2116 } else if (Op.isExpr()) {
2117 const MCExpr *Expr = Op.getExpr();
2118 if (Expr->getKind() == MCExpr::SymbolRef) {
2119 const MCSymbolRefExpr *SR =
2120 static_cast<const MCSymbolRefExpr *>(Expr);
2121 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2122 // Expand symbol.
2123 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2124 return getParser().hasPendingError();
2125 }
2126 } else if (!isEvaluated(Expr)) {
2127 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2128 return getParser().hasPendingError();
2129 }
2130 }
2131 }
2132 } // for
2133 } // if load/store
2134
2135 if (inMicroMipsMode()) {
2136 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2137 // Try to create 16-bit GP relative load instruction.
2138 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2139 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2140 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2141 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2142 MCOperand &Op = Inst.getOperand(i);
2143 if (Op.isImm()) {
2144 int MemOffset = Op.getImm();
2145 MCOperand &DstReg = Inst.getOperand(0);
2146 MCOperand &BaseReg = Inst.getOperand(1);
2147 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2148 getContext().getRegisterInfo()->getRegClass(
2149 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2150 (BaseReg.getReg() == Mips::GP ||
2151 BaseReg.getReg() == Mips::GP_64)) {
2152
2153 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2154 IDLoc, STI);
2155 return false;
2156 }
2157 }
2158 }
2159 } // for
2160 } // if load
2161
2162 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2163
2164 MCOperand Opnd;
2165 int Imm;
2166
2167 switch (Inst.getOpcode()) {
2168 default:
2169 break;
2170 case Mips::ADDIUSP_MM:
2171 Opnd = Inst.getOperand(0);
2172 if (!Opnd.isImm())
2173 return Error(IDLoc, "expected immediate operand kind");
2174 Imm = Opnd.getImm();
2175 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2176 Imm % 4 != 0)
2177 return Error(IDLoc, "immediate operand value out of range");
2178 break;
2179 case Mips::SLL16_MM:
2180 case Mips::SRL16_MM:
2181 Opnd = Inst.getOperand(2);
2182 if (!Opnd.isImm())
2183 return Error(IDLoc, "expected immediate operand kind");
2184 Imm = Opnd.getImm();
2185 if (Imm < 1 || Imm > 8)
2186 return Error(IDLoc, "immediate operand value out of range");
2187 break;
2188 case Mips::LI16_MM:
2189 Opnd = Inst.getOperand(1);
2190 if (!Opnd.isImm())
2191 return Error(IDLoc, "expected immediate operand kind");
2192 Imm = Opnd.getImm();
2193 if (Imm < -1 || Imm > 126)
2194 return Error(IDLoc, "immediate operand value out of range");
2195 break;
2196 case Mips::ADDIUR2_MM:
2197 Opnd = Inst.getOperand(2);
2198 if (!Opnd.isImm())
2199 return Error(IDLoc, "expected immediate operand kind");
2200 Imm = Opnd.getImm();
2201 if (!(Imm == 1 || Imm == -1 ||
2202 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2203 return Error(IDLoc, "immediate operand value out of range");
2204 break;
2205 case Mips::ANDI16_MM:
2206 Opnd = Inst.getOperand(2);
2207 if (!Opnd.isImm())
2208 return Error(IDLoc, "expected immediate operand kind");
2209 Imm = Opnd.getImm();
2210 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2211 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2212 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2213 return Error(IDLoc, "immediate operand value out of range");
2214 break;
2215 case Mips::LBU16_MM:
2216 Opnd = Inst.getOperand(2);
2217 if (!Opnd.isImm())
2218 return Error(IDLoc, "expected immediate operand kind");
2219 Imm = Opnd.getImm();
2220 if (Imm < -1 || Imm > 14)
2221 return Error(IDLoc, "immediate operand value out of range");
2222 break;
2223 case Mips::SB16_MM:
2224 case Mips::SB16_MMR6:
2225 Opnd = Inst.getOperand(2);
2226 if (!Opnd.isImm())
2227 return Error(IDLoc, "expected immediate operand kind");
2228 Imm = Opnd.getImm();
2229 if (Imm < 0 || Imm > 15)
2230 return Error(IDLoc, "immediate operand value out of range");
2231 break;
2232 case Mips::LHU16_MM:
2233 case Mips::SH16_MM:
2234 case Mips::SH16_MMR6:
2235 Opnd = Inst.getOperand(2);
2236 if (!Opnd.isImm())
2237 return Error(IDLoc, "expected immediate operand kind");
2238 Imm = Opnd.getImm();
2239 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2240 return Error(IDLoc, "immediate operand value out of range");
2241 break;
2242 case Mips::LW16_MM:
2243 case Mips::SW16_MM:
2244 case Mips::SW16_MMR6:
2245 Opnd = Inst.getOperand(2);
2246 if (!Opnd.isImm())
2247 return Error(IDLoc, "expected immediate operand kind");
2248 Imm = Opnd.getImm();
2249 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2250 return Error(IDLoc, "immediate operand value out of range");
2251 break;
2252 case Mips::ADDIUPC_MM:
2253 Opnd = Inst.getOperand(1);
2254 if (!Opnd.isImm())
2255 return Error(IDLoc, "expected immediate operand kind");
2256 Imm = Opnd.getImm();
2257 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2258 return Error(IDLoc, "immediate operand value out of range");
2259 break;
2260 case Mips::LWP_MM:
2261 case Mips::SWP_MM:
2262 if (Inst.getOperand(0).getReg() == Mips::RA)
2263 return Error(IDLoc, "invalid operand for instruction");
2264 break;
2265 case Mips::MOVEP_MM:
2266 case Mips::MOVEP_MMR6: {
2267 unsigned R0 = Inst.getOperand(0).getReg();
2268 unsigned R1 = Inst.getOperand(1).getReg();
2269 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2270 (R0 == Mips::A1 && R1 == Mips::A3) ||
2271 (R0 == Mips::A2 && R1 == Mips::A3) ||
2272 (R0 == Mips::A0 && R1 == Mips::S5) ||
2273 (R0 == Mips::A0 && R1 == Mips::S6) ||
2274 (R0 == Mips::A0 && R1 == Mips::A1) ||
2275 (R0 == Mips::A0 && R1 == Mips::A2) ||
2276 (R0 == Mips::A0 && R1 == Mips::A3));
2277 if (!RegPair)
2278 return Error(IDLoc, "invalid operand for instruction");
2279 break;
2280 }
2281 }
2282 }
2283
2284 bool FillDelaySlot =
2285 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2286 if (FillDelaySlot)
2287 TOut.emitDirectiveSetNoReorder();
2288
2289 MacroExpanderResultTy ExpandResult =
2290 tryExpandInstruction(Inst, IDLoc, Out, STI);
2291 switch (ExpandResult) {
2292 case MER_NotAMacro:
2293 Out.EmitInstruction(Inst, *STI);
2294 break;
2295 case MER_Success:
2296 break;
2297 case MER_Fail:
2298 return true;
2299 }
2300
2301 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2302 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2303 if (inMicroMipsMode()) {
2304 TOut.setUsesMicroMips();
2305 TOut.updateABIInfo(*this);
2306 }
2307
2308 // If this instruction has a delay slot and .set reorder is active,
2309 // emit a NOP after it.
2310 if (FillDelaySlot) {
2311 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2312 TOut.emitDirectiveSetReorder();
2313 }
2314
2315 if ((Inst.getOpcode() == Mips::JalOneReg ||
2316 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2317 isPicAndNotNxxAbi()) {
2318 if (IsCpRestoreSet) {
2319 // We need a NOP between the JALR and the LW:
2320 // If .set reorder has been used, we've already emitted a NOP.
2321 // If .set noreorder has been used, we need to emit a NOP at this point.
2322 if (!AssemblerOptions.back()->isReorder())
2323 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2324 STI);
2325
2326 // Load the $gp from the stack.
2327 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2328 } else
2329 Warning(IDLoc, "no .cprestore used in PIC mode");
2330 }
2331
2332 return false;
2333 }
2334
2335 MipsAsmParser::MacroExpanderResultTy
tryExpandInstruction(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2336 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2337 const MCSubtargetInfo *STI) {
2338 switch (Inst.getOpcode()) {
2339 default:
2340 return MER_NotAMacro;
2341 case Mips::LoadImm32:
2342 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2343 case Mips::LoadImm64:
2344 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2345 case Mips::LoadAddrImm32:
2346 case Mips::LoadAddrImm64:
2347 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2348 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2349 "expected immediate operand kind");
2350
2351 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2352 Inst.getOperand(1),
2353 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2354 Out, STI)
2355 ? MER_Fail
2356 : MER_Success;
2357 case Mips::LoadAddrReg32:
2358 case Mips::LoadAddrReg64:
2359 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2360 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2361 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2362 "expected immediate operand kind");
2363
2364 return expandLoadAddress(Inst.getOperand(0).getReg(),
2365 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2366 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2367 Out, STI)
2368 ? MER_Fail
2369 : MER_Success;
2370 case Mips::B_MM_Pseudo:
2371 case Mips::B_MMR6_Pseudo:
2372 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2373 : MER_Success;
2374 case Mips::SWM_MM:
2375 case Mips::LWM_MM:
2376 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2377 : MER_Success;
2378 case Mips::JalOneReg:
2379 case Mips::JalTwoReg:
2380 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2381 case Mips::BneImm:
2382 case Mips::BeqImm:
2383 case Mips::BEQLImmMacro:
2384 case Mips::BNELImmMacro:
2385 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2386 case Mips::BLT:
2387 case Mips::BLE:
2388 case Mips::BGE:
2389 case Mips::BGT:
2390 case Mips::BLTU:
2391 case Mips::BLEU:
2392 case Mips::BGEU:
2393 case Mips::BGTU:
2394 case Mips::BLTL:
2395 case Mips::BLEL:
2396 case Mips::BGEL:
2397 case Mips::BGTL:
2398 case Mips::BLTUL:
2399 case Mips::BLEUL:
2400 case Mips::BGEUL:
2401 case Mips::BGTUL:
2402 case Mips::BLTImmMacro:
2403 case Mips::BLEImmMacro:
2404 case Mips::BGEImmMacro:
2405 case Mips::BGTImmMacro:
2406 case Mips::BLTUImmMacro:
2407 case Mips::BLEUImmMacro:
2408 case Mips::BGEUImmMacro:
2409 case Mips::BGTUImmMacro:
2410 case Mips::BLTLImmMacro:
2411 case Mips::BLELImmMacro:
2412 case Mips::BGELImmMacro:
2413 case Mips::BGTLImmMacro:
2414 case Mips::BLTULImmMacro:
2415 case Mips::BLEULImmMacro:
2416 case Mips::BGEULImmMacro:
2417 case Mips::BGTULImmMacro:
2418 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2419 case Mips::SDivMacro:
2420 case Mips::SDivIMacro:
2421 case Mips::SRemMacro:
2422 case Mips::SRemIMacro:
2423 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2424 : MER_Success;
2425 case Mips::DSDivMacro:
2426 case Mips::DSDivIMacro:
2427 case Mips::DSRemMacro:
2428 case Mips::DSRemIMacro:
2429 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2430 : MER_Success;
2431 case Mips::UDivMacro:
2432 case Mips::UDivIMacro:
2433 case Mips::URemMacro:
2434 case Mips::URemIMacro:
2435 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2436 : MER_Success;
2437 case Mips::DUDivMacro:
2438 case Mips::DUDivIMacro:
2439 case Mips::DURemMacro:
2440 case Mips::DURemIMacro:
2441 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2442 : MER_Success;
2443 case Mips::PseudoTRUNC_W_S:
2444 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2445 : MER_Success;
2446 case Mips::PseudoTRUNC_W_D32:
2447 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2448 : MER_Success;
2449 case Mips::PseudoTRUNC_W_D:
2450 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2451 : MER_Success;
2452
2453 case Mips::LoadImmSingleGPR:
2454 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2455 ? MER_Fail
2456 : MER_Success;
2457 case Mips::LoadImmSingleFGR:
2458 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2459 ? MER_Fail
2460 : MER_Success;
2461 case Mips::LoadImmDoubleGPR:
2462 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2463 ? MER_Fail
2464 : MER_Success;
2465 case Mips::LoadImmDoubleFGR:
2466 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2467 ? MER_Fail
2468 : MER_Success;
2469 case Mips::LoadImmDoubleFGR_32:
2470 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2471 ? MER_Fail
2472 : MER_Success;
2473 case Mips::Ulh:
2474 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2475 case Mips::Ulhu:
2476 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2477 case Mips::Ush:
2478 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2479 case Mips::Ulw:
2480 case Mips::Usw:
2481 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2482 case Mips::NORImm:
2483 case Mips::NORImm64:
2484 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2485 case Mips::SLTImm64:
2486 if (isInt<16>(Inst.getOperand(2).getImm())) {
2487 Inst.setOpcode(Mips::SLTi64);
2488 return MER_NotAMacro;
2489 }
2490 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2491 case Mips::SLTUImm64:
2492 if (isInt<16>(Inst.getOperand(2).getImm())) {
2493 Inst.setOpcode(Mips::SLTiu64);
2494 return MER_NotAMacro;
2495 }
2496 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2497 case Mips::ADDi: case Mips::ADDi_MM:
2498 case Mips::ADDiu: case Mips::ADDiu_MM:
2499 case Mips::SLTi: case Mips::SLTi_MM:
2500 case Mips::SLTiu: case Mips::SLTiu_MM:
2501 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2502 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2503 int64_t ImmValue = Inst.getOperand(2).getImm();
2504 if (isInt<16>(ImmValue))
2505 return MER_NotAMacro;
2506 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2507 : MER_Success;
2508 }
2509 return MER_NotAMacro;
2510 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2511 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2512 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2513 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2514 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2515 int64_t ImmValue = Inst.getOperand(2).getImm();
2516 if (isUInt<16>(ImmValue))
2517 return MER_NotAMacro;
2518 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2519 : MER_Success;
2520 }
2521 return MER_NotAMacro;
2522 case Mips::ROL:
2523 case Mips::ROR:
2524 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2525 case Mips::ROLImm:
2526 case Mips::RORImm:
2527 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2528 case Mips::DROL:
2529 case Mips::DROR:
2530 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2531 case Mips::DROLImm:
2532 case Mips::DRORImm:
2533 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534 case Mips::ABSMacro:
2535 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::MULImmMacro:
2537 case Mips::DMULImmMacro:
2538 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 case Mips::MULOMacro:
2540 case Mips::DMULOMacro:
2541 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 case Mips::MULOUMacro:
2543 case Mips::DMULOUMacro:
2544 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545 case Mips::DMULMacro:
2546 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2547 case Mips::LDMacro:
2548 case Mips::SDMacro:
2549 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2550 Inst.getOpcode() == Mips::LDMacro)
2551 ? MER_Fail
2552 : MER_Success;
2553 case Mips::SEQMacro:
2554 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::SEQIMacro:
2556 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 case Mips::MFTC0: case Mips::MTTC0:
2558 case Mips::MFTGPR: case Mips::MTTGPR:
2559 case Mips::MFTLO: case Mips::MTTLO:
2560 case Mips::MFTHI: case Mips::MTTHI:
2561 case Mips::MFTACX: case Mips::MTTACX:
2562 case Mips::MFTDSP: case Mips::MTTDSP:
2563 case Mips::MFTC1: case Mips::MTTC1:
2564 case Mips::MFTHC1: case Mips::MTTHC1:
2565 case Mips::CFTC1: case Mips::CTTC1:
2566 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2567 }
2568 }
2569
expandJalWithRegs(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2570 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2571 MCStreamer &Out,
2572 const MCSubtargetInfo *STI) {
2573 MipsTargetStreamer &TOut = getTargetStreamer();
2574
2575 // Create a JALR instruction which is going to replace the pseudo-JAL.
2576 MCInst JalrInst;
2577 JalrInst.setLoc(IDLoc);
2578 const MCOperand FirstRegOp = Inst.getOperand(0);
2579 const unsigned Opcode = Inst.getOpcode();
2580
2581 if (Opcode == Mips::JalOneReg) {
2582 // jal $rs => jalr $rs
2583 if (IsCpRestoreSet && inMicroMipsMode()) {
2584 JalrInst.setOpcode(Mips::JALRS16_MM);
2585 JalrInst.addOperand(FirstRegOp);
2586 } else if (inMicroMipsMode()) {
2587 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2588 JalrInst.addOperand(FirstRegOp);
2589 } else {
2590 JalrInst.setOpcode(Mips::JALR);
2591 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2592 JalrInst.addOperand(FirstRegOp);
2593 }
2594 } else if (Opcode == Mips::JalTwoReg) {
2595 // jal $rd, $rs => jalr $rd, $rs
2596 if (IsCpRestoreSet && inMicroMipsMode())
2597 JalrInst.setOpcode(Mips::JALRS_MM);
2598 else
2599 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2600 JalrInst.addOperand(FirstRegOp);
2601 const MCOperand SecondRegOp = Inst.getOperand(1);
2602 JalrInst.addOperand(SecondRegOp);
2603 }
2604 Out.EmitInstruction(JalrInst, *STI);
2605
2606 // If .set reorder is active and branch instruction has a delay slot,
2607 // emit a NOP after it.
2608 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2609 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2610 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2611 STI);
2612
2613 return false;
2614 }
2615
2616 /// Can the value be represented by a unsigned N-bit value and a shift left?
isShiftedUIntAtAnyPosition(uint64_t x)2617 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2618 unsigned BitNum = findFirstSet(x);
2619
2620 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2621 }
2622
2623 /// Load (or add) an immediate into a register.
2624 ///
2625 /// @param ImmValue The immediate to load.
2626 /// @param DstReg The register that will hold the immediate.
2627 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2628 /// for a simple initialization.
2629 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2630 /// @param IsAddress True if the immediate represents an address. False if it
2631 /// is an integer.
2632 /// @param IDLoc Location of the immediate in the source file.
loadImmediate(int64_t ImmValue,unsigned DstReg,unsigned SrcReg,bool Is32BitImm,bool IsAddress,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2633 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2634 unsigned SrcReg, bool Is32BitImm,
2635 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2636 const MCSubtargetInfo *STI) {
2637 MipsTargetStreamer &TOut = getTargetStreamer();
2638
2639 if (!Is32BitImm && !isGP64bit()) {
2640 Error(IDLoc, "instruction requires a 64-bit architecture");
2641 return true;
2642 }
2643
2644 if (Is32BitImm) {
2645 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2646 // Sign extend up to 64-bit so that the predicates match the hardware
2647 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2648 // true.
2649 ImmValue = SignExtend64<32>(ImmValue);
2650 } else {
2651 Error(IDLoc, "instruction requires a 32-bit immediate");
2652 return true;
2653 }
2654 }
2655
2656 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2657 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2658
2659 bool UseSrcReg = false;
2660 if (SrcReg != Mips::NoRegister)
2661 UseSrcReg = true;
2662
2663 unsigned TmpReg = DstReg;
2664 if (UseSrcReg &&
2665 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2666 // At this point we need AT to perform the expansions and we exit if it is
2667 // not available.
2668 unsigned ATReg = getATReg(IDLoc);
2669 if (!ATReg)
2670 return true;
2671 TmpReg = ATReg;
2672 }
2673
2674 if (isInt<16>(ImmValue)) {
2675 if (!UseSrcReg)
2676 SrcReg = ZeroReg;
2677
2678 // This doesn't quite follow the usual ABI expectations for N32 but matches
2679 // traditional assembler behaviour. N32 would normally use addiu for both
2680 // integers and addresses.
2681 if (IsAddress && !Is32BitImm) {
2682 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2683 return false;
2684 }
2685
2686 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2687 return false;
2688 }
2689
2690 if (isUInt<16>(ImmValue)) {
2691 unsigned TmpReg = DstReg;
2692 if (SrcReg == DstReg) {
2693 TmpReg = getATReg(IDLoc);
2694 if (!TmpReg)
2695 return true;
2696 }
2697
2698 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2699 if (UseSrcReg)
2700 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2701 return false;
2702 }
2703
2704 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2705 warnIfNoMacro(IDLoc);
2706
2707 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2708 uint16_t Bits15To0 = ImmValue & 0xffff;
2709 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2710 // Traditional behaviour seems to special case this particular value. It's
2711 // not clear why other masks are handled differently.
2712 if (ImmValue == 0xffffffff) {
2713 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2714 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2715 if (UseSrcReg)
2716 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2717 return false;
2718 }
2719
2720 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2721 // upper 32 bits.
2722 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2723 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2724 if (Bits15To0)
2725 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2726 if (UseSrcReg)
2727 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2728 return false;
2729 }
2730
2731 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2732 if (Bits15To0)
2733 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2734 if (UseSrcReg)
2735 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2736 return false;
2737 }
2738
2739 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2740 if (Is32BitImm) {
2741 Error(IDLoc, "instruction requires a 32-bit immediate");
2742 return true;
2743 }
2744
2745 // Traditionally, these immediates are shifted as little as possible and as
2746 // such we align the most significant bit to bit 15 of our temporary.
2747 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2748 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2749 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2750 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2751 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2752 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2753
2754 if (UseSrcReg)
2755 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2756
2757 return false;
2758 }
2759
2760 warnIfNoMacro(IDLoc);
2761
2762 // The remaining case is packed with a sequence of dsll and ori with zeros
2763 // being omitted and any neighbouring dsll's being coalesced.
2764 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2765
2766 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2767 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2768 IDLoc, Out, STI))
2769 return false;
2770
2771 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2772 // skip it and defer the shift to the next chunk.
2773 unsigned ShiftCarriedForwards = 16;
2774 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2775 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2776
2777 if (ImmChunk != 0) {
2778 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2779 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2780 ShiftCarriedForwards = 0;
2781 }
2782
2783 ShiftCarriedForwards += 16;
2784 }
2785 ShiftCarriedForwards -= 16;
2786
2787 // Finish any remaining shifts left by trailing zeros.
2788 if (ShiftCarriedForwards)
2789 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2790
2791 if (UseSrcReg)
2792 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2793
2794 return false;
2795 }
2796
expandLoadImm(MCInst & Inst,bool Is32BitImm,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2797 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2798 MCStreamer &Out, const MCSubtargetInfo *STI) {
2799 const MCOperand &ImmOp = Inst.getOperand(1);
2800 assert(ImmOp.isImm() && "expected immediate operand kind");
2801 const MCOperand &DstRegOp = Inst.getOperand(0);
2802 assert(DstRegOp.isReg() && "expected register operand kind");
2803
2804 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2805 Is32BitImm, false, IDLoc, Out, STI))
2806 return true;
2807
2808 return false;
2809 }
2810
expandLoadAddress(unsigned DstReg,unsigned BaseReg,const MCOperand & Offset,bool Is32BitAddress,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2811 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2812 const MCOperand &Offset,
2813 bool Is32BitAddress, SMLoc IDLoc,
2814 MCStreamer &Out,
2815 const MCSubtargetInfo *STI) {
2816 // la can't produce a usable address when addresses are 64-bit.
2817 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2818 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2819 // We currently can't do this because we depend on the equality
2820 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2821 Error(IDLoc, "la used to load 64-bit address");
2822 // Continue as if we had 'dla' instead.
2823 Is32BitAddress = false;
2824 return true;
2825 }
2826
2827 // dla requires 64-bit addresses.
2828 if (!Is32BitAddress && !hasMips3()) {
2829 Error(IDLoc, "instruction requires a 64-bit architecture");
2830 return true;
2831 }
2832
2833 if (!Offset.isImm())
2834 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2835 Is32BitAddress, IDLoc, Out, STI);
2836
2837 if (!ABI.ArePtrs64bit()) {
2838 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2839 Is32BitAddress = true;
2840 }
2841
2842 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2843 IDLoc, Out, STI);
2844 }
2845
loadAndAddSymbolAddress(const MCExpr * SymExpr,unsigned DstReg,unsigned SrcReg,bool Is32BitSym,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2846 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2847 unsigned DstReg, unsigned SrcReg,
2848 bool Is32BitSym, SMLoc IDLoc,
2849 MCStreamer &Out,
2850 const MCSubtargetInfo *STI) {
2851 // FIXME: These expansions do not respect -mxgot.
2852 MipsTargetStreamer &TOut = getTargetStreamer();
2853 bool UseSrcReg = SrcReg != Mips::NoRegister;
2854 warnIfNoMacro(IDLoc);
2855
2856 if (inPicMode() && ABI.IsO32()) {
2857 MCValue Res;
2858 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2859 Error(IDLoc, "expected relocatable expression");
2860 return true;
2861 }
2862 if (Res.getSymB() != nullptr) {
2863 Error(IDLoc, "expected relocatable expression with only one symbol");
2864 return true;
2865 }
2866
2867 // The case where the result register is $25 is somewhat special. If the
2868 // symbol in the final relocation is external and not modified with a
2869 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2870 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2871 Res.getConstant() == 0 &&
2872 !(Res.getSymA()->getSymbol().isInSection() ||
2873 Res.getSymA()->getSymbol().isTemporary() ||
2874 (Res.getSymA()->getSymbol().isELF() &&
2875 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2876 ELF::STB_LOCAL))) {
2877 const MCExpr *CallExpr =
2878 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2879 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2880 MCOperand::createExpr(CallExpr), IDLoc, STI);
2881 return false;
2882 }
2883
2884 // The remaining cases are:
2885 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2886 // >addiu $tmp, $tmp, %lo(offset)
2887 // >addiu $rd, $tmp, $rs
2888 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2889 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2890 // >addiu $rd, $tmp, $rs
2891 // The addiu's marked with a '>' may be omitted if they are redundant. If
2892 // this happens then the last instruction must use $rd as the result
2893 // register.
2894 const MipsMCExpr *GotExpr =
2895 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2896 const MCExpr *LoExpr = nullptr;
2897 if (Res.getSymA()->getSymbol().isInSection() ||
2898 Res.getSymA()->getSymbol().isTemporary())
2899 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2900 else if (Res.getConstant() != 0) {
2901 // External symbols fully resolve the symbol with just the %got(symbol)
2902 // but we must still account for any offset to the symbol for expressions
2903 // like symbol+8.
2904 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2905 }
2906
2907 unsigned TmpReg = DstReg;
2908 if (UseSrcReg &&
2909 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2910 SrcReg)) {
2911 // If $rs is the same as $rd, we need to use AT.
2912 // If it is not available we exit.
2913 unsigned ATReg = getATReg(IDLoc);
2914 if (!ATReg)
2915 return true;
2916 TmpReg = ATReg;
2917 }
2918
2919 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2920 MCOperand::createExpr(GotExpr), IDLoc, STI);
2921
2922 if (LoExpr)
2923 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2924 IDLoc, STI);
2925
2926 if (UseSrcReg)
2927 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2928
2929 return false;
2930 }
2931
2932 if (inPicMode() && ABI.ArePtrs64bit()) {
2933 MCValue Res;
2934 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2935 Error(IDLoc, "expected relocatable expression");
2936 return true;
2937 }
2938 if (Res.getSymB() != nullptr) {
2939 Error(IDLoc, "expected relocatable expression with only one symbol");
2940 return true;
2941 }
2942
2943 // The case where the result register is $25 is somewhat special. If the
2944 // symbol in the final relocation is external and not modified with a
2945 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2946 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2947 Res.getConstant() == 0 &&
2948 !(Res.getSymA()->getSymbol().isInSection() ||
2949 Res.getSymA()->getSymbol().isTemporary() ||
2950 (Res.getSymA()->getSymbol().isELF() &&
2951 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2952 ELF::STB_LOCAL))) {
2953 const MCExpr *CallExpr =
2954 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2955 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2956 MCOperand::createExpr(CallExpr), IDLoc, STI);
2957 return false;
2958 }
2959
2960 // The remaining cases are:
2961 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2962 // >daddiu $tmp, $tmp, offset
2963 // >daddu $rd, $tmp, $rs
2964 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2965 // this happens then the last instruction must use $rd as the result
2966 // register.
2967 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2968 Res.getSymA(),
2969 getContext());
2970 const MCExpr *LoExpr = nullptr;
2971 if (Res.getConstant() != 0) {
2972 // Symbols fully resolve with just the %got_disp(symbol) but we
2973 // must still account for any offset to the symbol for
2974 // expressions like symbol+8.
2975 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2976
2977 // FIXME: Offsets greater than 16 bits are not yet implemented.
2978 // FIXME: The correct range is a 32-bit sign-extended number.
2979 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2980 Error(IDLoc, "macro instruction uses large offset, which is not "
2981 "currently supported");
2982 return true;
2983 }
2984 }
2985
2986 unsigned TmpReg = DstReg;
2987 if (UseSrcReg &&
2988 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2989 SrcReg)) {
2990 // If $rs is the same as $rd, we need to use AT.
2991 // If it is not available we exit.
2992 unsigned ATReg = getATReg(IDLoc);
2993 if (!ATReg)
2994 return true;
2995 TmpReg = ATReg;
2996 }
2997
2998 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
2999 MCOperand::createExpr(GotExpr), IDLoc, STI);
3000
3001 if (LoExpr)
3002 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3003 IDLoc, STI);
3004
3005 if (UseSrcReg)
3006 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3007
3008 return false;
3009 }
3010
3011 const MipsMCExpr *HiExpr =
3012 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3013 const MipsMCExpr *LoExpr =
3014 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3015
3016 // This is the 64-bit symbol address expansion.
3017 if (ABI.ArePtrs64bit() && isGP64bit()) {
3018 // We need AT for the 64-bit expansion in the cases where the optional
3019 // source register is the destination register and for the superscalar
3020 // scheduled form.
3021 //
3022 // If it is not available we exit if the destination is the same as the
3023 // source register.
3024
3025 const MipsMCExpr *HighestExpr =
3026 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3027 const MipsMCExpr *HigherExpr =
3028 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3029
3030 bool RdRegIsRsReg =
3031 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3032
3033 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3034 unsigned ATReg = getATReg(IDLoc);
3035
3036 // If $rs is the same as $rd:
3037 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3038 // daddiu $at, $at, %higher(sym)
3039 // dsll $at, $at, 16
3040 // daddiu $at, $at, %hi(sym)
3041 // dsll $at, $at, 16
3042 // daddiu $at, $at, %lo(sym)
3043 // daddu $rd, $at, $rd
3044 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3045 STI);
3046 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3047 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3048 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3049 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3050 IDLoc, STI);
3051 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3052 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3053 IDLoc, STI);
3054 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3055
3056 return false;
3057 } else if (canUseATReg() && !RdRegIsRsReg) {
3058 unsigned ATReg = getATReg(IDLoc);
3059
3060 // If the $rs is different from $rd or if $rs isn't specified and we
3061 // have $at available:
3062 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3063 // lui $at, %hi(sym)
3064 // daddiu $rd, $rd, %higher(sym)
3065 // daddiu $at, $at, %lo(sym)
3066 // dsll32 $rd, $rd, 0
3067 // daddu $rd, $rd, $at
3068 // (daddu $rd, $rd, $rs)
3069 //
3070 // Which is preferred for superscalar issue.
3071 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3072 STI);
3073 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3074 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3075 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3076 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3077 IDLoc, STI);
3078 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3079 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3080 if (UseSrcReg)
3081 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3082
3083 return false;
3084 } else if (!canUseATReg() && !RdRegIsRsReg) {
3085 // Otherwise, synthesize the address in the destination register
3086 // serially:
3087 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3088 // daddiu $rd, $rd, %higher(sym)
3089 // dsll $rd, $rd, 16
3090 // daddiu $rd, $rd, %hi(sym)
3091 // dsll $rd, $rd, 16
3092 // daddiu $rd, $rd, %lo(sym)
3093 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3094 STI);
3095 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3096 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3097 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3098 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3099 MCOperand::createExpr(HiExpr), IDLoc, STI);
3100 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3101 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3102 MCOperand::createExpr(LoExpr), IDLoc, STI);
3103 if (UseSrcReg)
3104 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3105
3106 return false;
3107 } else {
3108 // We have a case where SrcReg == DstReg and we don't have $at
3109 // available. We can't expand this case, so error out appropriately.
3110 assert(SrcReg == DstReg && !canUseATReg() &&
3111 "Could have expanded dla but didn't?");
3112 reportParseError(IDLoc,
3113 "pseudo-instruction requires $at, which is not available");
3114 return true;
3115 }
3116 }
3117
3118 // And now, the 32-bit symbol address expansion:
3119 // If $rs is the same as $rd:
3120 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3121 // ori $at, $at, %lo(sym)
3122 // addu $rd, $at, $rd
3123 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3124 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3125 // ori $rd, $rd, %lo(sym)
3126 // (addu $rd, $rd, $rs)
3127 unsigned TmpReg = DstReg;
3128 if (UseSrcReg &&
3129 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3130 // If $rs is the same as $rd, we need to use AT.
3131 // If it is not available we exit.
3132 unsigned ATReg = getATReg(IDLoc);
3133 if (!ATReg)
3134 return true;
3135 TmpReg = ATReg;
3136 }
3137
3138 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3139 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3140 IDLoc, STI);
3141
3142 if (UseSrcReg)
3143 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3144 else
3145 assert(
3146 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3147
3148 return false;
3149 }
3150
3151 // Each double-precision register DO-D15 overlaps with two of the single
3152 // precision registers F0-F31. As an example, all of the following hold true:
3153 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
nextReg(unsigned Reg)3154 static unsigned nextReg(unsigned Reg) {
3155 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3156 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3157 switch (Reg) {
3158 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3159 case Mips::ZERO: return Mips::AT;
3160 case Mips::AT: return Mips::V0;
3161 case Mips::V0: return Mips::V1;
3162 case Mips::V1: return Mips::A0;
3163 case Mips::A0: return Mips::A1;
3164 case Mips::A1: return Mips::A2;
3165 case Mips::A2: return Mips::A3;
3166 case Mips::A3: return Mips::T0;
3167 case Mips::T0: return Mips::T1;
3168 case Mips::T1: return Mips::T2;
3169 case Mips::T2: return Mips::T3;
3170 case Mips::T3: return Mips::T4;
3171 case Mips::T4: return Mips::T5;
3172 case Mips::T5: return Mips::T6;
3173 case Mips::T6: return Mips::T7;
3174 case Mips::T7: return Mips::S0;
3175 case Mips::S0: return Mips::S1;
3176 case Mips::S1: return Mips::S2;
3177 case Mips::S2: return Mips::S3;
3178 case Mips::S3: return Mips::S4;
3179 case Mips::S4: return Mips::S5;
3180 case Mips::S5: return Mips::S6;
3181 case Mips::S6: return Mips::S7;
3182 case Mips::S7: return Mips::T8;
3183 case Mips::T8: return Mips::T9;
3184 case Mips::T9: return Mips::K0;
3185 case Mips::K0: return Mips::K1;
3186 case Mips::K1: return Mips::GP;
3187 case Mips::GP: return Mips::SP;
3188 case Mips::SP: return Mips::FP;
3189 case Mips::FP: return Mips::RA;
3190 case Mips::RA: return Mips::ZERO;
3191 case Mips::D0: return Mips::F1;
3192 case Mips::D1: return Mips::F3;
3193 case Mips::D2: return Mips::F5;
3194 case Mips::D3: return Mips::F7;
3195 case Mips::D4: return Mips::F9;
3196 case Mips::D5: return Mips::F11;
3197 case Mips::D6: return Mips::F13;
3198 case Mips::D7: return Mips::F15;
3199 case Mips::D8: return Mips::F17;
3200 case Mips::D9: return Mips::F19;
3201 case Mips::D10: return Mips::F21;
3202 case Mips::D11: return Mips::F23;
3203 case Mips::D12: return Mips::F25;
3204 case Mips::D13: return Mips::F27;
3205 case Mips::D14: return Mips::F29;
3206 case Mips::D15: return Mips::F31;
3207 }
3208 }
3209
3210 // FIXME: This method is too general. In principle we should compute the number
3211 // of instructions required to synthesize the immediate inline compared to
3212 // synthesizing the address inline and relying on non .text sections.
3213 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3214 // likely to yield a much larger benefit as we have to synthesize a 64bit
3215 // address to load a 64 bit value.
emitPartialAddress(MipsTargetStreamer & TOut,SMLoc IDLoc,MCSymbol * Sym)3216 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3217 MCSymbol *Sym) {
3218 unsigned ATReg = getATReg(IDLoc);
3219 if (!ATReg)
3220 return true;
3221
3222 if(IsPicEnabled) {
3223 const MCExpr *GotSym =
3224 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3225 const MipsMCExpr *GotExpr =
3226 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3227
3228 if(isABI_O32() || isABI_N32()) {
3229 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3230 IDLoc, STI);
3231 } else { //isABI_N64()
3232 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3233 IDLoc, STI);
3234 }
3235 } else { //!IsPicEnabled
3236 const MCExpr *HiSym =
3237 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3238 const MipsMCExpr *HiExpr =
3239 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3240
3241 // FIXME: This is technically correct but gives a different result to gas,
3242 // but gas is incomplete there (it has a fixme noting it doesn't work with
3243 // 64-bit addresses).
3244 // FIXME: With -msym32 option, the address expansion for N64 should probably
3245 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3246 // symbol's value is considered sign extended.
3247 if(isABI_O32() || isABI_N32()) {
3248 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3249 } else { //isABI_N64()
3250 const MCExpr *HighestSym =
3251 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3252 const MipsMCExpr *HighestExpr =
3253 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3254 const MCExpr *HigherSym =
3255 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3256 const MipsMCExpr *HigherExpr =
3257 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3258
3259 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3260 STI);
3261 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3262 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3263 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3264 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3265 IDLoc, STI);
3266 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3267 }
3268 }
3269 return false;
3270 }
3271
expandLoadImmReal(MCInst & Inst,bool IsSingle,bool IsGPR,bool Is64FPU,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3272 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3273 bool Is64FPU, SMLoc IDLoc,
3274 MCStreamer &Out,
3275 const MCSubtargetInfo *STI) {
3276 MipsTargetStreamer &TOut = getTargetStreamer();
3277 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3278 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3279 "Invalid instruction operand.");
3280
3281 unsigned FirstReg = Inst.getOperand(0).getReg();
3282 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3283
3284 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3285 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3286 // exponent field), convert it to double (e.g. 1 to 1.0)
3287 if ((HiImmOp64 & 0x7ff00000) == 0) {
3288 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3289 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3290 }
3291
3292 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3293 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3294
3295 if (IsSingle) {
3296 // Conversion of a double in an uint64_t to a float in a uint32_t,
3297 // retaining the bit pattern of a float.
3298 uint32_t ImmOp32;
3299 double doubleImm = BitsToDouble(ImmOp64);
3300 float tmp_float = static_cast<float>(doubleImm);
3301 ImmOp32 = FloatToBits(tmp_float);
3302
3303 if (IsGPR) {
3304 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3305 Out, STI))
3306 return true;
3307 return false;
3308 } else {
3309 unsigned ATReg = getATReg(IDLoc);
3310 if (!ATReg)
3311 return true;
3312 if (LoImmOp64 == 0) {
3313 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3314 Out, STI))
3315 return true;
3316 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3317 return false;
3318 }
3319
3320 MCSection *CS = getStreamer().getCurrentSectionOnly();
3321 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3322 // where appropriate.
3323 MCSection *ReadOnlySection = getContext().getELFSection(
3324 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3325
3326 MCSymbol *Sym = getContext().createTempSymbol();
3327 const MCExpr *LoSym =
3328 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3329 const MipsMCExpr *LoExpr =
3330 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3331
3332 getStreamer().SwitchSection(ReadOnlySection);
3333 getStreamer().EmitLabel(Sym, IDLoc);
3334 getStreamer().EmitIntValue(ImmOp32, 4);
3335 getStreamer().SwitchSection(CS);
3336
3337 if(emitPartialAddress(TOut, IDLoc, Sym))
3338 return true;
3339 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3340 MCOperand::createExpr(LoExpr), IDLoc, STI);
3341 }
3342 return false;
3343 }
3344
3345 // if(!IsSingle)
3346 unsigned ATReg = getATReg(IDLoc);
3347 if (!ATReg)
3348 return true;
3349
3350 if (IsGPR) {
3351 if (LoImmOp64 == 0) {
3352 if(isABI_N32() || isABI_N64()) {
3353 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3354 IDLoc, Out, STI))
3355 return true;
3356 return false;
3357 } else {
3358 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3359 IDLoc, Out, STI))
3360 return true;
3361
3362 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3363 IDLoc, Out, STI))
3364 return true;
3365 return false;
3366 }
3367 }
3368
3369 MCSection *CS = getStreamer().getCurrentSectionOnly();
3370 MCSection *ReadOnlySection = getContext().getELFSection(
3371 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3372
3373 MCSymbol *Sym = getContext().createTempSymbol();
3374 const MCExpr *LoSym =
3375 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3376 const MipsMCExpr *LoExpr =
3377 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3378
3379 getStreamer().SwitchSection(ReadOnlySection);
3380 getStreamer().EmitLabel(Sym, IDLoc);
3381 getStreamer().EmitIntValue(HiImmOp64, 4);
3382 getStreamer().EmitIntValue(LoImmOp64, 4);
3383 getStreamer().SwitchSection(CS);
3384
3385 if(emitPartialAddress(TOut, IDLoc, Sym))
3386 return true;
3387 if(isABI_N64())
3388 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3389 MCOperand::createExpr(LoExpr), IDLoc, STI);
3390 else
3391 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3392 MCOperand::createExpr(LoExpr), IDLoc, STI);
3393
3394 if(isABI_N32() || isABI_N64())
3395 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3396 else {
3397 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3398 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3399 }
3400 return false;
3401 } else { // if(!IsGPR && !IsSingle)
3402 if ((LoImmOp64 == 0) &&
3403 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3404 // FIXME: In the case where the constant is zero, we can load the
3405 // register directly from the zero register.
3406 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3407 Out, STI))
3408 return true;
3409 if (isABI_N32() || isABI_N64())
3410 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3411 else if (hasMips32r2()) {
3412 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3413 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3414 } else {
3415 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3416 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3417 }
3418 return false;
3419 }
3420
3421 MCSection *CS = getStreamer().getCurrentSectionOnly();
3422 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3423 // where appropriate.
3424 MCSection *ReadOnlySection = getContext().getELFSection(
3425 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3426
3427 MCSymbol *Sym = getContext().createTempSymbol();
3428 const MCExpr *LoSym =
3429 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3430 const MipsMCExpr *LoExpr =
3431 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3432
3433 getStreamer().SwitchSection(ReadOnlySection);
3434 getStreamer().EmitLabel(Sym, IDLoc);
3435 getStreamer().EmitIntValue(HiImmOp64, 4);
3436 getStreamer().EmitIntValue(LoImmOp64, 4);
3437 getStreamer().SwitchSection(CS);
3438
3439 if(emitPartialAddress(TOut, IDLoc, Sym))
3440 return true;
3441 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3442 MCOperand::createExpr(LoExpr), IDLoc, STI);
3443 }
3444 return false;
3445 }
3446
expandUncondBranchMMPseudo(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3447 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3448 MCStreamer &Out,
3449 const MCSubtargetInfo *STI) {
3450 MipsTargetStreamer &TOut = getTargetStreamer();
3451
3452 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3453 "unexpected number of operands");
3454
3455 MCOperand Offset = Inst.getOperand(0);
3456 if (Offset.isExpr()) {
3457 Inst.clear();
3458 Inst.setOpcode(Mips::BEQ_MM);
3459 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3460 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3461 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3462 } else {
3463 assert(Offset.isImm() && "expected immediate operand kind");
3464 if (isInt<11>(Offset.getImm())) {
3465 // If offset fits into 11 bits then this instruction becomes microMIPS
3466 // 16-bit unconditional branch instruction.
3467 if (inMicroMipsMode())
3468 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3469 } else {
3470 if (!isInt<17>(Offset.getImm()))
3471 return Error(IDLoc, "branch target out of range");
3472 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3473 return Error(IDLoc, "branch to misaligned address");
3474 Inst.clear();
3475 Inst.setOpcode(Mips::BEQ_MM);
3476 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3477 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3478 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3479 }
3480 }
3481 Out.EmitInstruction(Inst, *STI);
3482
3483 // If .set reorder is active and branch instruction has a delay slot,
3484 // emit a NOP after it.
3485 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3486 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3487 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3488
3489 return false;
3490 }
3491
expandBranchImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3492 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3493 const MCSubtargetInfo *STI) {
3494 MipsTargetStreamer &TOut = getTargetStreamer();
3495 const MCOperand &DstRegOp = Inst.getOperand(0);
3496 assert(DstRegOp.isReg() && "expected register operand kind");
3497
3498 const MCOperand &ImmOp = Inst.getOperand(1);
3499 assert(ImmOp.isImm() && "expected immediate operand kind");
3500
3501 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3502 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3503 "expected immediate or expression operand");
3504
3505 bool IsLikely = false;
3506
3507 unsigned OpCode = 0;
3508 switch(Inst.getOpcode()) {
3509 case Mips::BneImm:
3510 OpCode = Mips::BNE;
3511 break;
3512 case Mips::BeqImm:
3513 OpCode = Mips::BEQ;
3514 break;
3515 case Mips::BEQLImmMacro:
3516 OpCode = Mips::BEQL;
3517 IsLikely = true;
3518 break;
3519 case Mips::BNELImmMacro:
3520 OpCode = Mips::BNEL;
3521 IsLikely = true;
3522 break;
3523 default:
3524 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3525 break;
3526 }
3527
3528 int64_t ImmValue = ImmOp.getImm();
3529 if (ImmValue == 0) {
3530 if (IsLikely) {
3531 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3532 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3533 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3534 } else
3535 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3536 STI);
3537 } else {
3538 warnIfNoMacro(IDLoc);
3539
3540 unsigned ATReg = getATReg(IDLoc);
3541 if (!ATReg)
3542 return true;
3543
3544 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3545 IDLoc, Out, STI))
3546 return true;
3547
3548 if (IsLikely) {
3549 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3550 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3551 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3552 } else
3553 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3554 }
3555 return false;
3556 }
3557
expandMemInst(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI,bool IsLoad)3558 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3559 const MCSubtargetInfo *STI, bool IsLoad) {
3560 const MCOperand &DstRegOp = Inst.getOperand(0);
3561 assert(DstRegOp.isReg() && "expected register operand kind");
3562 const MCOperand &BaseRegOp = Inst.getOperand(1);
3563 assert(BaseRegOp.isReg() && "expected register operand kind");
3564 const MCOperand &OffsetOp = Inst.getOperand(2);
3565
3566 MipsTargetStreamer &TOut = getTargetStreamer();
3567 unsigned DstReg = DstRegOp.getReg();
3568 unsigned BaseReg = BaseRegOp.getReg();
3569 unsigned TmpReg = DstReg;
3570
3571 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3572 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3573 unsigned DstRegClassID =
3574 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3575 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3576 (DstRegClassID == Mips::GPR64RegClassID);
3577
3578 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3579 // At this point we need AT to perform the expansions
3580 // and we exit if it is not available.
3581 TmpReg = getATReg(IDLoc);
3582 if (!TmpReg)
3583 return;
3584 }
3585
3586 if (OffsetOp.isImm()) {
3587 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3588 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3589
3590 // If msb of LoOffset is 1(negative number) we must increment
3591 // HiOffset to account for the sign-extension of the low part.
3592 if (LoOffset & 0x8000)
3593 HiOffset += 0x10000;
3594
3595 bool IsLargeOffset = HiOffset != 0;
3596
3597 if (IsLargeOffset) {
3598 bool Is32BitImm = (HiOffset >> 32) == 0;
3599 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3600 IDLoc, Out, STI))
3601 return;
3602 }
3603
3604 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3605 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3606 BaseReg, IDLoc, STI);
3607 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3608 } else {
3609 assert(OffsetOp.isExpr() && "expected expression operand kind");
3610 const MCExpr *ExprOffset = OffsetOp.getExpr();
3611 MCOperand LoOperand = MCOperand::createExpr(
3612 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3613 MCOperand HiOperand = MCOperand::createExpr(
3614 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3615
3616 if (IsLoad)
3617 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3618 LoOperand, TmpReg, IDLoc, STI);
3619 else
3620 TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3621 LoOperand, TmpReg, IDLoc, STI);
3622 }
3623 }
3624
expandLoadStoreMultiple(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3625 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3626 MCStreamer &Out,
3627 const MCSubtargetInfo *STI) {
3628 unsigned OpNum = Inst.getNumOperands();
3629 unsigned Opcode = Inst.getOpcode();
3630 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3631
3632 assert(Inst.getOperand(OpNum - 1).isImm() &&
3633 Inst.getOperand(OpNum - 2).isReg() &&
3634 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3635
3636 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3637 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3638 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3639 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3640 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3641 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3642 // It can be implemented as SWM16 or LWM16 instruction.
3643 if (inMicroMipsMode() && hasMips32r6())
3644 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3645 else
3646 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3647 }
3648
3649 Inst.setOpcode(NewOpcode);
3650 Out.EmitInstruction(Inst, *STI);
3651 return false;
3652 }
3653
expandCondBranches(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3654 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3655 MCStreamer &Out,
3656 const MCSubtargetInfo *STI) {
3657 MipsTargetStreamer &TOut = getTargetStreamer();
3658 bool EmittedNoMacroWarning = false;
3659 unsigned PseudoOpcode = Inst.getOpcode();
3660 unsigned SrcReg = Inst.getOperand(0).getReg();
3661 const MCOperand &TrgOp = Inst.getOperand(1);
3662 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3663
3664 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3665 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3666
3667 unsigned TrgReg;
3668 if (TrgOp.isReg())
3669 TrgReg = TrgOp.getReg();
3670 else if (TrgOp.isImm()) {
3671 warnIfNoMacro(IDLoc);
3672 EmittedNoMacroWarning = true;
3673
3674 TrgReg = getATReg(IDLoc);
3675 if (!TrgReg)
3676 return true;
3677
3678 switch(PseudoOpcode) {
3679 default:
3680 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3681 case Mips::BLTImmMacro:
3682 PseudoOpcode = Mips::BLT;
3683 break;
3684 case Mips::BLEImmMacro:
3685 PseudoOpcode = Mips::BLE;
3686 break;
3687 case Mips::BGEImmMacro:
3688 PseudoOpcode = Mips::BGE;
3689 break;
3690 case Mips::BGTImmMacro:
3691 PseudoOpcode = Mips::BGT;
3692 break;
3693 case Mips::BLTUImmMacro:
3694 PseudoOpcode = Mips::BLTU;
3695 break;
3696 case Mips::BLEUImmMacro:
3697 PseudoOpcode = Mips::BLEU;
3698 break;
3699 case Mips::BGEUImmMacro:
3700 PseudoOpcode = Mips::BGEU;
3701 break;
3702 case Mips::BGTUImmMacro:
3703 PseudoOpcode = Mips::BGTU;
3704 break;
3705 case Mips::BLTLImmMacro:
3706 PseudoOpcode = Mips::BLTL;
3707 break;
3708 case Mips::BLELImmMacro:
3709 PseudoOpcode = Mips::BLEL;
3710 break;
3711 case Mips::BGELImmMacro:
3712 PseudoOpcode = Mips::BGEL;
3713 break;
3714 case Mips::BGTLImmMacro:
3715 PseudoOpcode = Mips::BGTL;
3716 break;
3717 case Mips::BLTULImmMacro:
3718 PseudoOpcode = Mips::BLTUL;
3719 break;
3720 case Mips::BLEULImmMacro:
3721 PseudoOpcode = Mips::BLEUL;
3722 break;
3723 case Mips::BGEULImmMacro:
3724 PseudoOpcode = Mips::BGEUL;
3725 break;
3726 case Mips::BGTULImmMacro:
3727 PseudoOpcode = Mips::BGTUL;
3728 break;
3729 }
3730
3731 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3732 false, IDLoc, Out, STI))
3733 return true;
3734 }
3735
3736 switch (PseudoOpcode) {
3737 case Mips::BLT:
3738 case Mips::BLTU:
3739 case Mips::BLTL:
3740 case Mips::BLTUL:
3741 AcceptsEquality = false;
3742 ReverseOrderSLT = false;
3743 IsUnsigned =
3744 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3745 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3746 ZeroSrcOpcode = Mips::BGTZ;
3747 ZeroTrgOpcode = Mips::BLTZ;
3748 break;
3749 case Mips::BLE:
3750 case Mips::BLEU:
3751 case Mips::BLEL:
3752 case Mips::BLEUL:
3753 AcceptsEquality = true;
3754 ReverseOrderSLT = true;
3755 IsUnsigned =
3756 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3757 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3758 ZeroSrcOpcode = Mips::BGEZ;
3759 ZeroTrgOpcode = Mips::BLEZ;
3760 break;
3761 case Mips::BGE:
3762 case Mips::BGEU:
3763 case Mips::BGEL:
3764 case Mips::BGEUL:
3765 AcceptsEquality = true;
3766 ReverseOrderSLT = false;
3767 IsUnsigned =
3768 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3769 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3770 ZeroSrcOpcode = Mips::BLEZ;
3771 ZeroTrgOpcode = Mips::BGEZ;
3772 break;
3773 case Mips::BGT:
3774 case Mips::BGTU:
3775 case Mips::BGTL:
3776 case Mips::BGTUL:
3777 AcceptsEquality = false;
3778 ReverseOrderSLT = true;
3779 IsUnsigned =
3780 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3781 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3782 ZeroSrcOpcode = Mips::BLTZ;
3783 ZeroTrgOpcode = Mips::BGTZ;
3784 break;
3785 default:
3786 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3787 }
3788
3789 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3790 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3791 if (IsSrcRegZero && IsTrgRegZero) {
3792 // FIXME: All of these Opcode-specific if's are needed for compatibility
3793 // with GAS' behaviour. However, they may not generate the most efficient
3794 // code in some circumstances.
3795 if (PseudoOpcode == Mips::BLT) {
3796 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3797 IDLoc, STI);
3798 return false;
3799 }
3800 if (PseudoOpcode == Mips::BLE) {
3801 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3802 IDLoc, STI);
3803 Warning(IDLoc, "branch is always taken");
3804 return false;
3805 }
3806 if (PseudoOpcode == Mips::BGE) {
3807 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3808 IDLoc, STI);
3809 Warning(IDLoc, "branch is always taken");
3810 return false;
3811 }
3812 if (PseudoOpcode == Mips::BGT) {
3813 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3814 IDLoc, STI);
3815 return false;
3816 }
3817 if (PseudoOpcode == Mips::BGTU) {
3818 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3819 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3820 return false;
3821 }
3822 if (AcceptsEquality) {
3823 // If both registers are $0 and the pseudo-branch accepts equality, it
3824 // will always be taken, so we emit an unconditional branch.
3825 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3826 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3827 Warning(IDLoc, "branch is always taken");
3828 return false;
3829 }
3830 // If both registers are $0 and the pseudo-branch does not accept
3831 // equality, it will never be taken, so we don't have to emit anything.
3832 return false;
3833 }
3834 if (IsSrcRegZero || IsTrgRegZero) {
3835 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3836 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3837 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3838 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3839 // the pseudo-branch will never be taken, so we don't emit anything.
3840 // This only applies to unsigned pseudo-branches.
3841 return false;
3842 }
3843 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3844 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3845 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3846 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3847 // the pseudo-branch will always be taken, so we emit an unconditional
3848 // branch.
3849 // This only applies to unsigned pseudo-branches.
3850 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3851 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3852 Warning(IDLoc, "branch is always taken");
3853 return false;
3854 }
3855 if (IsUnsigned) {
3856 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3857 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3858 // the pseudo-branch will be taken only when the non-zero register is
3859 // different from 0, so we emit a BNEZ.
3860 //
3861 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3862 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3863 // the pseudo-branch will be taken only when the non-zero register is
3864 // equal to 0, so we emit a BEQZ.
3865 //
3866 // Because only BLEU and BGEU branch on equality, we can use the
3867 // AcceptsEquality variable to decide when to emit the BEQZ.
3868 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3869 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3870 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3871 return false;
3872 }
3873 // If we have a signed pseudo-branch and one of the registers is $0,
3874 // we can use an appropriate compare-to-zero branch. We select which one
3875 // to use in the switch statement above.
3876 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3877 IsSrcRegZero ? TrgReg : SrcReg,
3878 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3879 return false;
3880 }
3881
3882 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3883 // expansions. If it is not available, we return.
3884 unsigned ATRegNum = getATReg(IDLoc);
3885 if (!ATRegNum)
3886 return true;
3887
3888 if (!EmittedNoMacroWarning)
3889 warnIfNoMacro(IDLoc);
3890
3891 // SLT fits well with 2 of our 4 pseudo-branches:
3892 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3893 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3894 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3895 // This is accomplished by using a BNEZ with the result of the SLT.
3896 //
3897 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3898 // and BLE with BGT), so we change the BNEZ into a BEQZ.
3899 // Because only BGE and BLE branch on equality, we can use the
3900 // AcceptsEquality variable to decide when to emit the BEQZ.
3901 // Note that the order of the SLT arguments doesn't change between
3902 // opposites.
3903 //
3904 // The same applies to the unsigned variants, except that SLTu is used
3905 // instead of SLT.
3906 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3907 ReverseOrderSLT ? TrgReg : SrcReg,
3908 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3909
3910 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3911 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3912 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3913 STI);
3914 return false;
3915 }
3916
3917 // Expand a integer division macro.
3918 //
3919 // Notably we don't have to emit a warning when encountering $rt as the $zero
3920 // register, or 0 as an immediate. processInstruction() has already done that.
3921 //
3922 // The destination register can only be $zero when expanding (S)DivIMacro or
3923 // D(S)DivMacro.
3924
expandDivRem(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI,const bool IsMips64,const bool Signed)3925 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3926 const MCSubtargetInfo *STI, const bool IsMips64,
3927 const bool Signed) {
3928 MipsTargetStreamer &TOut = getTargetStreamer();
3929
3930 warnIfNoMacro(IDLoc);
3931
3932 const MCOperand &RdRegOp = Inst.getOperand(0);
3933 assert(RdRegOp.isReg() && "expected register operand kind");
3934 unsigned RdReg = RdRegOp.getReg();
3935
3936 const MCOperand &RsRegOp = Inst.getOperand(1);
3937 assert(RsRegOp.isReg() && "expected register operand kind");
3938 unsigned RsReg = RsRegOp.getReg();
3939
3940 unsigned RtReg;
3941 int64_t ImmValue;
3942
3943 const MCOperand &RtOp = Inst.getOperand(2);
3944 assert((RtOp.isReg() || RtOp.isImm()) &&
3945 "expected register or immediate operand kind");
3946 if (RtOp.isReg())
3947 RtReg = RtOp.getReg();
3948 else
3949 ImmValue = RtOp.getImm();
3950
3951 unsigned DivOp;
3952 unsigned ZeroReg;
3953 unsigned SubOp;
3954
3955 if (IsMips64) {
3956 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3957 ZeroReg = Mips::ZERO_64;
3958 SubOp = Mips::DSUB;
3959 } else {
3960 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3961 ZeroReg = Mips::ZERO;
3962 SubOp = Mips::SUB;
3963 }
3964
3965 bool UseTraps = useTraps();
3966
3967 unsigned Opcode = Inst.getOpcode();
3968 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
3969 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
3970 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
3971 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
3972
3973 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
3974 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
3975 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
3976 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
3977
3978 if (RtOp.isImm()) {
3979 unsigned ATReg = getATReg(IDLoc);
3980 if (!ATReg)
3981 return true;
3982
3983 if (ImmValue == 0) {
3984 if (UseTraps)
3985 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3986 else
3987 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3988 return false;
3989 }
3990
3991 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
3992 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
3993 return false;
3994 } else if (isDiv && ImmValue == 1) {
3995 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3996 return false;
3997 } else if (isDiv && Signed && ImmValue == -1) {
3998 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3999 return false;
4000 } else {
4001 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4002 false, Inst.getLoc(), Out, STI))
4003 return true;
4004 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4005 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4006 return false;
4007 }
4008 return true;
4009 }
4010
4011 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4012 // break, insert the trap/break and exit. This gives a different result to
4013 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4014 // are handled equivalently. As the observed behaviour is the same, we're ok.
4015 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4016 if (UseTraps) {
4017 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4018 return false;
4019 }
4020 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4021 return false;
4022 }
4023
4024 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4025 // not expand to macro sequence.
4026 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4027 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4028 return false;
4029 }
4030
4031 // Temporary label for first branch traget
4032 MCContext &Context = TOut.getStreamer().getContext();
4033 MCSymbol *BrTarget;
4034 MCOperand LabelOp;
4035
4036 if (UseTraps) {
4037 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4038 } else {
4039 // Branch to the li instruction.
4040 BrTarget = Context.createTempSymbol();
4041 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4042 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4043 }
4044
4045 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4046
4047 if (!UseTraps)
4048 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4049
4050 if (!Signed) {
4051 if (!UseTraps)
4052 TOut.getStreamer().EmitLabel(BrTarget);
4053
4054 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4055 return false;
4056 }
4057
4058 unsigned ATReg = getATReg(IDLoc);
4059 if (!ATReg)
4060 return true;
4061
4062 if (!UseTraps)
4063 TOut.getStreamer().EmitLabel(BrTarget);
4064
4065 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4066
4067 // Temporary label for the second branch target.
4068 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4069 MCOperand LabelOpEnd =
4070 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4071
4072 // Branch to the mflo instruction.
4073 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4074
4075 if (IsMips64) {
4076 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4077 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4078 } else {
4079 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4080 }
4081
4082 if (UseTraps)
4083 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4084 else {
4085 // Branch to the mflo instruction.
4086 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4087 TOut.emitNop(IDLoc, STI);
4088 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4089 }
4090
4091 TOut.getStreamer().EmitLabel(BrTargetEnd);
4092 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4093 return false;
4094 }
4095
expandTrunc(MCInst & Inst,bool IsDouble,bool Is64FPU,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4096 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4097 SMLoc IDLoc, MCStreamer &Out,
4098 const MCSubtargetInfo *STI) {
4099 MipsTargetStreamer &TOut = getTargetStreamer();
4100
4101 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4102 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4103 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4104
4105 unsigned FirstReg = Inst.getOperand(0).getReg();
4106 unsigned SecondReg = Inst.getOperand(1).getReg();
4107 unsigned ThirdReg = Inst.getOperand(2).getReg();
4108
4109 if (hasMips1() && !hasMips2()) {
4110 unsigned ATReg = getATReg(IDLoc);
4111 if (!ATReg)
4112 return true;
4113 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4114 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4115 TOut.emitNop(IDLoc, STI);
4116 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4117 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4118 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4119 TOut.emitNop(IDLoc, STI);
4120 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4121 : Mips::CVT_W_S,
4122 FirstReg, SecondReg, IDLoc, STI);
4123 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4124 TOut.emitNop(IDLoc, STI);
4125 return false;
4126 }
4127
4128 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4129 : Mips::TRUNC_W_S,
4130 FirstReg, SecondReg, IDLoc, STI);
4131
4132 return false;
4133 }
4134
expandUlh(MCInst & Inst,bool Signed,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4135 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4136 MCStreamer &Out, const MCSubtargetInfo *STI) {
4137 if (hasMips32r6() || hasMips64r6()) {
4138 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4139 }
4140
4141 const MCOperand &DstRegOp = Inst.getOperand(0);
4142 assert(DstRegOp.isReg() && "expected register operand kind");
4143 const MCOperand &SrcRegOp = Inst.getOperand(1);
4144 assert(SrcRegOp.isReg() && "expected register operand kind");
4145 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4146 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4147
4148 MipsTargetStreamer &TOut = getTargetStreamer();
4149 unsigned DstReg = DstRegOp.getReg();
4150 unsigned SrcReg = SrcRegOp.getReg();
4151 int64_t OffsetValue = OffsetImmOp.getImm();
4152
4153 // NOTE: We always need AT for ULHU, as it is always used as the source
4154 // register for one of the LBu's.
4155 warnIfNoMacro(IDLoc);
4156 unsigned ATReg = getATReg(IDLoc);
4157 if (!ATReg)
4158 return true;
4159
4160 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4161 if (IsLargeOffset) {
4162 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4163 IDLoc, Out, STI))
4164 return true;
4165 }
4166
4167 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4168 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4169 if (isLittle())
4170 std::swap(FirstOffset, SecondOffset);
4171
4172 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4173 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4174
4175 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4176 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4177
4178 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4179 FirstOffset, IDLoc, STI);
4180 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4181 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4182 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4183
4184 return false;
4185 }
4186
expandUsh(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4187 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4188 const MCSubtargetInfo *STI) {
4189 if (hasMips32r6() || hasMips64r6()) {
4190 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4191 }
4192
4193 const MCOperand &DstRegOp = Inst.getOperand(0);
4194 assert(DstRegOp.isReg() && "expected register operand kind");
4195 const MCOperand &SrcRegOp = Inst.getOperand(1);
4196 assert(SrcRegOp.isReg() && "expected register operand kind");
4197 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4198 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4199
4200 MipsTargetStreamer &TOut = getTargetStreamer();
4201 unsigned DstReg = DstRegOp.getReg();
4202 unsigned SrcReg = SrcRegOp.getReg();
4203 int64_t OffsetValue = OffsetImmOp.getImm();
4204
4205 warnIfNoMacro(IDLoc);
4206 unsigned ATReg = getATReg(IDLoc);
4207 if (!ATReg)
4208 return true;
4209
4210 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4211 if (IsLargeOffset) {
4212 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4213 IDLoc, Out, STI))
4214 return true;
4215 }
4216
4217 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4218 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4219 if (isLittle())
4220 std::swap(FirstOffset, SecondOffset);
4221
4222 if (IsLargeOffset) {
4223 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4224 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4225 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4226 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4227 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4228 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4229 } else {
4230 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4231 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4232 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4233 }
4234
4235 return false;
4236 }
4237
expandUxw(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4238 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4239 const MCSubtargetInfo *STI) {
4240 if (hasMips32r6() || hasMips64r6()) {
4241 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4242 }
4243
4244 const MCOperand &DstRegOp = Inst.getOperand(0);
4245 assert(DstRegOp.isReg() && "expected register operand kind");
4246 const MCOperand &SrcRegOp = Inst.getOperand(1);
4247 assert(SrcRegOp.isReg() && "expected register operand kind");
4248 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4249 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4250
4251 MipsTargetStreamer &TOut = getTargetStreamer();
4252 unsigned DstReg = DstRegOp.getReg();
4253 unsigned SrcReg = SrcRegOp.getReg();
4254 int64_t OffsetValue = OffsetImmOp.getImm();
4255
4256 // Compute left/right load/store offsets.
4257 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4258 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4259 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4260 if (isLittle())
4261 std::swap(LxlOffset, LxrOffset);
4262
4263 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4264 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4265 unsigned TmpReg = SrcReg;
4266 if (IsLargeOffset || DoMove) {
4267 warnIfNoMacro(IDLoc);
4268 TmpReg = getATReg(IDLoc);
4269 if (!TmpReg)
4270 return true;
4271 }
4272
4273 if (IsLargeOffset) {
4274 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4275 IDLoc, Out, STI))
4276 return true;
4277 }
4278
4279 if (DoMove)
4280 std::swap(DstReg, TmpReg);
4281
4282 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4283 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4284 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4285 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4286
4287 if (DoMove)
4288 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4289
4290 return false;
4291 }
4292
expandAliasImmediate(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4293 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4294 MCStreamer &Out,
4295 const MCSubtargetInfo *STI) {
4296 MipsTargetStreamer &TOut = getTargetStreamer();
4297
4298 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4299 assert(Inst.getOperand(0).isReg() &&
4300 Inst.getOperand(1).isReg() &&
4301 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4302
4303 unsigned ATReg = Mips::NoRegister;
4304 unsigned FinalDstReg = Mips::NoRegister;
4305 unsigned DstReg = Inst.getOperand(0).getReg();
4306 unsigned SrcReg = Inst.getOperand(1).getReg();
4307 int64_t ImmValue = Inst.getOperand(2).getImm();
4308
4309 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4310
4311 unsigned FinalOpcode = Inst.getOpcode();
4312
4313 if (DstReg == SrcReg) {
4314 ATReg = getATReg(Inst.getLoc());
4315 if (!ATReg)
4316 return true;
4317 FinalDstReg = DstReg;
4318 DstReg = ATReg;
4319 }
4320
4321 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4322 Inst.getLoc(), Out, STI)) {
4323 switch (FinalOpcode) {
4324 default:
4325 llvm_unreachable("unimplemented expansion");
4326 case Mips::ADDi:
4327 FinalOpcode = Mips::ADD;
4328 break;
4329 case Mips::ADDiu:
4330 FinalOpcode = Mips::ADDu;
4331 break;
4332 case Mips::ANDi:
4333 FinalOpcode = Mips::AND;
4334 break;
4335 case Mips::NORImm:
4336 FinalOpcode = Mips::NOR;
4337 break;
4338 case Mips::ORi:
4339 FinalOpcode = Mips::OR;
4340 break;
4341 case Mips::SLTi:
4342 FinalOpcode = Mips::SLT;
4343 break;
4344 case Mips::SLTiu:
4345 FinalOpcode = Mips::SLTu;
4346 break;
4347 case Mips::XORi:
4348 FinalOpcode = Mips::XOR;
4349 break;
4350 case Mips::ADDi_MM:
4351 FinalOpcode = Mips::ADD_MM;
4352 break;
4353 case Mips::ADDiu_MM:
4354 FinalOpcode = Mips::ADDu_MM;
4355 break;
4356 case Mips::ANDi_MM:
4357 FinalOpcode = Mips::AND_MM;
4358 break;
4359 case Mips::ORi_MM:
4360 FinalOpcode = Mips::OR_MM;
4361 break;
4362 case Mips::SLTi_MM:
4363 FinalOpcode = Mips::SLT_MM;
4364 break;
4365 case Mips::SLTiu_MM:
4366 FinalOpcode = Mips::SLTu_MM;
4367 break;
4368 case Mips::XORi_MM:
4369 FinalOpcode = Mips::XOR_MM;
4370 break;
4371 case Mips::ANDi64:
4372 FinalOpcode = Mips::AND64;
4373 break;
4374 case Mips::NORImm64:
4375 FinalOpcode = Mips::NOR64;
4376 break;
4377 case Mips::ORi64:
4378 FinalOpcode = Mips::OR64;
4379 break;
4380 case Mips::SLTImm64:
4381 FinalOpcode = Mips::SLT64;
4382 break;
4383 case Mips::SLTUImm64:
4384 FinalOpcode = Mips::SLTu64;
4385 break;
4386 case Mips::XORi64:
4387 FinalOpcode = Mips::XOR64;
4388 break;
4389 }
4390
4391 if (FinalDstReg == Mips::NoRegister)
4392 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4393 else
4394 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4395 return false;
4396 }
4397 return true;
4398 }
4399
expandRotation(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4400 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4401 const MCSubtargetInfo *STI) {
4402 MipsTargetStreamer &TOut = getTargetStreamer();
4403 unsigned ATReg = Mips::NoRegister;
4404 unsigned DReg = Inst.getOperand(0).getReg();
4405 unsigned SReg = Inst.getOperand(1).getReg();
4406 unsigned TReg = Inst.getOperand(2).getReg();
4407 unsigned TmpReg = DReg;
4408
4409 unsigned FirstShift = Mips::NOP;
4410 unsigned SecondShift = Mips::NOP;
4411
4412 if (hasMips32r2()) {
4413 if (DReg == SReg) {
4414 TmpReg = getATReg(Inst.getLoc());
4415 if (!TmpReg)
4416 return true;
4417 }
4418
4419 if (Inst.getOpcode() == Mips::ROL) {
4420 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4421 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4422 return false;
4423 }
4424
4425 if (Inst.getOpcode() == Mips::ROR) {
4426 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4427 return false;
4428 }
4429
4430 return true;
4431 }
4432
4433 if (hasMips32()) {
4434 switch (Inst.getOpcode()) {
4435 default:
4436 llvm_unreachable("unexpected instruction opcode");
4437 case Mips::ROL:
4438 FirstShift = Mips::SRLV;
4439 SecondShift = Mips::SLLV;
4440 break;
4441 case Mips::ROR:
4442 FirstShift = Mips::SLLV;
4443 SecondShift = Mips::SRLV;
4444 break;
4445 }
4446
4447 ATReg = getATReg(Inst.getLoc());
4448 if (!ATReg)
4449 return true;
4450
4451 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4452 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4453 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4454 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4455
4456 return false;
4457 }
4458
4459 return true;
4460 }
4461
expandRotationImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4462 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4463 MCStreamer &Out,
4464 const MCSubtargetInfo *STI) {
4465 MipsTargetStreamer &TOut = getTargetStreamer();
4466 unsigned ATReg = Mips::NoRegister;
4467 unsigned DReg = Inst.getOperand(0).getReg();
4468 unsigned SReg = Inst.getOperand(1).getReg();
4469 int64_t ImmValue = Inst.getOperand(2).getImm();
4470
4471 unsigned FirstShift = Mips::NOP;
4472 unsigned SecondShift = Mips::NOP;
4473
4474 if (hasMips32r2()) {
4475 if (Inst.getOpcode() == Mips::ROLImm) {
4476 uint64_t MaxShift = 32;
4477 uint64_t ShiftValue = ImmValue;
4478 if (ImmValue != 0)
4479 ShiftValue = MaxShift - ImmValue;
4480 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4481 return false;
4482 }
4483
4484 if (Inst.getOpcode() == Mips::RORImm) {
4485 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4486 return false;
4487 }
4488
4489 return true;
4490 }
4491
4492 if (hasMips32()) {
4493 if (ImmValue == 0) {
4494 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4495 return false;
4496 }
4497
4498 switch (Inst.getOpcode()) {
4499 default:
4500 llvm_unreachable("unexpected instruction opcode");
4501 case Mips::ROLImm:
4502 FirstShift = Mips::SLL;
4503 SecondShift = Mips::SRL;
4504 break;
4505 case Mips::RORImm:
4506 FirstShift = Mips::SRL;
4507 SecondShift = Mips::SLL;
4508 break;
4509 }
4510
4511 ATReg = getATReg(Inst.getLoc());
4512 if (!ATReg)
4513 return true;
4514
4515 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4516 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4517 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4518
4519 return false;
4520 }
4521
4522 return true;
4523 }
4524
expandDRotation(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4525 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4526 const MCSubtargetInfo *STI) {
4527 MipsTargetStreamer &TOut = getTargetStreamer();
4528 unsigned ATReg = Mips::NoRegister;
4529 unsigned DReg = Inst.getOperand(0).getReg();
4530 unsigned SReg = Inst.getOperand(1).getReg();
4531 unsigned TReg = Inst.getOperand(2).getReg();
4532 unsigned TmpReg = DReg;
4533
4534 unsigned FirstShift = Mips::NOP;
4535 unsigned SecondShift = Mips::NOP;
4536
4537 if (hasMips64r2()) {
4538 if (TmpReg == SReg) {
4539 TmpReg = getATReg(Inst.getLoc());
4540 if (!TmpReg)
4541 return true;
4542 }
4543
4544 if (Inst.getOpcode() == Mips::DROL) {
4545 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4546 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4547 return false;
4548 }
4549
4550 if (Inst.getOpcode() == Mips::DROR) {
4551 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4552 return false;
4553 }
4554
4555 return true;
4556 }
4557
4558 if (hasMips64()) {
4559 switch (Inst.getOpcode()) {
4560 default:
4561 llvm_unreachable("unexpected instruction opcode");
4562 case Mips::DROL:
4563 FirstShift = Mips::DSRLV;
4564 SecondShift = Mips::DSLLV;
4565 break;
4566 case Mips::DROR:
4567 FirstShift = Mips::DSLLV;
4568 SecondShift = Mips::DSRLV;
4569 break;
4570 }
4571
4572 ATReg = getATReg(Inst.getLoc());
4573 if (!ATReg)
4574 return true;
4575
4576 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4577 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4578 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4579 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4580
4581 return false;
4582 }
4583
4584 return true;
4585 }
4586
expandDRotationImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4587 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4588 MCStreamer &Out,
4589 const MCSubtargetInfo *STI) {
4590 MipsTargetStreamer &TOut = getTargetStreamer();
4591 unsigned ATReg = Mips::NoRegister;
4592 unsigned DReg = Inst.getOperand(0).getReg();
4593 unsigned SReg = Inst.getOperand(1).getReg();
4594 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4595
4596 unsigned FirstShift = Mips::NOP;
4597 unsigned SecondShift = Mips::NOP;
4598
4599 MCInst TmpInst;
4600
4601 if (hasMips64r2()) {
4602 unsigned FinalOpcode = Mips::NOP;
4603 if (ImmValue == 0)
4604 FinalOpcode = Mips::DROTR;
4605 else if (ImmValue % 32 == 0)
4606 FinalOpcode = Mips::DROTR32;
4607 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4608 if (Inst.getOpcode() == Mips::DROLImm)
4609 FinalOpcode = Mips::DROTR32;
4610 else
4611 FinalOpcode = Mips::DROTR;
4612 } else if (ImmValue >= 33) {
4613 if (Inst.getOpcode() == Mips::DROLImm)
4614 FinalOpcode = Mips::DROTR;
4615 else
4616 FinalOpcode = Mips::DROTR32;
4617 }
4618
4619 uint64_t ShiftValue = ImmValue % 32;
4620 if (Inst.getOpcode() == Mips::DROLImm)
4621 ShiftValue = (32 - ImmValue % 32) % 32;
4622
4623 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4624
4625 return false;
4626 }
4627
4628 if (hasMips64()) {
4629 if (ImmValue == 0) {
4630 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4631 return false;
4632 }
4633
4634 switch (Inst.getOpcode()) {
4635 default:
4636 llvm_unreachable("unexpected instruction opcode");
4637 case Mips::DROLImm:
4638 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4639 FirstShift = Mips::DSLL;
4640 SecondShift = Mips::DSRL32;
4641 }
4642 if (ImmValue == 32) {
4643 FirstShift = Mips::DSLL32;
4644 SecondShift = Mips::DSRL32;
4645 }
4646 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4647 FirstShift = Mips::DSLL32;
4648 SecondShift = Mips::DSRL;
4649 }
4650 break;
4651 case Mips::DRORImm:
4652 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4653 FirstShift = Mips::DSRL;
4654 SecondShift = Mips::DSLL32;
4655 }
4656 if (ImmValue == 32) {
4657 FirstShift = Mips::DSRL32;
4658 SecondShift = Mips::DSLL32;
4659 }
4660 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4661 FirstShift = Mips::DSRL32;
4662 SecondShift = Mips::DSLL;
4663 }
4664 break;
4665 }
4666
4667 ATReg = getATReg(Inst.getLoc());
4668 if (!ATReg)
4669 return true;
4670
4671 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4672 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4673 Inst.getLoc(), STI);
4674 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4675
4676 return false;
4677 }
4678
4679 return true;
4680 }
4681
expandAbs(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4682 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4683 const MCSubtargetInfo *STI) {
4684 MipsTargetStreamer &TOut = getTargetStreamer();
4685 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4686 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4687
4688 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4689 if (FirstRegOp != SecondRegOp)
4690 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4691 else
4692 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4693 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4694
4695 return false;
4696 }
4697
expandMulImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4698 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4699 const MCSubtargetInfo *STI) {
4700 MipsTargetStreamer &TOut = getTargetStreamer();
4701 unsigned ATReg = Mips::NoRegister;
4702 unsigned DstReg = Inst.getOperand(0).getReg();
4703 unsigned SrcReg = Inst.getOperand(1).getReg();
4704 int32_t ImmValue = Inst.getOperand(2).getImm();
4705
4706 ATReg = getATReg(IDLoc);
4707 if (!ATReg)
4708 return true;
4709
4710 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4711 STI);
4712
4713 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4714 SrcReg, ATReg, IDLoc, STI);
4715
4716 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4717
4718 return false;
4719 }
4720
expandMulO(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4721 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4722 const MCSubtargetInfo *STI) {
4723 MipsTargetStreamer &TOut = getTargetStreamer();
4724 unsigned ATReg = Mips::NoRegister;
4725 unsigned DstReg = Inst.getOperand(0).getReg();
4726 unsigned SrcReg = Inst.getOperand(1).getReg();
4727 unsigned TmpReg = Inst.getOperand(2).getReg();
4728
4729 ATReg = getATReg(Inst.getLoc());
4730 if (!ATReg)
4731 return true;
4732
4733 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4734 SrcReg, TmpReg, IDLoc, STI);
4735
4736 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4737
4738 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4739 DstReg, DstReg, 0x1F, IDLoc, STI);
4740
4741 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4742
4743 if (useTraps()) {
4744 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4745 } else {
4746 MCContext & Context = TOut.getStreamer().getContext();
4747 MCSymbol * BrTarget = Context.createTempSymbol();
4748 MCOperand LabelOp =
4749 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4750
4751 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4752 if (AssemblerOptions.back()->isReorder())
4753 TOut.emitNop(IDLoc, STI);
4754 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4755
4756 TOut.getStreamer().EmitLabel(BrTarget);
4757 }
4758 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4759
4760 return false;
4761 }
4762
expandMulOU(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4763 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4764 const MCSubtargetInfo *STI) {
4765 MipsTargetStreamer &TOut = getTargetStreamer();
4766 unsigned ATReg = Mips::NoRegister;
4767 unsigned DstReg = Inst.getOperand(0).getReg();
4768 unsigned SrcReg = Inst.getOperand(1).getReg();
4769 unsigned TmpReg = Inst.getOperand(2).getReg();
4770
4771 ATReg = getATReg(IDLoc);
4772 if (!ATReg)
4773 return true;
4774
4775 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4776 SrcReg, TmpReg, IDLoc, STI);
4777
4778 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4779 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4780 if (useTraps()) {
4781 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4782 } else {
4783 MCContext & Context = TOut.getStreamer().getContext();
4784 MCSymbol * BrTarget = Context.createTempSymbol();
4785 MCOperand LabelOp =
4786 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4787
4788 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4789 if (AssemblerOptions.back()->isReorder())
4790 TOut.emitNop(IDLoc, STI);
4791 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4792
4793 TOut.getStreamer().EmitLabel(BrTarget);
4794 }
4795
4796 return false;
4797 }
4798
expandDMULMacro(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4799 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4800 const MCSubtargetInfo *STI) {
4801 MipsTargetStreamer &TOut = getTargetStreamer();
4802 unsigned DstReg = Inst.getOperand(0).getReg();
4803 unsigned SrcReg = Inst.getOperand(1).getReg();
4804 unsigned TmpReg = Inst.getOperand(2).getReg();
4805
4806 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4807 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4808
4809 return false;
4810 }
4811
4812 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4813 // lw $<reg+1>>, offset+4($reg2)'
4814 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4815 // sw $<reg+1>>, offset+4($reg2)'
4816 // for O32.
expandLoadStoreDMacro(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI,bool IsLoad)4817 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4818 MCStreamer &Out,
4819 const MCSubtargetInfo *STI,
4820 bool IsLoad) {
4821 if (!isABI_O32())
4822 return true;
4823
4824 warnIfNoMacro(IDLoc);
4825
4826 MipsTargetStreamer &TOut = getTargetStreamer();
4827 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4828 unsigned FirstReg = Inst.getOperand(0).getReg();
4829 unsigned SecondReg = nextReg(FirstReg);
4830 unsigned BaseReg = Inst.getOperand(1).getReg();
4831 if (!SecondReg)
4832 return true;
4833
4834 warnIfRegIndexIsAT(FirstReg, IDLoc);
4835
4836 assert(Inst.getOperand(2).isImm() &&
4837 "Offset for load macro is not immediate!");
4838
4839 MCOperand &FirstOffset = Inst.getOperand(2);
4840 signed NextOffset = FirstOffset.getImm() + 4;
4841 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4842
4843 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4844 return true;
4845
4846 // For loads, clobber the base register with the second load instead of the
4847 // first if the BaseReg == FirstReg.
4848 if (FirstReg != BaseReg || !IsLoad) {
4849 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4850 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4851 } else {
4852 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4853 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4854 }
4855
4856 return false;
4857 }
4858
expandSeq(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4859 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4860 const MCSubtargetInfo *STI) {
4861
4862 warnIfNoMacro(IDLoc);
4863 MipsTargetStreamer &TOut = getTargetStreamer();
4864
4865 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4866 Inst.getOperand(2).getReg() != Mips::ZERO) {
4867 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4868 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4869 IDLoc, STI);
4870 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4871 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4872 return false;
4873 }
4874
4875 unsigned Reg = 0;
4876 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4877 Reg = Inst.getOperand(2).getReg();
4878 } else {
4879 Reg = Inst.getOperand(1).getReg();
4880 }
4881 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4882 return false;
4883 }
4884
expandSeqI(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4885 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4886 const MCSubtargetInfo *STI) {
4887 warnIfNoMacro(IDLoc);
4888 MipsTargetStreamer &TOut = getTargetStreamer();
4889
4890 unsigned Opc;
4891 int64_t Imm = Inst.getOperand(2).getImm();
4892 unsigned Reg = Inst.getOperand(1).getReg();
4893
4894 if (Imm == 0) {
4895 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4896 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4897 return false;
4898 } else {
4899
4900 if (Reg == Mips::ZERO) {
4901 Warning(IDLoc, "comparison is always false");
4902 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4903 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4904 return false;
4905 }
4906
4907 if (Imm > -0x8000 && Imm < 0) {
4908 Imm = -Imm;
4909 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4910 } else {
4911 Opc = Mips::XORi;
4912 }
4913 }
4914 if (!isUInt<16>(Imm)) {
4915 unsigned ATReg = getATReg(IDLoc);
4916 if (!ATReg)
4917 return true;
4918
4919 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4920 Out, STI))
4921 return true;
4922
4923 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4924 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4925 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4926 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4927 return false;
4928 }
4929
4930 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4931 Imm, IDLoc, STI);
4932 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4933 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4934 return false;
4935 }
4936
4937 // Map the DSP accumulator and control register to the corresponding gpr
4938 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
4939 // do not map the DSP registers contigously to gpr registers.
getRegisterForMxtrDSP(MCInst & Inst,bool IsMFDSP)4940 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
4941 switch (Inst.getOpcode()) {
4942 case Mips::MFTLO:
4943 case Mips::MTTLO:
4944 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4945 case Mips::AC0:
4946 return Mips::ZERO;
4947 case Mips::AC1:
4948 return Mips::A0;
4949 case Mips::AC2:
4950 return Mips::T0;
4951 case Mips::AC3:
4952 return Mips::T4;
4953 default:
4954 llvm_unreachable("Unknown register for 'mttr' alias!");
4955 }
4956 case Mips::MFTHI:
4957 case Mips::MTTHI:
4958 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4959 case Mips::AC0:
4960 return Mips::AT;
4961 case Mips::AC1:
4962 return Mips::A1;
4963 case Mips::AC2:
4964 return Mips::T1;
4965 case Mips::AC3:
4966 return Mips::T5;
4967 default:
4968 llvm_unreachable("Unknown register for 'mttr' alias!");
4969 }
4970 case Mips::MFTACX:
4971 case Mips::MTTACX:
4972 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4973 case Mips::AC0:
4974 return Mips::V0;
4975 case Mips::AC1:
4976 return Mips::A2;
4977 case Mips::AC2:
4978 return Mips::T2;
4979 case Mips::AC3:
4980 return Mips::T6;
4981 default:
4982 llvm_unreachable("Unknown register for 'mttr' alias!");
4983 }
4984 case Mips::MFTDSP:
4985 case Mips::MTTDSP:
4986 return Mips::S0;
4987 default:
4988 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
4989 }
4990 }
4991
4992 // Map the floating point register operand to the corresponding register
4993 // operand.
getRegisterForMxtrFP(MCInst & Inst,bool IsMFTC1)4994 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
4995 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
4996 case Mips::F0: return Mips::ZERO;
4997 case Mips::F1: return Mips::AT;
4998 case Mips::F2: return Mips::V0;
4999 case Mips::F3: return Mips::V1;
5000 case Mips::F4: return Mips::A0;
5001 case Mips::F5: return Mips::A1;
5002 case Mips::F6: return Mips::A2;
5003 case Mips::F7: return Mips::A3;
5004 case Mips::F8: return Mips::T0;
5005 case Mips::F9: return Mips::T1;
5006 case Mips::F10: return Mips::T2;
5007 case Mips::F11: return Mips::T3;
5008 case Mips::F12: return Mips::T4;
5009 case Mips::F13: return Mips::T5;
5010 case Mips::F14: return Mips::T6;
5011 case Mips::F15: return Mips::T7;
5012 case Mips::F16: return Mips::S0;
5013 case Mips::F17: return Mips::S1;
5014 case Mips::F18: return Mips::S2;
5015 case Mips::F19: return Mips::S3;
5016 case Mips::F20: return Mips::S4;
5017 case Mips::F21: return Mips::S5;
5018 case Mips::F22: return Mips::S6;
5019 case Mips::F23: return Mips::S7;
5020 case Mips::F24: return Mips::T8;
5021 case Mips::F25: return Mips::T9;
5022 case Mips::F26: return Mips::K0;
5023 case Mips::F27: return Mips::K1;
5024 case Mips::F28: return Mips::GP;
5025 case Mips::F29: return Mips::SP;
5026 case Mips::F30: return Mips::FP;
5027 case Mips::F31: return Mips::RA;
5028 default: llvm_unreachable("Unknown register for mttc1 alias!");
5029 }
5030 }
5031
5032 // Map the coprocessor operand the corresponding gpr register operand.
getRegisterForMxtrC0(MCInst & Inst,bool IsMFTC0)5033 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5034 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5035 case Mips::COP00: return Mips::ZERO;
5036 case Mips::COP01: return Mips::AT;
5037 case Mips::COP02: return Mips::V0;
5038 case Mips::COP03: return Mips::V1;
5039 case Mips::COP04: return Mips::A0;
5040 case Mips::COP05: return Mips::A1;
5041 case Mips::COP06: return Mips::A2;
5042 case Mips::COP07: return Mips::A3;
5043 case Mips::COP08: return Mips::T0;
5044 case Mips::COP09: return Mips::T1;
5045 case Mips::COP010: return Mips::T2;
5046 case Mips::COP011: return Mips::T3;
5047 case Mips::COP012: return Mips::T4;
5048 case Mips::COP013: return Mips::T5;
5049 case Mips::COP014: return Mips::T6;
5050 case Mips::COP015: return Mips::T7;
5051 case Mips::COP016: return Mips::S0;
5052 case Mips::COP017: return Mips::S1;
5053 case Mips::COP018: return Mips::S2;
5054 case Mips::COP019: return Mips::S3;
5055 case Mips::COP020: return Mips::S4;
5056 case Mips::COP021: return Mips::S5;
5057 case Mips::COP022: return Mips::S6;
5058 case Mips::COP023: return Mips::S7;
5059 case Mips::COP024: return Mips::T8;
5060 case Mips::COP025: return Mips::T9;
5061 case Mips::COP026: return Mips::K0;
5062 case Mips::COP027: return Mips::K1;
5063 case Mips::COP028: return Mips::GP;
5064 case Mips::COP029: return Mips::SP;
5065 case Mips::COP030: return Mips::FP;
5066 case Mips::COP031: return Mips::RA;
5067 default: llvm_unreachable("Unknown register for mttc0 alias!");
5068 }
5069 }
5070
5071 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5072 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
expandMXTRAlias(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5073 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5074 const MCSubtargetInfo *STI) {
5075 MipsTargetStreamer &TOut = getTargetStreamer();
5076 unsigned rd = 0;
5077 unsigned u = 1;
5078 unsigned sel = 0;
5079 unsigned h = 0;
5080 bool IsMFTR = false;
5081 switch (Inst.getOpcode()) {
5082 case Mips::MFTC0:
5083 IsMFTR = true;
5084 LLVM_FALLTHROUGH;
5085 case Mips::MTTC0:
5086 u = 0;
5087 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5088 sel = Inst.getOperand(2).getImm();
5089 break;
5090 case Mips::MFTGPR:
5091 IsMFTR = true;
5092 LLVM_FALLTHROUGH;
5093 case Mips::MTTGPR:
5094 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5095 break;
5096 case Mips::MFTLO:
5097 case Mips::MFTHI:
5098 case Mips::MFTACX:
5099 case Mips::MFTDSP:
5100 IsMFTR = true;
5101 LLVM_FALLTHROUGH;
5102 case Mips::MTTLO:
5103 case Mips::MTTHI:
5104 case Mips::MTTACX:
5105 case Mips::MTTDSP:
5106 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5107 sel = 1;
5108 break;
5109 case Mips::MFTHC1:
5110 h = 1;
5111 LLVM_FALLTHROUGH;
5112 case Mips::MFTC1:
5113 IsMFTR = true;
5114 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5115 sel = 2;
5116 break;
5117 case Mips::MTTHC1:
5118 h = 1;
5119 LLVM_FALLTHROUGH;
5120 case Mips::MTTC1:
5121 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5122 sel = 2;
5123 break;
5124 case Mips::CFTC1:
5125 IsMFTR = true;
5126 LLVM_FALLTHROUGH;
5127 case Mips::CTTC1:
5128 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5129 sel = 3;
5130 break;
5131 }
5132 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5133 unsigned Op1 =
5134 IsMFTR ? rd
5135 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5136 : Inst.getOperand(0).getReg());
5137
5138 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5139 STI);
5140 return false;
5141 }
5142
5143 unsigned
checkEarlyTargetMatchPredicate(MCInst & Inst,const OperandVector & Operands)5144 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5145 const OperandVector &Operands) {
5146 switch (Inst.getOpcode()) {
5147 default:
5148 return Match_Success;
5149 case Mips::DATI:
5150 case Mips::DAHI:
5151 if (static_cast<MipsOperand &>(*Operands[1])
5152 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5153 return Match_Success;
5154 return Match_RequiresSameSrcAndDst;
5155 }
5156 }
5157
checkTargetMatchPredicate(MCInst & Inst)5158 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5159 switch (Inst.getOpcode()) {
5160 // As described by the MIPSR6 spec, daui must not use the zero operand for
5161 // its source operand.
5162 case Mips::DAUI:
5163 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5164 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5165 return Match_RequiresNoZeroRegister;
5166 return Match_Success;
5167 // As described by the Mips32r2 spec, the registers Rd and Rs for
5168 // jalr.hb must be different.
5169 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5170 // and registers Rd and Base for microMIPS lwp instruction
5171 case Mips::JALR_HB:
5172 case Mips::JALR_HB64:
5173 case Mips::JALRC_HB_MMR6:
5174 case Mips::JALRC_MMR6:
5175 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5176 return Match_RequiresDifferentSrcAndDst;
5177 return Match_Success;
5178 case Mips::LWP_MM:
5179 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5180 return Match_RequiresDifferentSrcAndDst;
5181 return Match_Success;
5182 case Mips::SYNC:
5183 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5184 return Match_NonZeroOperandForSync;
5185 return Match_Success;
5186 case Mips::MFC0:
5187 case Mips::MTC0:
5188 case Mips::MTC2:
5189 case Mips::MFC2:
5190 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5191 return Match_NonZeroOperandForMTCX;
5192 return Match_Success;
5193 // As described the MIPSR6 spec, the compact branches that compare registers
5194 // must:
5195 // a) Not use the zero register.
5196 // b) Not use the same register twice.
5197 // c) rs < rt for bnec, beqc.
5198 // NB: For this case, the encoding will swap the operands as their
5199 // ordering doesn't matter. GAS performs this transformation too.
5200 // Hence, that constraint does not have to be enforced.
5201 //
5202 // The compact branches that branch iff the signed addition of two registers
5203 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5204 // operand swapping. They do not have restriction of using the zero register.
5205 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5206 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5207 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5208 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5209 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5210 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5211 case Mips::BLEZC64:
5212 case Mips::BGEZC64:
5213 case Mips::BGTZC64:
5214 case Mips::BLTZC64:
5215 case Mips::BEQZC64:
5216 case Mips::BNEZC64:
5217 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5218 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5219 return Match_RequiresNoZeroRegister;
5220 return Match_Success;
5221 case Mips::BGEC: case Mips::BGEC_MMR6:
5222 case Mips::BLTC: case Mips::BLTC_MMR6:
5223 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5224 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5225 case Mips::BEQC: case Mips::BEQC_MMR6:
5226 case Mips::BNEC: case Mips::BNEC_MMR6:
5227 case Mips::BGEC64:
5228 case Mips::BLTC64:
5229 case Mips::BGEUC64:
5230 case Mips::BLTUC64:
5231 case Mips::BEQC64:
5232 case Mips::BNEC64:
5233 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5234 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5235 return Match_RequiresNoZeroRegister;
5236 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5237 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5238 return Match_RequiresNoZeroRegister;
5239 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5240 return Match_RequiresDifferentOperands;
5241 return Match_Success;
5242 case Mips::DINS: {
5243 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5244 "Operands must be immediates for dins!");
5245 const signed Pos = Inst.getOperand(2).getImm();
5246 const signed Size = Inst.getOperand(3).getImm();
5247 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5248 return Match_RequiresPosSizeRange0_32;
5249 return Match_Success;
5250 }
5251 case Mips::DINSM:
5252 case Mips::DINSU: {
5253 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5254 "Operands must be immediates for dinsm/dinsu!");
5255 const signed Pos = Inst.getOperand(2).getImm();
5256 const signed Size = Inst.getOperand(3).getImm();
5257 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5258 return Match_RequiresPosSizeRange33_64;
5259 return Match_Success;
5260 }
5261 case Mips::DEXT: {
5262 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5263 "Operands must be immediates for DEXTM!");
5264 const signed Pos = Inst.getOperand(2).getImm();
5265 const signed Size = Inst.getOperand(3).getImm();
5266 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5267 return Match_RequiresPosSizeUImm6;
5268 return Match_Success;
5269 }
5270 case Mips::DEXTM:
5271 case Mips::DEXTU: {
5272 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5273 "Operands must be immediates for dextm/dextu!");
5274 const signed Pos = Inst.getOperand(2).getImm();
5275 const signed Size = Inst.getOperand(3).getImm();
5276 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5277 return Match_RequiresPosSizeRange33_64;
5278 return Match_Success;
5279 }
5280 case Mips::CRC32B: case Mips::CRC32CB:
5281 case Mips::CRC32H: case Mips::CRC32CH:
5282 case Mips::CRC32W: case Mips::CRC32CW:
5283 case Mips::CRC32D: case Mips::CRC32CD:
5284 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5285 return Match_RequiresSameSrcAndDst;
5286 return Match_Success;
5287 }
5288
5289 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5290 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5291 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5292 return Match_NoFCCRegisterForCurrentISA;
5293
5294 return Match_Success;
5295
5296 }
5297
RefineErrorLoc(const SMLoc Loc,const OperandVector & Operands,uint64_t ErrorInfo)5298 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5299 uint64_t ErrorInfo) {
5300 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5301 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5302 if (ErrorLoc == SMLoc())
5303 return Loc;
5304 return ErrorLoc;
5305 }
5306 return Loc;
5307 }
5308
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)5309 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5310 OperandVector &Operands,
5311 MCStreamer &Out,
5312 uint64_t &ErrorInfo,
5313 bool MatchingInlineAsm) {
5314 MCInst Inst;
5315 unsigned MatchResult =
5316 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5317
5318 switch (MatchResult) {
5319 case Match_Success:
5320 if (processInstruction(Inst, IDLoc, Out, STI))
5321 return true;
5322 return false;
5323 case Match_MissingFeature:
5324 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5325 return true;
5326 case Match_InvalidOperand: {
5327 SMLoc ErrorLoc = IDLoc;
5328 if (ErrorInfo != ~0ULL) {
5329 if (ErrorInfo >= Operands.size())
5330 return Error(IDLoc, "too few operands for instruction");
5331
5332 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5333 if (ErrorLoc == SMLoc())
5334 ErrorLoc = IDLoc;
5335 }
5336
5337 return Error(ErrorLoc, "invalid operand for instruction");
5338 }
5339 case Match_NonZeroOperandForSync:
5340 return Error(IDLoc,
5341 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5342 case Match_NonZeroOperandForMTCX:
5343 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5344 case Match_MnemonicFail:
5345 return Error(IDLoc, "invalid instruction");
5346 case Match_RequiresDifferentSrcAndDst:
5347 return Error(IDLoc, "source and destination must be different");
5348 case Match_RequiresDifferentOperands:
5349 return Error(IDLoc, "registers must be different");
5350 case Match_RequiresNoZeroRegister:
5351 return Error(IDLoc, "invalid operand ($zero) for instruction");
5352 case Match_RequiresSameSrcAndDst:
5353 return Error(IDLoc, "source and destination must match");
5354 case Match_NoFCCRegisterForCurrentISA:
5355 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5356 "non-zero fcc register doesn't exist in current ISA level");
5357 case Match_Immz:
5358 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5359 case Match_UImm1_0:
5360 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5361 "expected 1-bit unsigned immediate");
5362 case Match_UImm2_0:
5363 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5364 "expected 2-bit unsigned immediate");
5365 case Match_UImm2_1:
5366 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5367 "expected immediate in range 1 .. 4");
5368 case Match_UImm3_0:
5369 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5370 "expected 3-bit unsigned immediate");
5371 case Match_UImm4_0:
5372 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5373 "expected 4-bit unsigned immediate");
5374 case Match_SImm4_0:
5375 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5376 "expected 4-bit signed immediate");
5377 case Match_UImm5_0:
5378 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5379 "expected 5-bit unsigned immediate");
5380 case Match_SImm5_0:
5381 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5382 "expected 5-bit signed immediate");
5383 case Match_UImm5_1:
5384 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5385 "expected immediate in range 1 .. 32");
5386 case Match_UImm5_32:
5387 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5388 "expected immediate in range 32 .. 63");
5389 case Match_UImm5_33:
5390 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5391 "expected immediate in range 33 .. 64");
5392 case Match_UImm5_0_Report_UImm6:
5393 // This is used on UImm5 operands that have a corresponding UImm5_32
5394 // operand to avoid confusing the user.
5395 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5396 "expected 6-bit unsigned immediate");
5397 case Match_UImm5_Lsl2:
5398 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5399 "expected both 7-bit unsigned immediate and multiple of 4");
5400 case Match_UImmRange2_64:
5401 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5402 "expected immediate in range 2 .. 64");
5403 case Match_UImm6_0:
5404 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5405 "expected 6-bit unsigned immediate");
5406 case Match_UImm6_Lsl2:
5407 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5408 "expected both 8-bit unsigned immediate and multiple of 4");
5409 case Match_SImm6_0:
5410 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5411 "expected 6-bit signed immediate");
5412 case Match_UImm7_0:
5413 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5414 "expected 7-bit unsigned immediate");
5415 case Match_UImm7_N1:
5416 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5417 "expected immediate in range -1 .. 126");
5418 case Match_SImm7_Lsl2:
5419 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5420 "expected both 9-bit signed immediate and multiple of 4");
5421 case Match_UImm8_0:
5422 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5423 "expected 8-bit unsigned immediate");
5424 case Match_UImm10_0:
5425 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5426 "expected 10-bit unsigned immediate");
5427 case Match_SImm10_0:
5428 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5429 "expected 10-bit signed immediate");
5430 case Match_SImm11_0:
5431 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5432 "expected 11-bit signed immediate");
5433 case Match_UImm16:
5434 case Match_UImm16_Relaxed:
5435 case Match_UImm16_AltRelaxed:
5436 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5437 "expected 16-bit unsigned immediate");
5438 case Match_SImm16:
5439 case Match_SImm16_Relaxed:
5440 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5441 "expected 16-bit signed immediate");
5442 case Match_SImm19_Lsl2:
5443 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5444 "expected both 19-bit signed immediate and multiple of 4");
5445 case Match_UImm20_0:
5446 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5447 "expected 20-bit unsigned immediate");
5448 case Match_UImm26_0:
5449 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5450 "expected 26-bit unsigned immediate");
5451 case Match_SImm32:
5452 case Match_SImm32_Relaxed:
5453 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5454 "expected 32-bit signed immediate");
5455 case Match_UImm32_Coerced:
5456 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5457 "expected 32-bit immediate");
5458 case Match_MemSImm9:
5459 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5460 "expected memory with 9-bit signed offset");
5461 case Match_MemSImm10:
5462 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5463 "expected memory with 10-bit signed offset");
5464 case Match_MemSImm10Lsl1:
5465 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5466 "expected memory with 11-bit signed offset and multiple of 2");
5467 case Match_MemSImm10Lsl2:
5468 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5469 "expected memory with 12-bit signed offset and multiple of 4");
5470 case Match_MemSImm10Lsl3:
5471 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5472 "expected memory with 13-bit signed offset and multiple of 8");
5473 case Match_MemSImm11:
5474 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5475 "expected memory with 11-bit signed offset");
5476 case Match_MemSImm12:
5477 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5478 "expected memory with 12-bit signed offset");
5479 case Match_MemSImm16:
5480 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5481 "expected memory with 16-bit signed offset");
5482 case Match_MemSImmPtr:
5483 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5484 "expected memory with 32-bit signed offset");
5485 case Match_RequiresPosSizeRange0_32: {
5486 SMLoc ErrorStart = Operands[3]->getStartLoc();
5487 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5488 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5489 SMRange(ErrorStart, ErrorEnd));
5490 }
5491 case Match_RequiresPosSizeUImm6: {
5492 SMLoc ErrorStart = Operands[3]->getStartLoc();
5493 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5494 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5495 SMRange(ErrorStart, ErrorEnd));
5496 }
5497 case Match_RequiresPosSizeRange33_64: {
5498 SMLoc ErrorStart = Operands[3]->getStartLoc();
5499 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5500 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5501 SMRange(ErrorStart, ErrorEnd));
5502 }
5503 }
5504
5505 llvm_unreachable("Implement any new match types added!");
5506 }
5507
warnIfRegIndexIsAT(unsigned RegIndex,SMLoc Loc)5508 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5509 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5510 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5511 ") without \".set noat\"");
5512 }
5513
warnIfNoMacro(SMLoc Loc)5514 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5515 if (!AssemblerOptions.back()->isMacro())
5516 Warning(Loc, "macro instruction expanded into multiple instructions");
5517 }
5518
ConvertXWPOperands(MCInst & Inst,const OperandVector & Operands)5519 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5520 const OperandVector &Operands) {
5521 assert(
5522 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
5523 "Unexpected instruction!");
5524 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5525 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5526 Inst.addOperand(MCOperand::createReg(NextReg));
5527 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5528 }
5529
5530 void
printWarningWithFixIt(const Twine & Msg,const Twine & FixMsg,SMRange Range,bool ShowColors)5531 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5532 SMRange Range, bool ShowColors) {
5533 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5534 Range, SMFixIt(Range, FixMsg),
5535 ShowColors);
5536 }
5537
matchCPURegisterName(StringRef Name)5538 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5539 int CC;
5540
5541 CC = StringSwitch<unsigned>(Name)
5542 .Case("zero", 0)
5543 .Cases("at", "AT", 1)
5544 .Case("a0", 4)
5545 .Case("a1", 5)
5546 .Case("a2", 6)
5547 .Case("a3", 7)
5548 .Case("v0", 2)
5549 .Case("v1", 3)
5550 .Case("s0", 16)
5551 .Case("s1", 17)
5552 .Case("s2", 18)
5553 .Case("s3", 19)
5554 .Case("s4", 20)
5555 .Case("s5", 21)
5556 .Case("s6", 22)
5557 .Case("s7", 23)
5558 .Case("k0", 26)
5559 .Case("k1", 27)
5560 .Case("gp", 28)
5561 .Case("sp", 29)
5562 .Case("fp", 30)
5563 .Case("s8", 30)
5564 .Case("ra", 31)
5565 .Case("t0", 8)
5566 .Case("t1", 9)
5567 .Case("t2", 10)
5568 .Case("t3", 11)
5569 .Case("t4", 12)
5570 .Case("t5", 13)
5571 .Case("t6", 14)
5572 .Case("t7", 15)
5573 .Case("t8", 24)
5574 .Case("t9", 25)
5575 .Default(-1);
5576
5577 if (!(isABI_N32() || isABI_N64()))
5578 return CC;
5579
5580 if (12 <= CC && CC <= 15) {
5581 // Name is one of t4-t7
5582 AsmToken RegTok = getLexer().peekTok();
5583 SMRange RegRange = RegTok.getLocRange();
5584
5585 StringRef FixedName = StringSwitch<StringRef>(Name)
5586 .Case("t4", "t0")
5587 .Case("t5", "t1")
5588 .Case("t6", "t2")
5589 .Case("t7", "t3")
5590 .Default("");
5591 assert(FixedName != "" && "Register name is not one of t4-t7.");
5592
5593 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5594 "Did you mean $" + FixedName + "?", RegRange);
5595 }
5596
5597 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5598 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5599 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5600 if (8 <= CC && CC <= 11)
5601 CC += 4;
5602
5603 if (CC == -1)
5604 CC = StringSwitch<unsigned>(Name)
5605 .Case("a4", 8)
5606 .Case("a5", 9)
5607 .Case("a6", 10)
5608 .Case("a7", 11)
5609 .Case("kt0", 26)
5610 .Case("kt1", 27)
5611 .Default(-1);
5612
5613 return CC;
5614 }
5615
matchHWRegsRegisterName(StringRef Name)5616 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5617 int CC;
5618
5619 CC = StringSwitch<unsigned>(Name)
5620 .Case("hwr_cpunum", 0)
5621 .Case("hwr_synci_step", 1)
5622 .Case("hwr_cc", 2)
5623 .Case("hwr_ccres", 3)
5624 .Case("hwr_ulr", 29)
5625 .Default(-1);
5626
5627 return CC;
5628 }
5629
matchFPURegisterName(StringRef Name)5630 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5631 if (Name[0] == 'f') {
5632 StringRef NumString = Name.substr(1);
5633 unsigned IntVal;
5634 if (NumString.getAsInteger(10, IntVal))
5635 return -1; // This is not an integer.
5636 if (IntVal > 31) // Maximum index for fpu register.
5637 return -1;
5638 return IntVal;
5639 }
5640 return -1;
5641 }
5642
matchFCCRegisterName(StringRef Name)5643 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5644 if (Name.startswith("fcc")) {
5645 StringRef NumString = Name.substr(3);
5646 unsigned IntVal;
5647 if (NumString.getAsInteger(10, IntVal))
5648 return -1; // This is not an integer.
5649 if (IntVal > 7) // There are only 8 fcc registers.
5650 return -1;
5651 return IntVal;
5652 }
5653 return -1;
5654 }
5655
matchACRegisterName(StringRef Name)5656 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5657 if (Name.startswith("ac")) {
5658 StringRef NumString = Name.substr(2);
5659 unsigned IntVal;
5660 if (NumString.getAsInteger(10, IntVal))
5661 return -1; // This is not an integer.
5662 if (IntVal > 3) // There are only 3 acc registers.
5663 return -1;
5664 return IntVal;
5665 }
5666 return -1;
5667 }
5668
matchMSA128RegisterName(StringRef Name)5669 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5670 unsigned IntVal;
5671
5672 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5673 return -1;
5674
5675 if (IntVal > 31)
5676 return -1;
5677
5678 return IntVal;
5679 }
5680
matchMSA128CtrlRegisterName(StringRef Name)5681 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5682 int CC;
5683
5684 CC = StringSwitch<unsigned>(Name)
5685 .Case("msair", 0)
5686 .Case("msacsr", 1)
5687 .Case("msaaccess", 2)
5688 .Case("msasave", 3)
5689 .Case("msamodify", 4)
5690 .Case("msarequest", 5)
5691 .Case("msamap", 6)
5692 .Case("msaunmap", 7)
5693 .Default(-1);
5694
5695 return CC;
5696 }
5697
canUseATReg()5698 bool MipsAsmParser::canUseATReg() {
5699 return AssemblerOptions.back()->getATRegIndex() != 0;
5700 }
5701
getATReg(SMLoc Loc)5702 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5703 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5704 if (ATIndex == 0) {
5705 reportParseError(Loc,
5706 "pseudo-instruction requires $at, which is not available");
5707 return 0;
5708 }
5709 unsigned AT = getReg(
5710 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5711 return AT;
5712 }
5713
getReg(int RC,int RegNo)5714 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5715 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5716 }
5717
parseOperand(OperandVector & Operands,StringRef Mnemonic)5718 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5719 MCAsmParser &Parser = getParser();
5720 LLVM_DEBUG(dbgs() << "parseOperand\n");
5721
5722 // Check if the current operand has a custom associated parser, if so, try to
5723 // custom parse the operand, or fallback to the general approach.
5724 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5725 if (ResTy == MatchOperand_Success)
5726 return false;
5727 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5728 // there was a match, but an error occurred, in which case, just return that
5729 // the operand parsing failed.
5730 if (ResTy == MatchOperand_ParseFail)
5731 return true;
5732
5733 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
5734
5735 switch (getLexer().getKind()) {
5736 case AsmToken::Dollar: {
5737 // Parse the register.
5738 SMLoc S = Parser.getTok().getLoc();
5739
5740 // Almost all registers have been parsed by custom parsers. There is only
5741 // one exception to this. $zero (and it's alias $0) will reach this point
5742 // for div, divu, and similar instructions because it is not an operand
5743 // to the instruction definition but an explicit register. Special case
5744 // this situation for now.
5745 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5746 return false;
5747
5748 // Maybe it is a symbol reference.
5749 StringRef Identifier;
5750 if (Parser.parseIdentifier(Identifier))
5751 return true;
5752
5753 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5754 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5755 // Otherwise create a symbol reference.
5756 const MCExpr *Res =
5757 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5758
5759 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5760 return false;
5761 }
5762 default: {
5763 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
5764
5765 const MCExpr *Expr;
5766 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5767 if (getParser().parseExpression(Expr))
5768 return true;
5769
5770 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5771
5772 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5773 return false;
5774 }
5775 } // switch(getLexer().getKind())
5776 return true;
5777 }
5778
isEvaluated(const MCExpr * Expr)5779 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5780 switch (Expr->getKind()) {
5781 case MCExpr::Constant:
5782 return true;
5783 case MCExpr::SymbolRef:
5784 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5785 case MCExpr::Binary: {
5786 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
5787 if (!isEvaluated(BE->getLHS()))
5788 return false;
5789 return isEvaluated(BE->getRHS());
5790 }
5791 case MCExpr::Unary:
5792 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5793 case MCExpr::Target:
5794 return true;
5795 }
5796 return false;
5797 }
5798
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)5799 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5800 SMLoc &EndLoc) {
5801 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5802 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5803 if (ResTy == MatchOperand_Success) {
5804 assert(Operands.size() == 1);
5805 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5806 StartLoc = Operand.getStartLoc();
5807 EndLoc = Operand.getEndLoc();
5808
5809 // AFAIK, we only support numeric registers and named GPR's in CFI
5810 // directives.
5811 // Don't worry about eating tokens before failing. Using an unrecognised
5812 // register is a parse error.
5813 if (Operand.isGPRAsmReg()) {
5814 // Resolve to GPR32 or GPR64 appropriately.
5815 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5816 }
5817
5818 return (RegNo == (unsigned)-1);
5819 }
5820
5821 assert(Operands.size() == 0);
5822 return (RegNo == (unsigned)-1);
5823 }
5824
parseMemOffset(const MCExpr * & Res,bool isParenExpr)5825 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5826 SMLoc S;
5827
5828 if (isParenExpr)
5829 return getParser().parseParenExprOfDepth(0, Res, S);
5830 return getParser().parseExpression(Res);
5831 }
5832
5833 OperandMatchResultTy
parseMemOperand(OperandVector & Operands)5834 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5835 MCAsmParser &Parser = getParser();
5836 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
5837 const MCExpr *IdVal = nullptr;
5838 SMLoc S;
5839 bool isParenExpr = false;
5840 OperandMatchResultTy Res = MatchOperand_NoMatch;
5841 // First operand is the offset.
5842 S = Parser.getTok().getLoc();
5843
5844 if (getLexer().getKind() == AsmToken::LParen) {
5845 Parser.Lex();
5846 isParenExpr = true;
5847 }
5848
5849 if (getLexer().getKind() != AsmToken::Dollar) {
5850 if (parseMemOffset(IdVal, isParenExpr))
5851 return MatchOperand_ParseFail;
5852
5853 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5854 if (Tok.isNot(AsmToken::LParen)) {
5855 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5856 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5857 SMLoc E =
5858 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5859 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5860 return MatchOperand_Success;
5861 }
5862 if (Tok.is(AsmToken::EndOfStatement)) {
5863 SMLoc E =
5864 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5865
5866 // Zero register assumed, add a memory operand with ZERO as its base.
5867 // "Base" will be managed by k_Memory.
5868 auto Base = MipsOperand::createGPRReg(
5869 0, "0", getContext().getRegisterInfo(), S, E, *this);
5870 Operands.push_back(
5871 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5872 return MatchOperand_Success;
5873 }
5874 MCBinaryExpr::Opcode Opcode;
5875 // GAS and LLVM treat comparison operators different. GAS will generate -1
5876 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5877 // highly unlikely to be found in a memory offset expression, we don't
5878 // handle them.
5879 switch (Tok.getKind()) {
5880 case AsmToken::Plus:
5881 Opcode = MCBinaryExpr::Add;
5882 Parser.Lex();
5883 break;
5884 case AsmToken::Minus:
5885 Opcode = MCBinaryExpr::Sub;
5886 Parser.Lex();
5887 break;
5888 case AsmToken::Star:
5889 Opcode = MCBinaryExpr::Mul;
5890 Parser.Lex();
5891 break;
5892 case AsmToken::Pipe:
5893 Opcode = MCBinaryExpr::Or;
5894 Parser.Lex();
5895 break;
5896 case AsmToken::Amp:
5897 Opcode = MCBinaryExpr::And;
5898 Parser.Lex();
5899 break;
5900 case AsmToken::LessLess:
5901 Opcode = MCBinaryExpr::Shl;
5902 Parser.Lex();
5903 break;
5904 case AsmToken::GreaterGreater:
5905 Opcode = MCBinaryExpr::LShr;
5906 Parser.Lex();
5907 break;
5908 case AsmToken::Caret:
5909 Opcode = MCBinaryExpr::Xor;
5910 Parser.Lex();
5911 break;
5912 case AsmToken::Slash:
5913 Opcode = MCBinaryExpr::Div;
5914 Parser.Lex();
5915 break;
5916 case AsmToken::Percent:
5917 Opcode = MCBinaryExpr::Mod;
5918 Parser.Lex();
5919 break;
5920 default:
5921 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5922 return MatchOperand_ParseFail;
5923 }
5924 const MCExpr * NextExpr;
5925 if (getParser().parseExpression(NextExpr))
5926 return MatchOperand_ParseFail;
5927 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5928 }
5929
5930 Parser.Lex(); // Eat the '(' token.
5931 }
5932
5933 Res = parseAnyRegister(Operands);
5934 if (Res != MatchOperand_Success)
5935 return Res;
5936
5937 if (Parser.getTok().isNot(AsmToken::RParen)) {
5938 Error(Parser.getTok().getLoc(), "')' expected");
5939 return MatchOperand_ParseFail;
5940 }
5941
5942 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5943
5944 Parser.Lex(); // Eat the ')' token.
5945
5946 if (!IdVal)
5947 IdVal = MCConstantExpr::create(0, getContext());
5948
5949 // Replace the register operand with the memory operand.
5950 std::unique_ptr<MipsOperand> op(
5951 static_cast<MipsOperand *>(Operands.back().release()));
5952 // Remove the register from the operands.
5953 // "op" will be managed by k_Memory.
5954 Operands.pop_back();
5955 // Add the memory operand.
5956 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5957 int64_t Imm;
5958 if (IdVal->evaluateAsAbsolute(Imm))
5959 IdVal = MCConstantExpr::create(Imm, getContext());
5960 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5961 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5962 getContext());
5963 }
5964
5965 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5966 return MatchOperand_Success;
5967 }
5968
searchSymbolAlias(OperandVector & Operands)5969 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5970 MCAsmParser &Parser = getParser();
5971 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5972 if (!Sym)
5973 return false;
5974
5975 SMLoc S = Parser.getTok().getLoc();
5976 if (Sym->isVariable()) {
5977 const MCExpr *Expr = Sym->getVariableValue();
5978 if (Expr->getKind() == MCExpr::SymbolRef) {
5979 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5980 StringRef DefSymbol = Ref->getSymbol().getName();
5981 if (DefSymbol.startswith("$")) {
5982 OperandMatchResultTy ResTy =
5983 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5984 if (ResTy == MatchOperand_Success) {
5985 Parser.Lex();
5986 return true;
5987 }
5988 if (ResTy == MatchOperand_ParseFail)
5989 llvm_unreachable("Should never ParseFail");
5990 }
5991 }
5992 } else if (Sym->isUnset()) {
5993 // If symbol is unset, it might be created in the `parseSetAssignment`
5994 // routine as an alias for a numeric register name.
5995 // Lookup in the aliases list.
5996 auto Entry = RegisterSets.find(Sym->getName());
5997 if (Entry != RegisterSets.end()) {
5998 OperandMatchResultTy ResTy =
5999 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6000 if (ResTy == MatchOperand_Success) {
6001 Parser.Lex();
6002 return true;
6003 }
6004 }
6005 }
6006
6007 return false;
6008 }
6009
6010 OperandMatchResultTy
matchAnyRegisterNameWithoutDollar(OperandVector & Operands,StringRef Identifier,SMLoc S)6011 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6012 StringRef Identifier,
6013 SMLoc S) {
6014 int Index = matchCPURegisterName(Identifier);
6015 if (Index != -1) {
6016 Operands.push_back(MipsOperand::createGPRReg(
6017 Index, Identifier, getContext().getRegisterInfo(), S,
6018 getLexer().getLoc(), *this));
6019 return MatchOperand_Success;
6020 }
6021
6022 Index = matchHWRegsRegisterName(Identifier);
6023 if (Index != -1) {
6024 Operands.push_back(MipsOperand::createHWRegsReg(
6025 Index, Identifier, getContext().getRegisterInfo(), S,
6026 getLexer().getLoc(), *this));
6027 return MatchOperand_Success;
6028 }
6029
6030 Index = matchFPURegisterName(Identifier);
6031 if (Index != -1) {
6032 Operands.push_back(MipsOperand::createFGRReg(
6033 Index, Identifier, getContext().getRegisterInfo(), S,
6034 getLexer().getLoc(), *this));
6035 return MatchOperand_Success;
6036 }
6037
6038 Index = matchFCCRegisterName(Identifier);
6039 if (Index != -1) {
6040 Operands.push_back(MipsOperand::createFCCReg(
6041 Index, Identifier, getContext().getRegisterInfo(), S,
6042 getLexer().getLoc(), *this));
6043 return MatchOperand_Success;
6044 }
6045
6046 Index = matchACRegisterName(Identifier);
6047 if (Index != -1) {
6048 Operands.push_back(MipsOperand::createACCReg(
6049 Index, Identifier, getContext().getRegisterInfo(), S,
6050 getLexer().getLoc(), *this));
6051 return MatchOperand_Success;
6052 }
6053
6054 Index = matchMSA128RegisterName(Identifier);
6055 if (Index != -1) {
6056 Operands.push_back(MipsOperand::createMSA128Reg(
6057 Index, Identifier, getContext().getRegisterInfo(), S,
6058 getLexer().getLoc(), *this));
6059 return MatchOperand_Success;
6060 }
6061
6062 Index = matchMSA128CtrlRegisterName(Identifier);
6063 if (Index != -1) {
6064 Operands.push_back(MipsOperand::createMSACtrlReg(
6065 Index, Identifier, getContext().getRegisterInfo(), S,
6066 getLexer().getLoc(), *this));
6067 return MatchOperand_Success;
6068 }
6069
6070 return MatchOperand_NoMatch;
6071 }
6072
6073 OperandMatchResultTy
matchAnyRegisterWithoutDollar(OperandVector & Operands,const AsmToken & Token,SMLoc S)6074 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6075 const AsmToken &Token, SMLoc S) {
6076 if (Token.is(AsmToken::Identifier)) {
6077 LLVM_DEBUG(dbgs() << ".. identifier\n");
6078 StringRef Identifier = Token.getIdentifier();
6079 OperandMatchResultTy ResTy =
6080 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6081 return ResTy;
6082 } else if (Token.is(AsmToken::Integer)) {
6083 LLVM_DEBUG(dbgs() << ".. integer\n");
6084 int64_t RegNum = Token.getIntVal();
6085 if (RegNum < 0 || RegNum > 31) {
6086 // Show the error, but treat invalid register
6087 // number as a normal one to continue parsing
6088 // and catch other possible errors.
6089 Error(getLexer().getLoc(), "invalid register number");
6090 }
6091 Operands.push_back(MipsOperand::createNumericReg(
6092 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6093 Token.getLoc(), *this));
6094 return MatchOperand_Success;
6095 }
6096
6097 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6098
6099 return MatchOperand_NoMatch;
6100 }
6101
6102 OperandMatchResultTy
matchAnyRegisterWithoutDollar(OperandVector & Operands,SMLoc S)6103 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6104 auto Token = getLexer().peekTok(false);
6105 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6106 }
6107
6108 OperandMatchResultTy
parseAnyRegister(OperandVector & Operands)6109 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6110 MCAsmParser &Parser = getParser();
6111 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6112
6113 auto Token = Parser.getTok();
6114
6115 SMLoc S = Token.getLoc();
6116
6117 if (Token.isNot(AsmToken::Dollar)) {
6118 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6119 if (Token.is(AsmToken::Identifier)) {
6120 if (searchSymbolAlias(Operands))
6121 return MatchOperand_Success;
6122 }
6123 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6124 return MatchOperand_NoMatch;
6125 }
6126 LLVM_DEBUG(dbgs() << ".. $\n");
6127
6128 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6129 if (ResTy == MatchOperand_Success) {
6130 Parser.Lex(); // $
6131 Parser.Lex(); // identifier
6132 }
6133 return ResTy;
6134 }
6135
6136 OperandMatchResultTy
parseJumpTarget(OperandVector & Operands)6137 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6138 MCAsmParser &Parser = getParser();
6139 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6140
6141 SMLoc S = getLexer().getLoc();
6142
6143 // Registers are a valid target and have priority over symbols.
6144 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6145 if (ResTy != MatchOperand_NoMatch)
6146 return ResTy;
6147
6148 // Integers and expressions are acceptable
6149 const MCExpr *Expr = nullptr;
6150 if (Parser.parseExpression(Expr)) {
6151 // We have no way of knowing if a symbol was consumed so we must ParseFail
6152 return MatchOperand_ParseFail;
6153 }
6154 Operands.push_back(
6155 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6156 return MatchOperand_Success;
6157 }
6158
6159 OperandMatchResultTy
parseInvNum(OperandVector & Operands)6160 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6161 MCAsmParser &Parser = getParser();
6162 const MCExpr *IdVal;
6163 // If the first token is '$' we may have register operand. We have to reject
6164 // cases where it is not a register. Complicating the matter is that
6165 // register names are not reserved across all ABIs.
6166 // Peek past the dollar to see if it's a register name for this ABI.
6167 SMLoc S = Parser.getTok().getLoc();
6168 if (Parser.getTok().is(AsmToken::Dollar)) {
6169 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6170 ? MatchOperand_ParseFail
6171 : MatchOperand_NoMatch;
6172 }
6173 if (getParser().parseExpression(IdVal))
6174 return MatchOperand_ParseFail;
6175 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6176 if (!MCE)
6177 return MatchOperand_NoMatch;
6178 int64_t Val = MCE->getValue();
6179 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6180 Operands.push_back(MipsOperand::CreateImm(
6181 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6182 return MatchOperand_Success;
6183 }
6184
6185 OperandMatchResultTy
parseRegisterList(OperandVector & Operands)6186 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6187 MCAsmParser &Parser = getParser();
6188 SmallVector<unsigned, 10> Regs;
6189 unsigned RegNo;
6190 unsigned PrevReg = Mips::NoRegister;
6191 bool RegRange = false;
6192 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6193
6194 if (Parser.getTok().isNot(AsmToken::Dollar))
6195 return MatchOperand_ParseFail;
6196
6197 SMLoc S = Parser.getTok().getLoc();
6198 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6199 SMLoc E = getLexer().getLoc();
6200 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6201 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6202 if (RegRange) {
6203 // Remove last register operand because registers from register range
6204 // should be inserted first.
6205 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6206 (!isGP64bit() && RegNo == Mips::RA)) {
6207 Regs.push_back(RegNo);
6208 } else {
6209 unsigned TmpReg = PrevReg + 1;
6210 while (TmpReg <= RegNo) {
6211 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6212 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6213 isGP64bit())) {
6214 Error(E, "invalid register operand");
6215 return MatchOperand_ParseFail;
6216 }
6217
6218 PrevReg = TmpReg;
6219 Regs.push_back(TmpReg++);
6220 }
6221 }
6222
6223 RegRange = false;
6224 } else {
6225 if ((PrevReg == Mips::NoRegister) &&
6226 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6227 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6228 Error(E, "$16 or $31 expected");
6229 return MatchOperand_ParseFail;
6230 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6231 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6232 !isGP64bit()) ||
6233 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6234 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6235 isGP64bit()))) {
6236 Error(E, "invalid register operand");
6237 return MatchOperand_ParseFail;
6238 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6239 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6240 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6241 isGP64bit()))) {
6242 Error(E, "consecutive register numbers expected");
6243 return MatchOperand_ParseFail;
6244 }
6245
6246 Regs.push_back(RegNo);
6247 }
6248
6249 if (Parser.getTok().is(AsmToken::Minus))
6250 RegRange = true;
6251
6252 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6253 !Parser.getTok().isNot(AsmToken::Comma)) {
6254 Error(E, "',' or '-' expected");
6255 return MatchOperand_ParseFail;
6256 }
6257
6258 Lex(); // Consume comma or minus
6259 if (Parser.getTok().isNot(AsmToken::Dollar))
6260 break;
6261
6262 PrevReg = RegNo;
6263 }
6264
6265 SMLoc E = Parser.getTok().getLoc();
6266 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6267 parseMemOperand(Operands);
6268 return MatchOperand_Success;
6269 }
6270
6271 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6272 /// either this.
6273 /// ::= '(', register, ')'
6274 /// handle it before we iterate so we don't get tripped up by the lack of
6275 /// a comma.
parseParenSuffix(StringRef Name,OperandVector & Operands)6276 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6277 MCAsmParser &Parser = getParser();
6278 if (getLexer().is(AsmToken::LParen)) {
6279 Operands.push_back(
6280 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6281 Parser.Lex();
6282 if (parseOperand(Operands, Name)) {
6283 SMLoc Loc = getLexer().getLoc();
6284 return Error(Loc, "unexpected token in argument list");
6285 }
6286 if (Parser.getTok().isNot(AsmToken::RParen)) {
6287 SMLoc Loc = getLexer().getLoc();
6288 return Error(Loc, "unexpected token, expected ')'");
6289 }
6290 Operands.push_back(
6291 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6292 Parser.Lex();
6293 }
6294 return false;
6295 }
6296
6297 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6298 /// either one of these.
6299 /// ::= '[', register, ']'
6300 /// ::= '[', integer, ']'
6301 /// handle it before we iterate so we don't get tripped up by the lack of
6302 /// a comma.
parseBracketSuffix(StringRef Name,OperandVector & Operands)6303 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6304 OperandVector &Operands) {
6305 MCAsmParser &Parser = getParser();
6306 if (getLexer().is(AsmToken::LBrac)) {
6307 Operands.push_back(
6308 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6309 Parser.Lex();
6310 if (parseOperand(Operands, Name)) {
6311 SMLoc Loc = getLexer().getLoc();
6312 return Error(Loc, "unexpected token in argument list");
6313 }
6314 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6315 SMLoc Loc = getLexer().getLoc();
6316 return Error(Loc, "unexpected token, expected ']'");
6317 }
6318 Operands.push_back(
6319 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6320 Parser.Lex();
6321 }
6322 return false;
6323 }
6324
6325 static std::string MipsMnemonicSpellCheck(StringRef S, uint64_t FBS,
6326 unsigned VariantID = 0);
6327
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)6328 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6329 SMLoc NameLoc, OperandVector &Operands) {
6330 MCAsmParser &Parser = getParser();
6331 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6332
6333 // We have reached first instruction, module directive are now forbidden.
6334 getTargetStreamer().forbidModuleDirective();
6335
6336 // Check if we have valid mnemonic
6337 if (!mnemonicIsValid(Name, 0)) {
6338 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6339 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6340 return Error(NameLoc, "unknown instruction" + Suggestion);
6341 }
6342 // First operand in MCInst is instruction mnemonic.
6343 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6344
6345 // Read the remaining operands.
6346 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6347 // Read the first operand.
6348 if (parseOperand(Operands, Name)) {
6349 SMLoc Loc = getLexer().getLoc();
6350 return Error(Loc, "unexpected token in argument list");
6351 }
6352 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6353 return true;
6354 // AFAIK, parenthesis suffixes are never on the first operand
6355
6356 while (getLexer().is(AsmToken::Comma)) {
6357 Parser.Lex(); // Eat the comma.
6358 // Parse and remember the operand.
6359 if (parseOperand(Operands, Name)) {
6360 SMLoc Loc = getLexer().getLoc();
6361 return Error(Loc, "unexpected token in argument list");
6362 }
6363 // Parse bracket and parenthesis suffixes before we iterate
6364 if (getLexer().is(AsmToken::LBrac)) {
6365 if (parseBracketSuffix(Name, Operands))
6366 return true;
6367 } else if (getLexer().is(AsmToken::LParen) &&
6368 parseParenSuffix(Name, Operands))
6369 return true;
6370 }
6371 }
6372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6373 SMLoc Loc = getLexer().getLoc();
6374 return Error(Loc, "unexpected token in argument list");
6375 }
6376 Parser.Lex(); // Consume the EndOfStatement.
6377 return false;
6378 }
6379
6380 // FIXME: Given that these have the same name, these should both be
6381 // consistent on affecting the Parser.
reportParseError(Twine ErrorMsg)6382 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6383 SMLoc Loc = getLexer().getLoc();
6384 return Error(Loc, ErrorMsg);
6385 }
6386
reportParseError(SMLoc Loc,Twine ErrorMsg)6387 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6388 return Error(Loc, ErrorMsg);
6389 }
6390
parseSetNoAtDirective()6391 bool MipsAsmParser::parseSetNoAtDirective() {
6392 MCAsmParser &Parser = getParser();
6393 // Line should look like: ".set noat".
6394
6395 // Set the $at register to $0.
6396 AssemblerOptions.back()->setATRegIndex(0);
6397
6398 Parser.Lex(); // Eat "noat".
6399
6400 // If this is not the end of the statement, report an error.
6401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6402 reportParseError("unexpected token, expected end of statement");
6403 return false;
6404 }
6405
6406 getTargetStreamer().emitDirectiveSetNoAt();
6407 Parser.Lex(); // Consume the EndOfStatement.
6408 return false;
6409 }
6410
parseSetAtDirective()6411 bool MipsAsmParser::parseSetAtDirective() {
6412 // Line can be: ".set at", which sets $at to $1
6413 // or ".set at=$reg", which sets $at to $reg.
6414 MCAsmParser &Parser = getParser();
6415 Parser.Lex(); // Eat "at".
6416
6417 if (getLexer().is(AsmToken::EndOfStatement)) {
6418 // No register was specified, so we set $at to $1.
6419 AssemblerOptions.back()->setATRegIndex(1);
6420
6421 getTargetStreamer().emitDirectiveSetAt();
6422 Parser.Lex(); // Consume the EndOfStatement.
6423 return false;
6424 }
6425
6426 if (getLexer().isNot(AsmToken::Equal)) {
6427 reportParseError("unexpected token, expected equals sign");
6428 return false;
6429 }
6430 Parser.Lex(); // Eat "=".
6431
6432 if (getLexer().isNot(AsmToken::Dollar)) {
6433 if (getLexer().is(AsmToken::EndOfStatement)) {
6434 reportParseError("no register specified");
6435 return false;
6436 } else {
6437 reportParseError("unexpected token, expected dollar sign '$'");
6438 return false;
6439 }
6440 }
6441 Parser.Lex(); // Eat "$".
6442
6443 // Find out what "reg" is.
6444 unsigned AtRegNo;
6445 const AsmToken &Reg = Parser.getTok();
6446 if (Reg.is(AsmToken::Identifier)) {
6447 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6448 } else if (Reg.is(AsmToken::Integer)) {
6449 AtRegNo = Reg.getIntVal();
6450 } else {
6451 reportParseError("unexpected token, expected identifier or integer");
6452 return false;
6453 }
6454
6455 // Check if $reg is a valid register. If it is, set $at to $reg.
6456 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6457 reportParseError("invalid register");
6458 return false;
6459 }
6460 Parser.Lex(); // Eat "reg".
6461
6462 // If this is not the end of the statement, report an error.
6463 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6464 reportParseError("unexpected token, expected end of statement");
6465 return false;
6466 }
6467
6468 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6469
6470 Parser.Lex(); // Consume the EndOfStatement.
6471 return false;
6472 }
6473
parseSetReorderDirective()6474 bool MipsAsmParser::parseSetReorderDirective() {
6475 MCAsmParser &Parser = getParser();
6476 Parser.Lex();
6477 // If this is not the end of the statement, report an error.
6478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6479 reportParseError("unexpected token, expected end of statement");
6480 return false;
6481 }
6482 AssemblerOptions.back()->setReorder();
6483 getTargetStreamer().emitDirectiveSetReorder();
6484 Parser.Lex(); // Consume the EndOfStatement.
6485 return false;
6486 }
6487
parseSetNoReorderDirective()6488 bool MipsAsmParser::parseSetNoReorderDirective() {
6489 MCAsmParser &Parser = getParser();
6490 Parser.Lex();
6491 // If this is not the end of the statement, report an error.
6492 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6493 reportParseError("unexpected token, expected end of statement");
6494 return false;
6495 }
6496 AssemblerOptions.back()->setNoReorder();
6497 getTargetStreamer().emitDirectiveSetNoReorder();
6498 Parser.Lex(); // Consume the EndOfStatement.
6499 return false;
6500 }
6501
parseSetMacroDirective()6502 bool MipsAsmParser::parseSetMacroDirective() {
6503 MCAsmParser &Parser = getParser();
6504 Parser.Lex();
6505 // If this is not the end of the statement, report an error.
6506 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6507 reportParseError("unexpected token, expected end of statement");
6508 return false;
6509 }
6510 AssemblerOptions.back()->setMacro();
6511 getTargetStreamer().emitDirectiveSetMacro();
6512 Parser.Lex(); // Consume the EndOfStatement.
6513 return false;
6514 }
6515
parseSetNoMacroDirective()6516 bool MipsAsmParser::parseSetNoMacroDirective() {
6517 MCAsmParser &Parser = getParser();
6518 Parser.Lex();
6519 // If this is not the end of the statement, report an error.
6520 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6521 reportParseError("unexpected token, expected end of statement");
6522 return false;
6523 }
6524 if (AssemblerOptions.back()->isReorder()) {
6525 reportParseError("`noreorder' must be set before `nomacro'");
6526 return false;
6527 }
6528 AssemblerOptions.back()->setNoMacro();
6529 getTargetStreamer().emitDirectiveSetNoMacro();
6530 Parser.Lex(); // Consume the EndOfStatement.
6531 return false;
6532 }
6533
parseSetMsaDirective()6534 bool MipsAsmParser::parseSetMsaDirective() {
6535 MCAsmParser &Parser = getParser();
6536 Parser.Lex();
6537
6538 // If this is not the end of the statement, report an error.
6539 if (getLexer().isNot(AsmToken::EndOfStatement))
6540 return reportParseError("unexpected token, expected end of statement");
6541
6542 setFeatureBits(Mips::FeatureMSA, "msa");
6543 getTargetStreamer().emitDirectiveSetMsa();
6544 return false;
6545 }
6546
parseSetNoMsaDirective()6547 bool MipsAsmParser::parseSetNoMsaDirective() {
6548 MCAsmParser &Parser = getParser();
6549 Parser.Lex();
6550
6551 // If this is not the end of the statement, report an error.
6552 if (getLexer().isNot(AsmToken::EndOfStatement))
6553 return reportParseError("unexpected token, expected end of statement");
6554
6555 clearFeatureBits(Mips::FeatureMSA, "msa");
6556 getTargetStreamer().emitDirectiveSetNoMsa();
6557 return false;
6558 }
6559
parseSetNoDspDirective()6560 bool MipsAsmParser::parseSetNoDspDirective() {
6561 MCAsmParser &Parser = getParser();
6562 Parser.Lex(); // Eat "nodsp".
6563
6564 // If this is not the end of the statement, report an error.
6565 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6566 reportParseError("unexpected token, expected end of statement");
6567 return false;
6568 }
6569
6570 clearFeatureBits(Mips::FeatureDSP, "dsp");
6571 getTargetStreamer().emitDirectiveSetNoDsp();
6572 return false;
6573 }
6574
parseSetMips16Directive()6575 bool MipsAsmParser::parseSetMips16Directive() {
6576 MCAsmParser &Parser = getParser();
6577 Parser.Lex(); // Eat "mips16".
6578
6579 // If this is not the end of the statement, report an error.
6580 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6581 reportParseError("unexpected token, expected end of statement");
6582 return false;
6583 }
6584
6585 setFeatureBits(Mips::FeatureMips16, "mips16");
6586 getTargetStreamer().emitDirectiveSetMips16();
6587 Parser.Lex(); // Consume the EndOfStatement.
6588 return false;
6589 }
6590
parseSetNoMips16Directive()6591 bool MipsAsmParser::parseSetNoMips16Directive() {
6592 MCAsmParser &Parser = getParser();
6593 Parser.Lex(); // Eat "nomips16".
6594
6595 // If this is not the end of the statement, report an error.
6596 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6597 reportParseError("unexpected token, expected end of statement");
6598 return false;
6599 }
6600
6601 clearFeatureBits(Mips::FeatureMips16, "mips16");
6602 getTargetStreamer().emitDirectiveSetNoMips16();
6603 Parser.Lex(); // Consume the EndOfStatement.
6604 return false;
6605 }
6606
parseSetFpDirective()6607 bool MipsAsmParser::parseSetFpDirective() {
6608 MCAsmParser &Parser = getParser();
6609 MipsABIFlagsSection::FpABIKind FpAbiVal;
6610 // Line can be: .set fp=32
6611 // .set fp=xx
6612 // .set fp=64
6613 Parser.Lex(); // Eat fp token
6614 AsmToken Tok = Parser.getTok();
6615 if (Tok.isNot(AsmToken::Equal)) {
6616 reportParseError("unexpected token, expected equals sign '='");
6617 return false;
6618 }
6619 Parser.Lex(); // Eat '=' token.
6620 Tok = Parser.getTok();
6621
6622 if (!parseFpABIValue(FpAbiVal, ".set"))
6623 return false;
6624
6625 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6626 reportParseError("unexpected token, expected end of statement");
6627 return false;
6628 }
6629 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6630 Parser.Lex(); // Consume the EndOfStatement.
6631 return false;
6632 }
6633
parseSetOddSPRegDirective()6634 bool MipsAsmParser::parseSetOddSPRegDirective() {
6635 MCAsmParser &Parser = getParser();
6636
6637 Parser.Lex(); // Eat "oddspreg".
6638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6639 reportParseError("unexpected token, expected end of statement");
6640 return false;
6641 }
6642
6643 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6644 getTargetStreamer().emitDirectiveSetOddSPReg();
6645 return false;
6646 }
6647
parseSetNoOddSPRegDirective()6648 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6649 MCAsmParser &Parser = getParser();
6650
6651 Parser.Lex(); // Eat "nooddspreg".
6652 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6653 reportParseError("unexpected token, expected end of statement");
6654 return false;
6655 }
6656
6657 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6658 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6659 return false;
6660 }
6661
parseSetMtDirective()6662 bool MipsAsmParser::parseSetMtDirective() {
6663 MCAsmParser &Parser = getParser();
6664 Parser.Lex(); // Eat "mt".
6665
6666 // If this is not the end of the statement, report an error.
6667 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6668 reportParseError("unexpected token, expected end of statement");
6669 return false;
6670 }
6671
6672 setFeatureBits(Mips::FeatureMT, "mt");
6673 getTargetStreamer().emitDirectiveSetMt();
6674 Parser.Lex(); // Consume the EndOfStatement.
6675 return false;
6676 }
6677
parseSetNoMtDirective()6678 bool MipsAsmParser::parseSetNoMtDirective() {
6679 MCAsmParser &Parser = getParser();
6680 Parser.Lex(); // Eat "nomt".
6681
6682 // If this is not the end of the statement, report an error.
6683 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6684 reportParseError("unexpected token, expected end of statement");
6685 return false;
6686 }
6687
6688 clearFeatureBits(Mips::FeatureMT, "mt");
6689
6690 getTargetStreamer().emitDirectiveSetNoMt();
6691 Parser.Lex(); // Consume the EndOfStatement.
6692 return false;
6693 }
6694
parseSetNoCRCDirective()6695 bool MipsAsmParser::parseSetNoCRCDirective() {
6696 MCAsmParser &Parser = getParser();
6697 Parser.Lex(); // Eat "nocrc".
6698
6699 // If this is not the end of the statement, report an error.
6700 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6701 reportParseError("unexpected token, expected end of statement");
6702 return false;
6703 }
6704
6705 clearFeatureBits(Mips::FeatureCRC, "crc");
6706
6707 getTargetStreamer().emitDirectiveSetNoCRC();
6708 Parser.Lex(); // Consume the EndOfStatement.
6709 return false;
6710 }
6711
parseSetNoVirtDirective()6712 bool MipsAsmParser::parseSetNoVirtDirective() {
6713 MCAsmParser &Parser = getParser();
6714 Parser.Lex(); // Eat "novirt".
6715
6716 // If this is not the end of the statement, report an error.
6717 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6718 reportParseError("unexpected token, expected end of statement");
6719 return false;
6720 }
6721
6722 clearFeatureBits(Mips::FeatureVirt, "virt");
6723
6724 getTargetStreamer().emitDirectiveSetNoVirt();
6725 Parser.Lex(); // Consume the EndOfStatement.
6726 return false;
6727 }
6728
parseSetNoGINVDirective()6729 bool MipsAsmParser::parseSetNoGINVDirective() {
6730 MCAsmParser &Parser = getParser();
6731 Parser.Lex(); // Eat "noginv".
6732
6733 // If this is not the end of the statement, report an error.
6734 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6735 reportParseError("unexpected token, expected end of statement");
6736 return false;
6737 }
6738
6739 clearFeatureBits(Mips::FeatureGINV, "ginv");
6740
6741 getTargetStreamer().emitDirectiveSetNoGINV();
6742 Parser.Lex(); // Consume the EndOfStatement.
6743 return false;
6744 }
6745
parseSetPopDirective()6746 bool MipsAsmParser::parseSetPopDirective() {
6747 MCAsmParser &Parser = getParser();
6748 SMLoc Loc = getLexer().getLoc();
6749
6750 Parser.Lex();
6751 if (getLexer().isNot(AsmToken::EndOfStatement))
6752 return reportParseError("unexpected token, expected end of statement");
6753
6754 // Always keep an element on the options "stack" to prevent the user
6755 // from changing the initial options. This is how we remember them.
6756 if (AssemblerOptions.size() == 2)
6757 return reportParseError(Loc, ".set pop with no .set push");
6758
6759 MCSubtargetInfo &STI = copySTI();
6760 AssemblerOptions.pop_back();
6761 setAvailableFeatures(
6762 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6763 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6764
6765 getTargetStreamer().emitDirectiveSetPop();
6766 return false;
6767 }
6768
parseSetPushDirective()6769 bool MipsAsmParser::parseSetPushDirective() {
6770 MCAsmParser &Parser = getParser();
6771 Parser.Lex();
6772 if (getLexer().isNot(AsmToken::EndOfStatement))
6773 return reportParseError("unexpected token, expected end of statement");
6774
6775 // Create a copy of the current assembler options environment and push it.
6776 AssemblerOptions.push_back(
6777 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6778
6779 getTargetStreamer().emitDirectiveSetPush();
6780 return false;
6781 }
6782
parseSetSoftFloatDirective()6783 bool MipsAsmParser::parseSetSoftFloatDirective() {
6784 MCAsmParser &Parser = getParser();
6785 Parser.Lex();
6786 if (getLexer().isNot(AsmToken::EndOfStatement))
6787 return reportParseError("unexpected token, expected end of statement");
6788
6789 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6790 getTargetStreamer().emitDirectiveSetSoftFloat();
6791 return false;
6792 }
6793
parseSetHardFloatDirective()6794 bool MipsAsmParser::parseSetHardFloatDirective() {
6795 MCAsmParser &Parser = getParser();
6796 Parser.Lex();
6797 if (getLexer().isNot(AsmToken::EndOfStatement))
6798 return reportParseError("unexpected token, expected end of statement");
6799
6800 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6801 getTargetStreamer().emitDirectiveSetHardFloat();
6802 return false;
6803 }
6804
parseSetAssignment()6805 bool MipsAsmParser::parseSetAssignment() {
6806 StringRef Name;
6807 const MCExpr *Value;
6808 MCAsmParser &Parser = getParser();
6809
6810 if (Parser.parseIdentifier(Name))
6811 return reportParseError("expected identifier after .set");
6812
6813 if (getLexer().isNot(AsmToken::Comma))
6814 return reportParseError("unexpected token, expected comma");
6815 Lex(); // Eat comma
6816
6817 if (getLexer().is(AsmToken::Dollar) &&
6818 getLexer().peekTok().is(AsmToken::Integer)) {
6819 // Parse assignment of a numeric register:
6820 // .set r1,$1
6821 Parser.Lex(); // Eat $.
6822 RegisterSets[Name] = Parser.getTok();
6823 Parser.Lex(); // Eat identifier.
6824 getContext().getOrCreateSymbol(Name);
6825 } else if (!Parser.parseExpression(Value)) {
6826 // Parse assignment of an expression including
6827 // symbolic registers:
6828 // .set $tmp, $BB0-$BB1
6829 // .set r2, $f2
6830 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6831 Sym->setVariableValue(Value);
6832 } else {
6833 return reportParseError("expected valid expression after comma");
6834 }
6835
6836 return false;
6837 }
6838
parseSetMips0Directive()6839 bool MipsAsmParser::parseSetMips0Directive() {
6840 MCAsmParser &Parser = getParser();
6841 Parser.Lex();
6842 if (getLexer().isNot(AsmToken::EndOfStatement))
6843 return reportParseError("unexpected token, expected end of statement");
6844
6845 // Reset assembler options to their initial values.
6846 MCSubtargetInfo &STI = copySTI();
6847 setAvailableFeatures(
6848 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6849 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6850 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6851
6852 getTargetStreamer().emitDirectiveSetMips0();
6853 return false;
6854 }
6855
parseSetArchDirective()6856 bool MipsAsmParser::parseSetArchDirective() {
6857 MCAsmParser &Parser = getParser();
6858 Parser.Lex();
6859 if (getLexer().isNot(AsmToken::Equal))
6860 return reportParseError("unexpected token, expected equals sign");
6861
6862 Parser.Lex();
6863 StringRef Arch;
6864 if (Parser.parseIdentifier(Arch))
6865 return reportParseError("expected arch identifier");
6866
6867 StringRef ArchFeatureName =
6868 StringSwitch<StringRef>(Arch)
6869 .Case("mips1", "mips1")
6870 .Case("mips2", "mips2")
6871 .Case("mips3", "mips3")
6872 .Case("mips4", "mips4")
6873 .Case("mips5", "mips5")
6874 .Case("mips32", "mips32")
6875 .Case("mips32r2", "mips32r2")
6876 .Case("mips32r3", "mips32r3")
6877 .Case("mips32r5", "mips32r5")
6878 .Case("mips32r6", "mips32r6")
6879 .Case("mips64", "mips64")
6880 .Case("mips64r2", "mips64r2")
6881 .Case("mips64r3", "mips64r3")
6882 .Case("mips64r5", "mips64r5")
6883 .Case("mips64r6", "mips64r6")
6884 .Case("octeon", "cnmips")
6885 .Case("r4000", "mips3") // This is an implementation of Mips3.
6886 .Default("");
6887
6888 if (ArchFeatureName.empty())
6889 return reportParseError("unsupported architecture");
6890
6891 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
6892 return reportParseError("mips64r6 does not support microMIPS");
6893
6894 selectArch(ArchFeatureName);
6895 getTargetStreamer().emitDirectiveSetArch(Arch);
6896 return false;
6897 }
6898
parseSetFeature(uint64_t Feature)6899 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6900 MCAsmParser &Parser = getParser();
6901 Parser.Lex();
6902 if (getLexer().isNot(AsmToken::EndOfStatement))
6903 return reportParseError("unexpected token, expected end of statement");
6904
6905 switch (Feature) {
6906 default:
6907 llvm_unreachable("Unimplemented feature");
6908 case Mips::FeatureDSP:
6909 setFeatureBits(Mips::FeatureDSP, "dsp");
6910 getTargetStreamer().emitDirectiveSetDsp();
6911 break;
6912 case Mips::FeatureDSPR2:
6913 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
6914 getTargetStreamer().emitDirectiveSetDspr2();
6915 break;
6916 case Mips::FeatureMicroMips:
6917 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6918 getTargetStreamer().emitDirectiveSetMicroMips();
6919 break;
6920 case Mips::FeatureMips1:
6921 selectArch("mips1");
6922 getTargetStreamer().emitDirectiveSetMips1();
6923 break;
6924 case Mips::FeatureMips2:
6925 selectArch("mips2");
6926 getTargetStreamer().emitDirectiveSetMips2();
6927 break;
6928 case Mips::FeatureMips3:
6929 selectArch("mips3");
6930 getTargetStreamer().emitDirectiveSetMips3();
6931 break;
6932 case Mips::FeatureMips4:
6933 selectArch("mips4");
6934 getTargetStreamer().emitDirectiveSetMips4();
6935 break;
6936 case Mips::FeatureMips5:
6937 selectArch("mips5");
6938 getTargetStreamer().emitDirectiveSetMips5();
6939 break;
6940 case Mips::FeatureMips32:
6941 selectArch("mips32");
6942 getTargetStreamer().emitDirectiveSetMips32();
6943 break;
6944 case Mips::FeatureMips32r2:
6945 selectArch("mips32r2");
6946 getTargetStreamer().emitDirectiveSetMips32R2();
6947 break;
6948 case Mips::FeatureMips32r3:
6949 selectArch("mips32r3");
6950 getTargetStreamer().emitDirectiveSetMips32R3();
6951 break;
6952 case Mips::FeatureMips32r5:
6953 selectArch("mips32r5");
6954 getTargetStreamer().emitDirectiveSetMips32R5();
6955 break;
6956 case Mips::FeatureMips32r6:
6957 selectArch("mips32r6");
6958 getTargetStreamer().emitDirectiveSetMips32R6();
6959 break;
6960 case Mips::FeatureMips64:
6961 selectArch("mips64");
6962 getTargetStreamer().emitDirectiveSetMips64();
6963 break;
6964 case Mips::FeatureMips64r2:
6965 selectArch("mips64r2");
6966 getTargetStreamer().emitDirectiveSetMips64R2();
6967 break;
6968 case Mips::FeatureMips64r3:
6969 selectArch("mips64r3");
6970 getTargetStreamer().emitDirectiveSetMips64R3();
6971 break;
6972 case Mips::FeatureMips64r5:
6973 selectArch("mips64r5");
6974 getTargetStreamer().emitDirectiveSetMips64R5();
6975 break;
6976 case Mips::FeatureMips64r6:
6977 selectArch("mips64r6");
6978 getTargetStreamer().emitDirectiveSetMips64R6();
6979 break;
6980 case Mips::FeatureCRC:
6981 setFeatureBits(Mips::FeatureCRC, "crc");
6982 getTargetStreamer().emitDirectiveSetCRC();
6983 break;
6984 case Mips::FeatureVirt:
6985 setFeatureBits(Mips::FeatureVirt, "virt");
6986 getTargetStreamer().emitDirectiveSetVirt();
6987 break;
6988 case Mips::FeatureGINV:
6989 setFeatureBits(Mips::FeatureGINV, "ginv");
6990 getTargetStreamer().emitDirectiveSetGINV();
6991 break;
6992 }
6993 return false;
6994 }
6995
eatComma(StringRef ErrorStr)6996 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6997 MCAsmParser &Parser = getParser();
6998 if (getLexer().isNot(AsmToken::Comma)) {
6999 SMLoc Loc = getLexer().getLoc();
7000 return Error(Loc, ErrorStr);
7001 }
7002
7003 Parser.Lex(); // Eat the comma.
7004 return true;
7005 }
7006
7007 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7008 // In this class, it is only used for .cprestore.
7009 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7010 // MipsTargetELFStreamer and MipsAsmParser.
isPicAndNotNxxAbi()7011 bool MipsAsmParser::isPicAndNotNxxAbi() {
7012 return inPicMode() && !(isABI_N32() || isABI_N64());
7013 }
7014
parseDirectiveCpLoad(SMLoc Loc)7015 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7016 if (AssemblerOptions.back()->isReorder())
7017 Warning(Loc, ".cpload should be inside a noreorder section");
7018
7019 if (inMips16Mode()) {
7020 reportParseError(".cpload is not supported in Mips16 mode");
7021 return false;
7022 }
7023
7024 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7025 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7026 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7027 reportParseError("expected register containing function address");
7028 return false;
7029 }
7030
7031 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7032 if (!RegOpnd.isGPRAsmReg()) {
7033 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7034 return false;
7035 }
7036
7037 // If this is not the end of the statement, report an error.
7038 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7039 reportParseError("unexpected token, expected end of statement");
7040 return false;
7041 }
7042
7043 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7044 return false;
7045 }
7046
parseDirectiveCpRestore(SMLoc Loc)7047 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7048 MCAsmParser &Parser = getParser();
7049
7050 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7051 // is used in non-PIC mode.
7052
7053 if (inMips16Mode()) {
7054 reportParseError(".cprestore is not supported in Mips16 mode");
7055 return false;
7056 }
7057
7058 // Get the stack offset value.
7059 const MCExpr *StackOffset;
7060 int64_t StackOffsetVal;
7061 if (Parser.parseExpression(StackOffset)) {
7062 reportParseError("expected stack offset value");
7063 return false;
7064 }
7065
7066 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7067 reportParseError("stack offset is not an absolute expression");
7068 return false;
7069 }
7070
7071 if (StackOffsetVal < 0) {
7072 Warning(Loc, ".cprestore with negative stack offset has no effect");
7073 IsCpRestoreSet = false;
7074 } else {
7075 IsCpRestoreSet = true;
7076 CpRestoreOffset = StackOffsetVal;
7077 }
7078
7079 // If this is not the end of the statement, report an error.
7080 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7081 reportParseError("unexpected token, expected end of statement");
7082 return false;
7083 }
7084
7085 if (!getTargetStreamer().emitDirectiveCpRestore(
7086 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7087 return true;
7088 Parser.Lex(); // Consume the EndOfStatement.
7089 return false;
7090 }
7091
parseDirectiveCPSetup()7092 bool MipsAsmParser::parseDirectiveCPSetup() {
7093 MCAsmParser &Parser = getParser();
7094 unsigned FuncReg;
7095 unsigned Save;
7096 bool SaveIsReg = true;
7097
7098 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7099 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7100 if (ResTy == MatchOperand_NoMatch) {
7101 reportParseError("expected register containing function address");
7102 return false;
7103 }
7104
7105 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7106 if (!FuncRegOpnd.isGPRAsmReg()) {
7107 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7108 return false;
7109 }
7110
7111 FuncReg = FuncRegOpnd.getGPR32Reg();
7112 TmpReg.clear();
7113
7114 if (!eatComma("unexpected token, expected comma"))
7115 return true;
7116
7117 ResTy = parseAnyRegister(TmpReg);
7118 if (ResTy == MatchOperand_NoMatch) {
7119 const MCExpr *OffsetExpr;
7120 int64_t OffsetVal;
7121 SMLoc ExprLoc = getLexer().getLoc();
7122
7123 if (Parser.parseExpression(OffsetExpr) ||
7124 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7125 reportParseError(ExprLoc, "expected save register or stack offset");
7126 return false;
7127 }
7128
7129 Save = OffsetVal;
7130 SaveIsReg = false;
7131 } else {
7132 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7133 if (!SaveOpnd.isGPRAsmReg()) {
7134 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7135 return false;
7136 }
7137 Save = SaveOpnd.getGPR32Reg();
7138 }
7139
7140 if (!eatComma("unexpected token, expected comma"))
7141 return true;
7142
7143 const MCExpr *Expr;
7144 if (Parser.parseExpression(Expr)) {
7145 reportParseError("expected expression");
7146 return false;
7147 }
7148
7149 if (Expr->getKind() != MCExpr::SymbolRef) {
7150 reportParseError("expected symbol");
7151 return false;
7152 }
7153 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7154
7155 CpSaveLocation = Save;
7156 CpSaveLocationIsRegister = SaveIsReg;
7157
7158 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7159 SaveIsReg);
7160 return false;
7161 }
7162
parseDirectiveCPReturn()7163 bool MipsAsmParser::parseDirectiveCPReturn() {
7164 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7165 CpSaveLocationIsRegister);
7166 return false;
7167 }
7168
parseDirectiveNaN()7169 bool MipsAsmParser::parseDirectiveNaN() {
7170 MCAsmParser &Parser = getParser();
7171 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7172 const AsmToken &Tok = Parser.getTok();
7173
7174 if (Tok.getString() == "2008") {
7175 Parser.Lex();
7176 getTargetStreamer().emitDirectiveNaN2008();
7177 return false;
7178 } else if (Tok.getString() == "legacy") {
7179 Parser.Lex();
7180 getTargetStreamer().emitDirectiveNaNLegacy();
7181 return false;
7182 }
7183 }
7184 // If we don't recognize the option passed to the .nan
7185 // directive (e.g. no option or unknown option), emit an error.
7186 reportParseError("invalid option in .nan directive");
7187 return false;
7188 }
7189
parseDirectiveSet()7190 bool MipsAsmParser::parseDirectiveSet() {
7191 const AsmToken &Tok = getParser().getTok();
7192 StringRef IdVal = Tok.getString();
7193 SMLoc Loc = Tok.getLoc();
7194
7195 if (IdVal == "noat")
7196 return parseSetNoAtDirective();
7197 if (IdVal == "at")
7198 return parseSetAtDirective();
7199 if (IdVal == "arch")
7200 return parseSetArchDirective();
7201 if (IdVal == "bopt") {
7202 Warning(Loc, "'bopt' feature is unsupported");
7203 getParser().Lex();
7204 return false;
7205 }
7206 if (IdVal == "nobopt") {
7207 // We're already running in nobopt mode, so nothing to do.
7208 getParser().Lex();
7209 return false;
7210 }
7211 if (IdVal == "fp")
7212 return parseSetFpDirective();
7213 if (IdVal == "oddspreg")
7214 return parseSetOddSPRegDirective();
7215 if (IdVal == "nooddspreg")
7216 return parseSetNoOddSPRegDirective();
7217 if (IdVal == "pop")
7218 return parseSetPopDirective();
7219 if (IdVal == "push")
7220 return parseSetPushDirective();
7221 if (IdVal == "reorder")
7222 return parseSetReorderDirective();
7223 if (IdVal == "noreorder")
7224 return parseSetNoReorderDirective();
7225 if (IdVal == "macro")
7226 return parseSetMacroDirective();
7227 if (IdVal == "nomacro")
7228 return parseSetNoMacroDirective();
7229 if (IdVal == "mips16")
7230 return parseSetMips16Directive();
7231 if (IdVal == "nomips16")
7232 return parseSetNoMips16Directive();
7233 if (IdVal == "nomicromips") {
7234 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7235 getTargetStreamer().emitDirectiveSetNoMicroMips();
7236 getParser().eatToEndOfStatement();
7237 return false;
7238 }
7239 if (IdVal == "micromips") {
7240 if (hasMips64r6()) {
7241 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7242 return false;
7243 }
7244 return parseSetFeature(Mips::FeatureMicroMips);
7245 }
7246 if (IdVal == "mips0")
7247 return parseSetMips0Directive();
7248 if (IdVal == "mips1")
7249 return parseSetFeature(Mips::FeatureMips1);
7250 if (IdVal == "mips2")
7251 return parseSetFeature(Mips::FeatureMips2);
7252 if (IdVal == "mips3")
7253 return parseSetFeature(Mips::FeatureMips3);
7254 if (IdVal == "mips4")
7255 return parseSetFeature(Mips::FeatureMips4);
7256 if (IdVal == "mips5")
7257 return parseSetFeature(Mips::FeatureMips5);
7258 if (IdVal == "mips32")
7259 return parseSetFeature(Mips::FeatureMips32);
7260 if (IdVal == "mips32r2")
7261 return parseSetFeature(Mips::FeatureMips32r2);
7262 if (IdVal == "mips32r3")
7263 return parseSetFeature(Mips::FeatureMips32r3);
7264 if (IdVal == "mips32r5")
7265 return parseSetFeature(Mips::FeatureMips32r5);
7266 if (IdVal == "mips32r6")
7267 return parseSetFeature(Mips::FeatureMips32r6);
7268 if (IdVal == "mips64")
7269 return parseSetFeature(Mips::FeatureMips64);
7270 if (IdVal == "mips64r2")
7271 return parseSetFeature(Mips::FeatureMips64r2);
7272 if (IdVal == "mips64r3")
7273 return parseSetFeature(Mips::FeatureMips64r3);
7274 if (IdVal == "mips64r5")
7275 return parseSetFeature(Mips::FeatureMips64r5);
7276 if (IdVal == "mips64r6") {
7277 if (inMicroMipsMode()) {
7278 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7279 return false;
7280 }
7281 return parseSetFeature(Mips::FeatureMips64r6);
7282 }
7283 if (IdVal == "dsp")
7284 return parseSetFeature(Mips::FeatureDSP);
7285 if (IdVal == "dspr2")
7286 return parseSetFeature(Mips::FeatureDSPR2);
7287 if (IdVal == "nodsp")
7288 return parseSetNoDspDirective();
7289 if (IdVal == "msa")
7290 return parseSetMsaDirective();
7291 if (IdVal == "nomsa")
7292 return parseSetNoMsaDirective();
7293 if (IdVal == "mt")
7294 return parseSetMtDirective();
7295 if (IdVal == "nomt")
7296 return parseSetNoMtDirective();
7297 if (IdVal == "softfloat")
7298 return parseSetSoftFloatDirective();
7299 if (IdVal == "hardfloat")
7300 return parseSetHardFloatDirective();
7301 if (IdVal == "crc")
7302 return parseSetFeature(Mips::FeatureCRC);
7303 if (IdVal == "nocrc")
7304 return parseSetNoCRCDirective();
7305 if (IdVal == "virt")
7306 return parseSetFeature(Mips::FeatureVirt);
7307 if (IdVal == "novirt")
7308 return parseSetNoVirtDirective();
7309 if (IdVal == "ginv")
7310 return parseSetFeature(Mips::FeatureGINV);
7311 if (IdVal == "noginv")
7312 return parseSetNoGINVDirective();
7313
7314 // It is just an identifier, look for an assignment.
7315 return parseSetAssignment();
7316 }
7317
7318 /// parseDirectiveGpWord
7319 /// ::= .gpword local_sym
parseDirectiveGpWord()7320 bool MipsAsmParser::parseDirectiveGpWord() {
7321 MCAsmParser &Parser = getParser();
7322 const MCExpr *Value;
7323 // EmitGPRel32Value requires an expression, so we are using base class
7324 // method to evaluate the expression.
7325 if (getParser().parseExpression(Value))
7326 return true;
7327 getParser().getStreamer().EmitGPRel32Value(Value);
7328
7329 if (getLexer().isNot(AsmToken::EndOfStatement))
7330 return Error(getLexer().getLoc(),
7331 "unexpected token, expected end of statement");
7332 Parser.Lex(); // Eat EndOfStatement token.
7333 return false;
7334 }
7335
7336 /// parseDirectiveGpDWord
7337 /// ::= .gpdword local_sym
parseDirectiveGpDWord()7338 bool MipsAsmParser::parseDirectiveGpDWord() {
7339 MCAsmParser &Parser = getParser();
7340 const MCExpr *Value;
7341 // EmitGPRel64Value requires an expression, so we are using base class
7342 // method to evaluate the expression.
7343 if (getParser().parseExpression(Value))
7344 return true;
7345 getParser().getStreamer().EmitGPRel64Value(Value);
7346
7347 if (getLexer().isNot(AsmToken::EndOfStatement))
7348 return Error(getLexer().getLoc(),
7349 "unexpected token, expected end of statement");
7350 Parser.Lex(); // Eat EndOfStatement token.
7351 return false;
7352 }
7353
7354 /// parseDirectiveDtpRelWord
7355 /// ::= .dtprelword tls_sym
parseDirectiveDtpRelWord()7356 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7357 MCAsmParser &Parser = getParser();
7358 const MCExpr *Value;
7359 // EmitDTPRel32Value requires an expression, so we are using base class
7360 // method to evaluate the expression.
7361 if (getParser().parseExpression(Value))
7362 return true;
7363 getParser().getStreamer().EmitDTPRel32Value(Value);
7364
7365 if (getLexer().isNot(AsmToken::EndOfStatement))
7366 return Error(getLexer().getLoc(),
7367 "unexpected token, expected end of statement");
7368 Parser.Lex(); // Eat EndOfStatement token.
7369 return false;
7370 }
7371
7372 /// parseDirectiveDtpRelDWord
7373 /// ::= .dtpreldword tls_sym
parseDirectiveDtpRelDWord()7374 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7375 MCAsmParser &Parser = getParser();
7376 const MCExpr *Value;
7377 // EmitDTPRel64Value requires an expression, so we are using base class
7378 // method to evaluate the expression.
7379 if (getParser().parseExpression(Value))
7380 return true;
7381 getParser().getStreamer().EmitDTPRel64Value(Value);
7382
7383 if (getLexer().isNot(AsmToken::EndOfStatement))
7384 return Error(getLexer().getLoc(),
7385 "unexpected token, expected end of statement");
7386 Parser.Lex(); // Eat EndOfStatement token.
7387 return false;
7388 }
7389
7390 /// parseDirectiveTpRelWord
7391 /// ::= .tprelword tls_sym
parseDirectiveTpRelWord()7392 bool MipsAsmParser::parseDirectiveTpRelWord() {
7393 MCAsmParser &Parser = getParser();
7394 const MCExpr *Value;
7395 // EmitTPRel32Value requires an expression, so we are using base class
7396 // method to evaluate the expression.
7397 if (getParser().parseExpression(Value))
7398 return true;
7399 getParser().getStreamer().EmitTPRel32Value(Value);
7400
7401 if (getLexer().isNot(AsmToken::EndOfStatement))
7402 return Error(getLexer().getLoc(),
7403 "unexpected token, expected end of statement");
7404 Parser.Lex(); // Eat EndOfStatement token.
7405 return false;
7406 }
7407
7408 /// parseDirectiveTpRelDWord
7409 /// ::= .tpreldword tls_sym
parseDirectiveTpRelDWord()7410 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7411 MCAsmParser &Parser = getParser();
7412 const MCExpr *Value;
7413 // EmitTPRel64Value requires an expression, so we are using base class
7414 // method to evaluate the expression.
7415 if (getParser().parseExpression(Value))
7416 return true;
7417 getParser().getStreamer().EmitTPRel64Value(Value);
7418
7419 if (getLexer().isNot(AsmToken::EndOfStatement))
7420 return Error(getLexer().getLoc(),
7421 "unexpected token, expected end of statement");
7422 Parser.Lex(); // Eat EndOfStatement token.
7423 return false;
7424 }
7425
parseDirectiveOption()7426 bool MipsAsmParser::parseDirectiveOption() {
7427 MCAsmParser &Parser = getParser();
7428 // Get the option token.
7429 AsmToken Tok = Parser.getTok();
7430 // At the moment only identifiers are supported.
7431 if (Tok.isNot(AsmToken::Identifier)) {
7432 return Error(Parser.getTok().getLoc(),
7433 "unexpected token, expected identifier");
7434 }
7435
7436 StringRef Option = Tok.getIdentifier();
7437
7438 if (Option == "pic0") {
7439 // MipsAsmParser needs to know if the current PIC mode changes.
7440 IsPicEnabled = false;
7441
7442 getTargetStreamer().emitDirectiveOptionPic0();
7443 Parser.Lex();
7444 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7445 return Error(Parser.getTok().getLoc(),
7446 "unexpected token, expected end of statement");
7447 }
7448 return false;
7449 }
7450
7451 if (Option == "pic2") {
7452 // MipsAsmParser needs to know if the current PIC mode changes.
7453 IsPicEnabled = true;
7454
7455 getTargetStreamer().emitDirectiveOptionPic2();
7456 Parser.Lex();
7457 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7458 return Error(Parser.getTok().getLoc(),
7459 "unexpected token, expected end of statement");
7460 }
7461 return false;
7462 }
7463
7464 // Unknown option.
7465 Warning(Parser.getTok().getLoc(),
7466 "unknown option, expected 'pic0' or 'pic2'");
7467 Parser.eatToEndOfStatement();
7468 return false;
7469 }
7470
7471 /// parseInsnDirective
7472 /// ::= .insn
parseInsnDirective()7473 bool MipsAsmParser::parseInsnDirective() {
7474 // If this is not the end of the statement, report an error.
7475 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7476 reportParseError("unexpected token, expected end of statement");
7477 return false;
7478 }
7479
7480 // The actual label marking happens in
7481 // MipsELFStreamer::createPendingLabelRelocs().
7482 getTargetStreamer().emitDirectiveInsn();
7483
7484 getParser().Lex(); // Eat EndOfStatement token.
7485 return false;
7486 }
7487
7488 /// parseRSectionDirective
7489 /// ::= .rdata
parseRSectionDirective(StringRef Section)7490 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7491 // If this is not the end of the statement, report an error.
7492 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7493 reportParseError("unexpected token, expected end of statement");
7494 return false;
7495 }
7496
7497 MCSection *ELFSection = getContext().getELFSection(
7498 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7499 getParser().getStreamer().SwitchSection(ELFSection);
7500
7501 getParser().Lex(); // Eat EndOfStatement token.
7502 return false;
7503 }
7504
7505 /// parseSSectionDirective
7506 /// ::= .sbss
7507 /// ::= .sdata
parseSSectionDirective(StringRef Section,unsigned Type)7508 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7509 // If this is not the end of the statement, report an error.
7510 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7511 reportParseError("unexpected token, expected end of statement");
7512 return false;
7513 }
7514
7515 MCSection *ELFSection = getContext().getELFSection(
7516 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7517 getParser().getStreamer().SwitchSection(ELFSection);
7518
7519 getParser().Lex(); // Eat EndOfStatement token.
7520 return false;
7521 }
7522
7523 /// parseDirectiveModule
7524 /// ::= .module oddspreg
7525 /// ::= .module nooddspreg
7526 /// ::= .module fp=value
7527 /// ::= .module softfloat
7528 /// ::= .module hardfloat
7529 /// ::= .module mt
7530 /// ::= .module crc
7531 /// ::= .module nocrc
7532 /// ::= .module virt
7533 /// ::= .module novirt
7534 /// ::= .module ginv
7535 /// ::= .module noginv
parseDirectiveModule()7536 bool MipsAsmParser::parseDirectiveModule() {
7537 MCAsmParser &Parser = getParser();
7538 MCAsmLexer &Lexer = getLexer();
7539 SMLoc L = Lexer.getLoc();
7540
7541 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7542 // TODO : get a better message.
7543 reportParseError(".module directive must appear before any code");
7544 return false;
7545 }
7546
7547 StringRef Option;
7548 if (Parser.parseIdentifier(Option)) {
7549 reportParseError("expected .module option identifier");
7550 return false;
7551 }
7552
7553 if (Option == "oddspreg") {
7554 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7555
7556 // Synchronize the abiflags information with the FeatureBits information we
7557 // changed above.
7558 getTargetStreamer().updateABIInfo(*this);
7559
7560 // If printing assembly, use the recently updated abiflags information.
7561 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7562 // emitted at the end).
7563 getTargetStreamer().emitDirectiveModuleOddSPReg();
7564
7565 // If this is not the end of the statement, report an error.
7566 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7567 reportParseError("unexpected token, expected end of statement");
7568 return false;
7569 }
7570
7571 return false; // parseDirectiveModule has finished successfully.
7572 } else if (Option == "nooddspreg") {
7573 if (!isABI_O32()) {
7574 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7575 }
7576
7577 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7578
7579 // Synchronize the abiflags information with the FeatureBits information we
7580 // changed above.
7581 getTargetStreamer().updateABIInfo(*this);
7582
7583 // If printing assembly, use the recently updated abiflags information.
7584 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7585 // emitted at the end).
7586 getTargetStreamer().emitDirectiveModuleOddSPReg();
7587
7588 // If this is not the end of the statement, report an error.
7589 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7590 reportParseError("unexpected token, expected end of statement");
7591 return false;
7592 }
7593
7594 return false; // parseDirectiveModule has finished successfully.
7595 } else if (Option == "fp") {
7596 return parseDirectiveModuleFP();
7597 } else if (Option == "softfloat") {
7598 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7599
7600 // Synchronize the ABI Flags information with the FeatureBits information we
7601 // updated above.
7602 getTargetStreamer().updateABIInfo(*this);
7603
7604 // If printing assembly, use the recently updated ABI Flags information.
7605 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7606 // emitted later).
7607 getTargetStreamer().emitDirectiveModuleSoftFloat();
7608
7609 // If this is not the end of the statement, report an error.
7610 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7611 reportParseError("unexpected token, expected end of statement");
7612 return false;
7613 }
7614
7615 return false; // parseDirectiveModule has finished successfully.
7616 } else if (Option == "hardfloat") {
7617 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7618
7619 // Synchronize the ABI Flags information with the FeatureBits information we
7620 // updated above.
7621 getTargetStreamer().updateABIInfo(*this);
7622
7623 // If printing assembly, use the recently updated ABI Flags information.
7624 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7625 // emitted later).
7626 getTargetStreamer().emitDirectiveModuleHardFloat();
7627
7628 // If this is not the end of the statement, report an error.
7629 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7630 reportParseError("unexpected token, expected end of statement");
7631 return false;
7632 }
7633
7634 return false; // parseDirectiveModule has finished successfully.
7635 } else if (Option == "mt") {
7636 setModuleFeatureBits(Mips::FeatureMT, "mt");
7637
7638 // Synchronize the ABI Flags information with the FeatureBits information we
7639 // updated above.
7640 getTargetStreamer().updateABIInfo(*this);
7641
7642 // If printing assembly, use the recently updated ABI Flags information.
7643 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7644 // emitted later).
7645 getTargetStreamer().emitDirectiveModuleMT();
7646
7647 // If this is not the end of the statement, report an error.
7648 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7649 reportParseError("unexpected token, expected end of statement");
7650 return false;
7651 }
7652
7653 return false; // parseDirectiveModule has finished successfully.
7654 } else if (Option == "crc") {
7655 setModuleFeatureBits(Mips::FeatureCRC, "crc");
7656
7657 // Synchronize the ABI Flags information with the FeatureBits information we
7658 // updated above.
7659 getTargetStreamer().updateABIInfo(*this);
7660
7661 // If printing assembly, use the recently updated ABI Flags information.
7662 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7663 // emitted later).
7664 getTargetStreamer().emitDirectiveModuleCRC();
7665
7666 // If this is not the end of the statement, report an error.
7667 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7668 reportParseError("unexpected token, expected end of statement");
7669 return false;
7670 }
7671
7672 return false; // parseDirectiveModule has finished successfully.
7673 } else if (Option == "nocrc") {
7674 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
7675
7676 // Synchronize the ABI Flags information with the FeatureBits information we
7677 // updated above.
7678 getTargetStreamer().updateABIInfo(*this);
7679
7680 // If printing assembly, use the recently updated ABI Flags information.
7681 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7682 // emitted later).
7683 getTargetStreamer().emitDirectiveModuleNoCRC();
7684
7685 // If this is not the end of the statement, report an error.
7686 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7687 reportParseError("unexpected token, expected end of statement");
7688 return false;
7689 }
7690
7691 return false; // parseDirectiveModule has finished successfully.
7692 } else if (Option == "virt") {
7693 setModuleFeatureBits(Mips::FeatureVirt, "virt");
7694
7695 // Synchronize the ABI Flags information with the FeatureBits information we
7696 // updated above.
7697 getTargetStreamer().updateABIInfo(*this);
7698
7699 // If printing assembly, use the recently updated ABI Flags information.
7700 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7701 // emitted later).
7702 getTargetStreamer().emitDirectiveModuleVirt();
7703
7704 // If this is not the end of the statement, report an error.
7705 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7706 reportParseError("unexpected token, expected end of statement");
7707 return false;
7708 }
7709
7710 return false; // parseDirectiveModule has finished successfully.
7711 } else if (Option == "novirt") {
7712 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
7713
7714 // Synchronize the ABI Flags information with the FeatureBits information we
7715 // updated above.
7716 getTargetStreamer().updateABIInfo(*this);
7717
7718 // If printing assembly, use the recently updated ABI Flags information.
7719 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7720 // emitted later).
7721 getTargetStreamer().emitDirectiveModuleNoVirt();
7722
7723 // If this is not the end of the statement, report an error.
7724 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7725 reportParseError("unexpected token, expected end of statement");
7726 return false;
7727 }
7728
7729 return false; // parseDirectiveModule has finished successfully.
7730 } else if (Option == "ginv") {
7731 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
7732
7733 // Synchronize the ABI Flags information with the FeatureBits information we
7734 // updated above.
7735 getTargetStreamer().updateABIInfo(*this);
7736
7737 // If printing assembly, use the recently updated ABI Flags information.
7738 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7739 // emitted later).
7740 getTargetStreamer().emitDirectiveModuleGINV();
7741
7742 // If this is not the end of the statement, report an error.
7743 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7744 reportParseError("unexpected token, expected end of statement");
7745 return false;
7746 }
7747
7748 return false; // parseDirectiveModule has finished successfully.
7749 } else if (Option == "noginv") {
7750 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
7751
7752 // Synchronize the ABI Flags information with the FeatureBits information we
7753 // updated above.
7754 getTargetStreamer().updateABIInfo(*this);
7755
7756 // If printing assembly, use the recently updated ABI Flags information.
7757 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7758 // emitted later).
7759 getTargetStreamer().emitDirectiveModuleNoGINV();
7760
7761 // If this is not the end of the statement, report an error.
7762 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7763 reportParseError("unexpected token, expected end of statement");
7764 return false;
7765 }
7766
7767 return false; // parseDirectiveModule has finished successfully.
7768 } else {
7769 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7770 }
7771 }
7772
7773 /// parseDirectiveModuleFP
7774 /// ::= =32
7775 /// ::= =xx
7776 /// ::= =64
parseDirectiveModuleFP()7777 bool MipsAsmParser::parseDirectiveModuleFP() {
7778 MCAsmParser &Parser = getParser();
7779 MCAsmLexer &Lexer = getLexer();
7780
7781 if (Lexer.isNot(AsmToken::Equal)) {
7782 reportParseError("unexpected token, expected equals sign '='");
7783 return false;
7784 }
7785 Parser.Lex(); // Eat '=' token.
7786
7787 MipsABIFlagsSection::FpABIKind FpABI;
7788 if (!parseFpABIValue(FpABI, ".module"))
7789 return false;
7790
7791 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7792 reportParseError("unexpected token, expected end of statement");
7793 return false;
7794 }
7795
7796 // Synchronize the abiflags information with the FeatureBits information we
7797 // changed above.
7798 getTargetStreamer().updateABIInfo(*this);
7799
7800 // If printing assembly, use the recently updated abiflags information.
7801 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7802 // emitted at the end).
7803 getTargetStreamer().emitDirectiveModuleFP();
7804
7805 Parser.Lex(); // Consume the EndOfStatement.
7806 return false;
7807 }
7808
parseFpABIValue(MipsABIFlagsSection::FpABIKind & FpABI,StringRef Directive)7809 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7810 StringRef Directive) {
7811 MCAsmParser &Parser = getParser();
7812 MCAsmLexer &Lexer = getLexer();
7813 bool ModuleLevelOptions = Directive == ".module";
7814
7815 if (Lexer.is(AsmToken::Identifier)) {
7816 StringRef Value = Parser.getTok().getString();
7817 Parser.Lex();
7818
7819 if (Value != "xx") {
7820 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7821 return false;
7822 }
7823
7824 if (!isABI_O32()) {
7825 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7826 return false;
7827 }
7828
7829 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7830 if (ModuleLevelOptions) {
7831 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7832 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7833 } else {
7834 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7835 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7836 }
7837 return true;
7838 }
7839
7840 if (Lexer.is(AsmToken::Integer)) {
7841 unsigned Value = Parser.getTok().getIntVal();
7842 Parser.Lex();
7843
7844 if (Value != 32 && Value != 64) {
7845 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7846 return false;
7847 }
7848
7849 if (Value == 32) {
7850 if (!isABI_O32()) {
7851 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7852 return false;
7853 }
7854
7855 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7856 if (ModuleLevelOptions) {
7857 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7858 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7859 } else {
7860 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7861 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7862 }
7863 } else {
7864 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7865 if (ModuleLevelOptions) {
7866 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7867 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7868 } else {
7869 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7870 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7871 }
7872 }
7873
7874 return true;
7875 }
7876
7877 return false;
7878 }
7879
ParseDirective(AsmToken DirectiveID)7880 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7881 // This returns false if this function recognizes the directive
7882 // regardless of whether it is successfully handles or reports an
7883 // error. Otherwise it returns true to give the generic parser a
7884 // chance at recognizing it.
7885
7886 MCAsmParser &Parser = getParser();
7887 StringRef IDVal = DirectiveID.getString();
7888
7889 if (IDVal == ".cpload") {
7890 parseDirectiveCpLoad(DirectiveID.getLoc());
7891 return false;
7892 }
7893 if (IDVal == ".cprestore") {
7894 parseDirectiveCpRestore(DirectiveID.getLoc());
7895 return false;
7896 }
7897 if (IDVal == ".ent") {
7898 StringRef SymbolName;
7899
7900 if (Parser.parseIdentifier(SymbolName)) {
7901 reportParseError("expected identifier after .ent");
7902 return false;
7903 }
7904
7905 // There's an undocumented extension that allows an integer to
7906 // follow the name of the procedure which AFAICS is ignored by GAS.
7907 // Example: .ent foo,2
7908 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7909 if (getLexer().isNot(AsmToken::Comma)) {
7910 // Even though we accept this undocumented extension for compatibility
7911 // reasons, the additional integer argument does not actually change
7912 // the behaviour of the '.ent' directive, so we would like to discourage
7913 // its use. We do this by not referring to the extended version in
7914 // error messages which are not directly related to its use.
7915 reportParseError("unexpected token, expected end of statement");
7916 return false;
7917 }
7918 Parser.Lex(); // Eat the comma.
7919 const MCExpr *DummyNumber;
7920 int64_t DummyNumberVal;
7921 // If the user was explicitly trying to use the extended version,
7922 // we still give helpful extension-related error messages.
7923 if (Parser.parseExpression(DummyNumber)) {
7924 reportParseError("expected number after comma");
7925 return false;
7926 }
7927 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7928 reportParseError("expected an absolute expression after comma");
7929 return false;
7930 }
7931 }
7932
7933 // If this is not the end of the statement, report an error.
7934 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7935 reportParseError("unexpected token, expected end of statement");
7936 return false;
7937 }
7938
7939 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7940
7941 getTargetStreamer().emitDirectiveEnt(*Sym);
7942 CurrentFn = Sym;
7943 IsCpRestoreSet = false;
7944 return false;
7945 }
7946
7947 if (IDVal == ".end") {
7948 StringRef SymbolName;
7949
7950 if (Parser.parseIdentifier(SymbolName)) {
7951 reportParseError("expected identifier after .end");
7952 return false;
7953 }
7954
7955 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7956 reportParseError("unexpected token, expected end of statement");
7957 return false;
7958 }
7959
7960 if (CurrentFn == nullptr) {
7961 reportParseError(".end used without .ent");
7962 return false;
7963 }
7964
7965 if ((SymbolName != CurrentFn->getName())) {
7966 reportParseError(".end symbol does not match .ent symbol");
7967 return false;
7968 }
7969
7970 getTargetStreamer().emitDirectiveEnd(SymbolName);
7971 CurrentFn = nullptr;
7972 IsCpRestoreSet = false;
7973 return false;
7974 }
7975
7976 if (IDVal == ".frame") {
7977 // .frame $stack_reg, frame_size_in_bytes, $return_reg
7978 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7979 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7980 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7981 reportParseError("expected stack register");
7982 return false;
7983 }
7984
7985 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7986 if (!StackRegOpnd.isGPRAsmReg()) {
7987 reportParseError(StackRegOpnd.getStartLoc(),
7988 "expected general purpose register");
7989 return false;
7990 }
7991 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7992
7993 if (Parser.getTok().is(AsmToken::Comma))
7994 Parser.Lex();
7995 else {
7996 reportParseError("unexpected token, expected comma");
7997 return false;
7998 }
7999
8000 // Parse the frame size.
8001 const MCExpr *FrameSize;
8002 int64_t FrameSizeVal;
8003
8004 if (Parser.parseExpression(FrameSize)) {
8005 reportParseError("expected frame size value");
8006 return false;
8007 }
8008
8009 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8010 reportParseError("frame size not an absolute expression");
8011 return false;
8012 }
8013
8014 if (Parser.getTok().is(AsmToken::Comma))
8015 Parser.Lex();
8016 else {
8017 reportParseError("unexpected token, expected comma");
8018 return false;
8019 }
8020
8021 // Parse the return register.
8022 TmpReg.clear();
8023 ResTy = parseAnyRegister(TmpReg);
8024 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8025 reportParseError("expected return register");
8026 return false;
8027 }
8028
8029 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8030 if (!ReturnRegOpnd.isGPRAsmReg()) {
8031 reportParseError(ReturnRegOpnd.getStartLoc(),
8032 "expected general purpose register");
8033 return false;
8034 }
8035
8036 // If this is not the end of the statement, report an error.
8037 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8038 reportParseError("unexpected token, expected end of statement");
8039 return false;
8040 }
8041
8042 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8043 ReturnRegOpnd.getGPR32Reg());
8044 IsCpRestoreSet = false;
8045 return false;
8046 }
8047
8048 if (IDVal == ".set") {
8049 parseDirectiveSet();
8050 return false;
8051 }
8052
8053 if (IDVal == ".mask" || IDVal == ".fmask") {
8054 // .mask bitmask, frame_offset
8055 // bitmask: One bit for each register used.
8056 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8057 // first register is expected to be saved.
8058 // Examples:
8059 // .mask 0x80000000, -4
8060 // .fmask 0x80000000, -4
8061 //
8062
8063 // Parse the bitmask
8064 const MCExpr *BitMask;
8065 int64_t BitMaskVal;
8066
8067 if (Parser.parseExpression(BitMask)) {
8068 reportParseError("expected bitmask value");
8069 return false;
8070 }
8071
8072 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8073 reportParseError("bitmask not an absolute expression");
8074 return false;
8075 }
8076
8077 if (Parser.getTok().is(AsmToken::Comma))
8078 Parser.Lex();
8079 else {
8080 reportParseError("unexpected token, expected comma");
8081 return false;
8082 }
8083
8084 // Parse the frame_offset
8085 const MCExpr *FrameOffset;
8086 int64_t FrameOffsetVal;
8087
8088 if (Parser.parseExpression(FrameOffset)) {
8089 reportParseError("expected frame offset value");
8090 return false;
8091 }
8092
8093 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8094 reportParseError("frame offset not an absolute expression");
8095 return false;
8096 }
8097
8098 // If this is not the end of the statement, report an error.
8099 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8100 reportParseError("unexpected token, expected end of statement");
8101 return false;
8102 }
8103
8104 if (IDVal == ".mask")
8105 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8106 else
8107 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8108 return false;
8109 }
8110
8111 if (IDVal == ".nan")
8112 return parseDirectiveNaN();
8113
8114 if (IDVal == ".gpword") {
8115 parseDirectiveGpWord();
8116 return false;
8117 }
8118
8119 if (IDVal == ".gpdword") {
8120 parseDirectiveGpDWord();
8121 return false;
8122 }
8123
8124 if (IDVal == ".dtprelword") {
8125 parseDirectiveDtpRelWord();
8126 return false;
8127 }
8128
8129 if (IDVal == ".dtpreldword") {
8130 parseDirectiveDtpRelDWord();
8131 return false;
8132 }
8133
8134 if (IDVal == ".tprelword") {
8135 parseDirectiveTpRelWord();
8136 return false;
8137 }
8138
8139 if (IDVal == ".tpreldword") {
8140 parseDirectiveTpRelDWord();
8141 return false;
8142 }
8143
8144 if (IDVal == ".option") {
8145 parseDirectiveOption();
8146 return false;
8147 }
8148
8149 if (IDVal == ".abicalls") {
8150 getTargetStreamer().emitDirectiveAbiCalls();
8151 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8152 Error(Parser.getTok().getLoc(),
8153 "unexpected token, expected end of statement");
8154 }
8155 return false;
8156 }
8157
8158 if (IDVal == ".cpsetup") {
8159 parseDirectiveCPSetup();
8160 return false;
8161 }
8162 if (IDVal == ".cpreturn") {
8163 parseDirectiveCPReturn();
8164 return false;
8165 }
8166 if (IDVal == ".module") {
8167 parseDirectiveModule();
8168 return false;
8169 }
8170 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8171 parseInternalDirectiveReallowModule();
8172 return false;
8173 }
8174 if (IDVal == ".insn") {
8175 parseInsnDirective();
8176 return false;
8177 }
8178 if (IDVal == ".rdata") {
8179 parseRSectionDirective(".rodata");
8180 return false;
8181 }
8182 if (IDVal == ".sbss") {
8183 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8184 return false;
8185 }
8186 if (IDVal == ".sdata") {
8187 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8188 return false;
8189 }
8190
8191 return true;
8192 }
8193
parseInternalDirectiveReallowModule()8194 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8195 // If this is not the end of the statement, report an error.
8196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8197 reportParseError("unexpected token, expected end of statement");
8198 return false;
8199 }
8200
8201 getTargetStreamer().reallowModuleDirective();
8202
8203 getParser().Lex(); // Eat EndOfStatement token.
8204 return false;
8205 }
8206
LLVMInitializeMipsAsmParser()8207 extern "C" void LLVMInitializeMipsAsmParser() {
8208 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8209 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8210 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8211 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8212 }
8213
8214 #define GET_REGISTER_MATCHER
8215 #define GET_MATCHER_IMPLEMENTATION
8216 #define GET_MNEMONIC_SPELL_CHECKER
8217 #include "MipsGenAsmMatcher.inc"
8218
mnemonicIsValid(StringRef Mnemonic,unsigned VariantID)8219 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8220 // Find the appropriate table for this asm variant.
8221 const MatchEntry *Start, *End;
8222 switch (VariantID) {
8223 default: llvm_unreachable("invalid variant!");
8224 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8225 }
8226 // Search the table.
8227 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8228 return MnemonicRange.first != MnemonicRange.second;
8229 }
8230