Bug Summary

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

Annotated Source Code

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