Bug Summary

File:lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 2583, column 18
The result of the right shift is undefined due to shifting by '4294967295', which is greater or equal to the width of type 'uint64_t'

Annotated Source Code

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