Bug Summary

File:lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 6130, column 11
Value stored to 'PrevReg' is never read

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