Bug Summary

File:lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 2508, column 18
The result of the '>>' expression is undefined

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