Bug Summary

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