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