Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name MipsAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-config-compatibility-mode=true -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips -I /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/lib/Target/Mips -I /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn349319/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/lib/Target/Mips/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-8~svn349319=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-12-17-043027-19008-1 -x c++ /build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

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/CommandLine.h"
43#include "llvm/Support/Compiler.h"
44#include "llvm/Support/Debug.h"
45#include "llvm/Support/ErrorHandling.h"
46#include "llvm/Support/MathExtras.h"
47#include "llvm/Support/SMLoc.h"
48#include "llvm/Support/SourceMgr.h"
49#include "llvm/Support/TargetRegistry.h"
50#include "llvm/Support/raw_ostream.h"
51#include <algorithm>
52#include <cassert>
53#include <cstdint>
54#include <memory>
55#include <string>
56#include <utility>
57
58using namespace llvm;
59
60#define DEBUG_TYPE"mips-asm-parser" "mips-asm-parser"
61
62namespace llvm {
63
64class MCInstrInfo;
65
66} // end namespace llvm
67
68static cl::opt<bool>
69EmitJalrReloc("mips-jalr-reloc", cl::Hidden,
70 cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"),
71 cl::init(true));
72
73namespace {
74
75class MipsAssemblerOptions {
76public:
77 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
78
79 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
80 ATReg = Opts->getATRegIndex();
81 Reorder = Opts->isReorder();
82 Macro = Opts->isMacro();
83 Features = Opts->getFeatures();
84 }
85
86 unsigned getATRegIndex() const { return ATReg; }
87 bool setATRegIndex(unsigned Reg) {
88 if (Reg > 31)
89 return false;
90
91 ATReg = Reg;
92 return true;
93 }
94
95 bool isReorder() const { return Reorder; }
96 void setReorder() { Reorder = true; }
97 void setNoReorder() { Reorder = false; }
98
99 bool isMacro() const { return Macro; }
100 void setMacro() { Macro = true; }
101 void setNoMacro() { Macro = false; }
102
103 const FeatureBitset &getFeatures() const { return Features; }
104 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
105
106 // Set of features that are either architecture features or referenced
107 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
108 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
109 // The reason we need this mask is explained in the selectArch function.
110 // FIXME: Ideally we would like TableGen to generate this information.
111 static const FeatureBitset AllArchRelatedMask;
112
113private:
114 unsigned ATReg = 1;
115 bool Reorder = true;
116 bool Macro = true;
117 FeatureBitset Features;
118};
119
120} // end anonymous namespace
121
122const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
131};
132
133namespace {
134
135class MipsAsmParser : public MCTargetAsmParser {
136 MipsTargetStreamer &getTargetStreamer() {
137 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
138 return static_cast<MipsTargetStreamer &>(TS);
139 }
140
141 MipsABIInfo ABI;
142 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
143 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
144 // nullptr, which indicates that no function is currently
145 // selected. This usually happens after an '.end func'
146 // directive.
147 bool IsLittleEndian;
148 bool IsPicEnabled;
149 bool IsCpRestoreSet;
150 int CpRestoreOffset;
151 unsigned CpSaveLocation;
152 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
153 bool CpSaveLocationIsRegister;
154
155 // Map of register aliases created via the .set directive.
156 StringMap<AsmToken> RegisterSets;
157
158 // Print a warning along with its fix-it message at the given range.
159 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
160 SMRange Range, bool ShowColors = true);
161
162 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
163
164#define GET_ASSEMBLER_HEADER
165#include "MipsGenAsmMatcher.inc"
166
167 unsigned
168 checkEarlyTargetMatchPredicate(MCInst &Inst,
169 const OperandVector &Operands) override;
170 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
171
172 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
173 OperandVector &Operands, MCStreamer &Out,
174 uint64_t &ErrorInfo,
175 bool MatchingInlineAsm) override;
176
177 /// Parse a register as used in CFI directives
178 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
179
180 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
181
182 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
183
184 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
185
186 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
187 SMLoc NameLoc, OperandVector &Operands) override;
188
189 bool ParseDirective(AsmToken DirectiveID) override;
190
191 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
192 OperandMatchResultTy
193 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
194 StringRef Identifier, SMLoc S);
195 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
196 const AsmToken &Token,
197 SMLoc S);
198 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
199 SMLoc S);
200 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
201 OperandMatchResultTy parseImm(OperandVector &Operands);
202 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
203 OperandMatchResultTy parseInvNum(OperandVector &Operands);
204 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
205
206 bool searchSymbolAlias(OperandVector &Operands);
207
208 bool parseOperand(OperandVector &, StringRef Mnemonic);
209
210 enum MacroExpanderResultTy {
211 MER_NotAMacro,
212 MER_Success,
213 MER_Fail,
214 };
215
216 // Expands assembly pseudo instructions.
217 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
218 MCStreamer &Out,
219 const MCSubtargetInfo *STI);
220
221 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
222 const MCSubtargetInfo *STI);
223
224 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
225 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
226 MCStreamer &Out, const MCSubtargetInfo *STI);
227
228 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
229 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
230 MCStreamer &Out, const MCSubtargetInfo *STI);
231
232 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
233
234 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
235 MCStreamer &Out, const MCSubtargetInfo *STI);
236
237 bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
238 SMLoc IDLoc, MCStreamer &Out,
239 const MCSubtargetInfo *STI);
240
241 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
242 const MCOperand &Offset, bool Is32BitAddress,
243 SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245
246 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI);
248
249 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
250 const MCSubtargetInfo *STI, bool IsLoad);
251
252 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
254
255 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
257
258 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI);
260
261 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI);
263
264 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
265 const MCSubtargetInfo *STI, const bool IsMips64,
266 const bool Signed);
267
268 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
269 MCStreamer &Out, const MCSubtargetInfo *STI);
270
271 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
273
274 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI);
276
277 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
278 const MCSubtargetInfo *STI);
279
280 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
281 MCStreamer &Out, const MCSubtargetInfo *STI);
282 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
284 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
285 const MCSubtargetInfo *STI);
286 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
287 const MCSubtargetInfo *STI);
288
289 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
290 const MCSubtargetInfo *STI);
291
292 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
294
295 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
297
298 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
300
301 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI);
303
304 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI, bool IsLoad);
306
307 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308 const MCSubtargetInfo *STI);
309
310 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
312
313 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
314 const MCSubtargetInfo *STI);
315
316 bool reportParseError(Twine ErrorMsg);
317 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
318
319 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
320
321 bool isEvaluated(const MCExpr *Expr);
322 bool parseSetMips0Directive();
323 bool parseSetArchDirective();
324 bool parseSetFeature(uint64_t Feature);
325 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
326 bool parseDirectiveCpLoad(SMLoc Loc);
327 bool parseDirectiveCpRestore(SMLoc Loc);
328 bool parseDirectiveCPSetup();
329 bool parseDirectiveCPReturn();
330 bool parseDirectiveNaN();
331 bool parseDirectiveSet();
332 bool parseDirectiveOption();
333 bool parseInsnDirective();
334 bool parseRSectionDirective(StringRef Section);
335 bool parseSSectionDirective(StringRef Section, unsigned Type);
336
337 bool parseSetAtDirective();
338 bool parseSetNoAtDirective();
339 bool parseSetMacroDirective();
340 bool parseSetNoMacroDirective();
341 bool parseSetMsaDirective();
342 bool parseSetNoMsaDirective();
343 bool parseSetNoDspDirective();
344 bool parseSetReorderDirective();
345 bool parseSetNoReorderDirective();
346 bool parseSetMips16Directive();
347 bool parseSetNoMips16Directive();
348 bool parseSetFpDirective();
349 bool parseSetOddSPRegDirective();
350 bool parseSetNoOddSPRegDirective();
351 bool parseSetPopDirective();
352 bool parseSetPushDirective();
353 bool parseSetSoftFloatDirective();
354 bool parseSetHardFloatDirective();
355 bool parseSetMtDirective();
356 bool parseSetNoMtDirective();
357 bool parseSetNoCRCDirective();
358 bool parseSetNoVirtDirective();
359 bool parseSetNoGINVDirective();
360
361 bool parseSetAssignment();
362
363 bool parseDirectiveGpWord();
364 bool parseDirectiveGpDWord();
365 bool parseDirectiveDtpRelWord();
366 bool parseDirectiveDtpRelDWord();
367 bool parseDirectiveTpRelWord();
368 bool parseDirectiveTpRelDWord();
369 bool parseDirectiveModule();
370 bool parseDirectiveModuleFP();
371 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
372 StringRef Directive);
373
374 bool parseInternalDirectiveReallowModule();
375
376 bool eatComma(StringRef ErrorStr);
377
378 int matchCPURegisterName(StringRef Symbol);
379
380 int matchHWRegsRegisterName(StringRef Symbol);
381
382 int matchFPURegisterName(StringRef Name);
383
384 int matchFCCRegisterName(StringRef Name);
385
386 int matchACRegisterName(StringRef Name);
387
388 int matchMSA128RegisterName(StringRef Name);
389
390 int matchMSA128CtrlRegisterName(StringRef Name);
391
392 unsigned getReg(int RC, int RegNo);
393
394 /// Returns the internal register number for the current AT. Also checks if
395 /// the current AT is unavailable (set to $0) and gives an error if it is.
396 /// This should be used in pseudo-instruction expansions which need AT.
397 unsigned getATReg(SMLoc Loc);
398
399 bool canUseATReg();
400
401 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
402 const MCSubtargetInfo *STI);
403
404 // Helper function that checks if the value of a vector index is within the
405 // boundaries of accepted values for each RegisterKind
406 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
407 bool validateMSAIndex(int Val, int RegKind);
408
409 // Selects a new architecture by updating the FeatureBits with the necessary
410 // info including implied dependencies.
411 // Internally, it clears all the feature bits related to *any* architecture
412 // and selects the new one using the ToggleFeature functionality of the
413 // MCSubtargetInfo object that handles implied dependencies. The reason we
414 // clear all the arch related bits manually is because ToggleFeature only
415 // clears the features that imply the feature being cleared and not the
416 // features implied by the feature being cleared. This is easier to see
417 // with an example:
418 // --------------------------------------------------
419 // | Feature | Implies |
420 // | -------------------------------------------------|
421 // | FeatureMips1 | None |
422 // | FeatureMips2 | FeatureMips1 |
423 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
424 // | FeatureMips4 | FeatureMips3 |
425 // | ... | |
426 // --------------------------------------------------
427 //
428 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
429 // FeatureMipsGP64 | FeatureMips1)
430 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
431 void selectArch(StringRef ArchFeature) {
432 MCSubtargetInfo &STI = copySTI();
433 FeatureBitset FeatureBits = STI.getFeatureBits();
434 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
435 STI.setFeatureBits(FeatureBits);
436 setAvailableFeatures(
437 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
438 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
439 }
440
441 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
442 if (!(getSTI().getFeatureBits()[Feature])) {
443 MCSubtargetInfo &STI = copySTI();
444 setAvailableFeatures(
445 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
446 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
447 }
448 }
449
450 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
451 if (getSTI().getFeatureBits()[Feature]) {
452 MCSubtargetInfo &STI = copySTI();
453 setAvailableFeatures(
454 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
455 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
456 }
457 }
458
459 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
460 setFeatureBits(Feature, FeatureString);
461 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
462 }
463
464 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
465 clearFeatureBits(Feature, FeatureString);
466 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
467 }
468
469public:
470 enum MipsMatchResultTy {
471 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
472 Match_RequiresDifferentOperands,
473 Match_RequiresNoZeroRegister,
474 Match_RequiresSameSrcAndDst,
475 Match_NoFCCRegisterForCurrentISA,
476 Match_NonZeroOperandForSync,
477 Match_NonZeroOperandForMTCX,
478 Match_RequiresPosSizeRange0_32,
479 Match_RequiresPosSizeRange33_64,
480 Match_RequiresPosSizeUImm6,
481#define GET_OPERAND_DIAGNOSTIC_TYPES
482#include "MipsGenAsmMatcher.inc"
483#undef GET_OPERAND_DIAGNOSTIC_TYPES
484 };
485
486 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
487 const MCInstrInfo &MII, const MCTargetOptions &Options)
488 : MCTargetAsmParser(Options, sti, MII),
489 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
490 sti.getCPU(), Options)) {
491 MCAsmParserExtension::Initialize(parser);
492
493 parser.addAliasForDirective(".asciiz", ".asciz");
494 parser.addAliasForDirective(".hword", ".2byte");
495 parser.addAliasForDirective(".word", ".4byte");
496 parser.addAliasForDirective(".dword", ".8byte");
497
498 // Initialize the set of available features.
499 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
500
501 // Remember the initial assembler options. The user can not modify these.
502 AssemblerOptions.push_back(
503 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
504
505 // Create an assembler options environment for the user to modify.
506 AssemblerOptions.push_back(
507 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
508
509 getTargetStreamer().updateABIInfo(*this);
510
511 if (!isABI_O32() && !useOddSPReg() != 0)
512 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
513
514 CurrentFn = nullptr;
515
516 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
517
518 IsCpRestoreSet = false;
519 CpRestoreOffset = -1;
520
521 const Triple &TheTriple = sti.getTargetTriple();
522 IsLittleEndian = TheTriple.isLittleEndian();
523
524 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
525 report_fatal_error("microMIPS64R6 is not supported", false);
526
527 if (!isABI_O32() && inMicroMipsMode())
528 report_fatal_error("microMIPS64 is not supported", false);
529 }
530
531 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
532 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
533
534 bool isGP64bit() const {
535 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
536 }
537
538 bool isFP64bit() const {
539 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
540 }
541
542 const MipsABIInfo &getABI() const { return ABI; }
543 bool isABI_N32() const { return ABI.IsN32(); }
544 bool isABI_N64() const { return ABI.IsN64(); }
545 bool isABI_O32() const { return ABI.IsO32(); }
546 bool isABI_FPXX() const {
547 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
548 }
549
550 bool useOddSPReg() const {
551 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
552 }
553
554 bool inMicroMipsMode() const {
555 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
556 }
557
558 bool hasMips1() const {
559 return getSTI().getFeatureBits()[Mips::FeatureMips1];
560 }
561
562 bool hasMips2() const {
563 return getSTI().getFeatureBits()[Mips::FeatureMips2];
564 }
565
566 bool hasMips3() const {
567 return getSTI().getFeatureBits()[Mips::FeatureMips3];
568 }
569
570 bool hasMips4() const {
571 return getSTI().getFeatureBits()[Mips::FeatureMips4];
572 }
573
574 bool hasMips5() const {
575 return getSTI().getFeatureBits()[Mips::FeatureMips5];
576 }
577
578 bool hasMips32() const {
579 return getSTI().getFeatureBits()[Mips::FeatureMips32];
580 }
581
582 bool hasMips64() const {
583 return getSTI().getFeatureBits()[Mips::FeatureMips64];
584 }
585
586 bool hasMips32r2() const {
587 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
588 }
589
590 bool hasMips64r2() const {
591 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
592 }
593
594 bool hasMips32r3() const {
595 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
596 }
597
598 bool hasMips64r3() const {
599 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
600 }
601
602 bool hasMips32r5() const {
603 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
604 }
605
606 bool hasMips64r5() const {
607 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
608 }
609
610 bool hasMips32r6() const {
611 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
612 }
613
614 bool hasMips64r6() const {
615 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
616 }
617
618 bool hasDSP() const {
619 return getSTI().getFeatureBits()[Mips::FeatureDSP];
620 }
621
622 bool hasDSPR2() const {
623 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
624 }
625
626 bool hasDSPR3() const {
627 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
628 }
629
630 bool hasMSA() const {
631 return getSTI().getFeatureBits()[Mips::FeatureMSA];
632 }
633
634 bool hasCnMips() const {
635 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
636 }
637
638 bool inPicMode() {
639 return IsPicEnabled;
640 }
641
642 bool inMips16Mode() const {
643 return getSTI().getFeatureBits()[Mips::FeatureMips16];
644 }
645
646 bool useTraps() const {
647 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
648 }
649
650 bool useSoftFloat() const {
651 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
652 }
653 bool hasMT() const {
654 return getSTI().getFeatureBits()[Mips::FeatureMT];
655 }
656
657 bool hasCRC() const {
658 return getSTI().getFeatureBits()[Mips::FeatureCRC];
659 }
660
661 bool hasVirt() const {
662 return getSTI().getFeatureBits()[Mips::FeatureVirt];
663 }
664
665 bool hasGINV() const {
666 return getSTI().getFeatureBits()[Mips::FeatureGINV];
667 }
668
669 /// Warn if RegIndex is the same as the current AT.
670 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
671
672 void warnIfNoMacro(SMLoc Loc);
673
674 bool isLittle() const { return IsLittleEndian; }
675
676 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
677 AsmToken::TokenKind OperatorToken,
678 MCContext &Ctx) override {
679 switch(OperatorToken) {
680 default:
681 llvm_unreachable("Unknown token")::llvm::llvm_unreachable_internal("Unknown token", "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 681)
;
682 return nullptr;
683 case AsmToken::PercentCall16:
684 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
685 case AsmToken::PercentCall_Hi:
686 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
687 case AsmToken::PercentCall_Lo:
688 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
689 case AsmToken::PercentDtprel_Hi:
690 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
691 case AsmToken::PercentDtprel_Lo:
692 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
693 case AsmToken::PercentGot:
694 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
695 case AsmToken::PercentGot_Disp:
696 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
697 case AsmToken::PercentGot_Hi:
698 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
699 case AsmToken::PercentGot_Lo:
700 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
701 case AsmToken::PercentGot_Ofst:
702 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
703 case AsmToken::PercentGot_Page:
704 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
705 case AsmToken::PercentGottprel:
706 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
707 case AsmToken::PercentGp_Rel:
708 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
709 case AsmToken::PercentHi:
710 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
711 case AsmToken::PercentHigher:
712 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
713 case AsmToken::PercentHighest:
714 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
715 case AsmToken::PercentLo:
716 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
717 case AsmToken::PercentNeg:
718 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
719 case AsmToken::PercentPcrel_Hi:
720 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
721 case AsmToken::PercentPcrel_Lo:
722 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
723 case AsmToken::PercentTlsgd:
724 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
725 case AsmToken::PercentTlsldm:
726 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
727 case AsmToken::PercentTprel_Hi:
728 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
729 case AsmToken::PercentTprel_Lo:
730 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
731 }
732 }
733};
734
735/// MipsOperand - Instances of this class represent a parsed Mips machine
736/// instruction.
737class MipsOperand : public MCParsedAsmOperand {
738public:
739 /// Broad categories of register classes
740 /// The exact class is finalized by the render method.
741 enum RegKind {
742 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
743 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
744 /// isFP64bit())
745 RegKind_FCC = 4, /// FCC
746 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
747 RegKind_MSACtrl = 16, /// MSA control registers
748 RegKind_COP2 = 32, /// COP2
749 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
750 /// context).
751 RegKind_CCR = 128, /// CCR
752 RegKind_HWRegs = 256, /// HWRegs
753 RegKind_COP3 = 512, /// COP3
754 RegKind_COP0 = 1024, /// COP0
755 /// Potentially any (e.g. $1)
756 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
757 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
758 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
759 };
760
761private:
762 enum KindTy {
763 k_Immediate, /// An immediate (possibly involving symbol references)
764 k_Memory, /// Base + Offset Memory Address
765 k_RegisterIndex, /// A register index in one or more RegKind.
766 k_Token, /// A simple token
767 k_RegList, /// A physical register list
768 } Kind;
769
770public:
771 MipsOperand(KindTy K, MipsAsmParser &Parser)
772 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
773
774 ~MipsOperand() override {
775 switch (Kind) {
776 case k_Memory:
777 delete Mem.Base;
778 break;
779 case k_RegList:
780 delete RegList.List;
781 break;
782 case k_Immediate:
783 case k_RegisterIndex:
784 case k_Token:
785 break;
786 }
787 }
788
789private:
790 /// For diagnostics, and checking the assembler temporary
791 MipsAsmParser &AsmParser;
792
793 struct Token {
794 const char *Data;
795 unsigned Length;
796 };
797
798 struct RegIdxOp {
799 unsigned Index; /// Index into the register class
800 RegKind Kind; /// Bitfield of the kinds it could possibly be
801 struct Token Tok; /// The input token this operand originated from.
802 const MCRegisterInfo *RegInfo;
803 };
804
805 struct ImmOp {
806 const MCExpr *Val;
807 };
808
809 struct MemOp {
810 MipsOperand *Base;
811 const MCExpr *Off;
812 };
813
814 struct RegListOp {
815 SmallVector<unsigned, 10> *List;
816 };
817
818 union {
819 struct Token Tok;
820 struct RegIdxOp RegIdx;
821 struct ImmOp Imm;
822 struct MemOp Mem;
823 struct RegListOp RegList;
824 };
825
826 SMLoc StartLoc, EndLoc;
827
828 /// Internal constructor for register kinds
829 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
830 RegKind RegKind,
831 const MCRegisterInfo *RegInfo,
832 SMLoc S, SMLoc E,
833 MipsAsmParser &Parser) {
834 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
835 Op->RegIdx.Index = Index;
836 Op->RegIdx.RegInfo = RegInfo;
837 Op->RegIdx.Kind = RegKind;
838 Op->RegIdx.Tok.Data = Str.data();
839 Op->RegIdx.Tok.Length = Str.size();
840 Op->StartLoc = S;
841 Op->EndLoc = E;
842 return Op;
843 }
844
845public:
846 /// Coerce the register to GPR32 and return the real register for the current
847 /// target.
848 unsigned getGPR32Reg() const {
849 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 849, __PRETTY_FUNCTION__))
;
850 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
851 unsigned ClassID = Mips::GPR32RegClassID;
852 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
853 }
854
855 /// Coerce the register to GPR32 and return the real register for the current
856 /// target.
857 unsigned getGPRMM16Reg() const {
858 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 858, __PRETTY_FUNCTION__))
;
859 unsigned ClassID = Mips::GPR32RegClassID;
860 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
861 }
862
863 /// Coerce the register to GPR64 and return the real register for the current
864 /// target.
865 unsigned getGPR64Reg() const {
866 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 866, __PRETTY_FUNCTION__))
;
867 unsigned ClassID = Mips::GPR64RegClassID;
868 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
869 }
870
871private:
872 /// Coerce the register to AFGR64 and return the real register for the current
873 /// target.
874 unsigned getAFGR64Reg() const {
875 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 875, __PRETTY_FUNCTION__))
;
876 if (RegIdx.Index % 2 != 0)
877 AsmParser.Warning(StartLoc, "Float register should be even.");
878 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
879 .getRegister(RegIdx.Index / 2);
880 }
881
882 /// Coerce the register to FGR64 and return the real register for the current
883 /// target.
884 unsigned getFGR64Reg() const {
885 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 885, __PRETTY_FUNCTION__))
;
886 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
887 .getRegister(RegIdx.Index);
888 }
889
890 /// Coerce the register to FGR32 and return the real register for the current
891 /// target.
892 unsigned getFGR32Reg() const {
893 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 893, __PRETTY_FUNCTION__))
;
894 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
895 .getRegister(RegIdx.Index);
896 }
897
898 /// Coerce the register to FGRH32 and return the real register for the current
899 /// target.
900 unsigned getFGRH32Reg() const {
901 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 901, __PRETTY_FUNCTION__))
;
902 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
903 .getRegister(RegIdx.Index);
904 }
905
906 /// Coerce the register to FCC and return the real register for the current
907 /// target.
908 unsigned getFCCReg() const {
909 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FCC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 909, __PRETTY_FUNCTION__))
;
910 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
911 .getRegister(RegIdx.Index);
912 }
913
914 /// Coerce the register to MSA128 and return the real register for the current
915 /// target.
916 unsigned getMSA128Reg() const {
917 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 917, __PRETTY_FUNCTION__))
;
918 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
919 // identical
920 unsigned ClassID = Mips::MSA128BRegClassID;
921 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
922 }
923
924 /// Coerce the register to MSACtrl and return the real register for the
925 /// current target.
926 unsigned getMSACtrlReg() const {
927 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 927, __PRETTY_FUNCTION__))
;
928 unsigned ClassID = Mips::MSACtrlRegClassID;
929 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
930 }
931
932 /// Coerce the register to COP0 and return the real register for the
933 /// current target.
934 unsigned getCOP0Reg() const {
935 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP0) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 935, __PRETTY_FUNCTION__))
;
936 unsigned ClassID = Mips::COP0RegClassID;
937 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
938 }
939
940 /// Coerce the register to COP2 and return the real register for the
941 /// current target.
942 unsigned getCOP2Reg() const {
943 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP2) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 943, __PRETTY_FUNCTION__))
;
944 unsigned ClassID = Mips::COP2RegClassID;
945 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
946 }
947
948 /// Coerce the register to COP3 and return the real register for the
949 /// current target.
950 unsigned getCOP3Reg() const {
951 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP3) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 951, __PRETTY_FUNCTION__))
;
952 unsigned ClassID = Mips::COP3RegClassID;
953 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
954 }
955
956 /// Coerce the register to ACC64DSP and return the real register for the
957 /// current target.
958 unsigned getACC64DSPReg() const {
959 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 959, __PRETTY_FUNCTION__))
;
960 unsigned ClassID = Mips::ACC64DSPRegClassID;
961 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
962 }
963
964 /// Coerce the register to HI32DSP and return the real register for the
965 /// current target.
966 unsigned getHI32DSPReg() const {
967 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 967, __PRETTY_FUNCTION__))
;
968 unsigned ClassID = Mips::HI32DSPRegClassID;
969 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
970 }
971
972 /// Coerce the register to LO32DSP and return the real register for the
973 /// current target.
974 unsigned getLO32DSPReg() const {
975 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 975, __PRETTY_FUNCTION__))
;
976 unsigned ClassID = Mips::LO32DSPRegClassID;
977 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
978 }
979
980 /// Coerce the register to CCR and return the real register for the
981 /// current target.
982 unsigned getCCRReg() const {
983 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_CCR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 983, __PRETTY_FUNCTION__))
;
984 unsigned ClassID = Mips::CCRRegClassID;
985 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
986 }
987
988 /// Coerce the register to HWRegs and return the real register for the
989 /// current target.
990 unsigned getHWRegsReg() const {
991 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 991, __PRETTY_FUNCTION__))
;
992 unsigned ClassID = Mips::HWRegsRegClassID;
993 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
994 }
995
996public:
997 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
998 // Add as immediate when possible. Null MCExpr = 0.
999 if (!Expr)
1000 Inst.addOperand(MCOperand::createImm(0));
1001 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1002 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1003 else
1004 Inst.addOperand(MCOperand::createExpr(Expr));
1005 }
1006
1007 void addRegOperands(MCInst &Inst, unsigned N) const {
1008 llvm_unreachable("Use a custom parser instead")::llvm::llvm_unreachable_internal("Use a custom parser instead"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1008)
;
1009 }
1010
1011 /// Render the operand to an MCInst as a GPR32
1012 /// Asserts if the wrong number of operands are requested, or the operand
1013 /// is not a k_RegisterIndex compatible with RegKind_GPR
1014 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1015 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1015, __PRETTY_FUNCTION__))
;
1016 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1017 }
1018
1019 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1020 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1020, __PRETTY_FUNCTION__))
;
1021 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1022 }
1023
1024 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1025 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1025, __PRETTY_FUNCTION__))
;
1026 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1027 }
1028
1029 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1030 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1030, __PRETTY_FUNCTION__))
;
1031 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1032 }
1033
1034 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1035 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1035, __PRETTY_FUNCTION__))
;
1036 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1037 }
1038
1039 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1040 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1040, __PRETTY_FUNCTION__))
;
1041 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1042 }
1043
1044 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1045 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1045, __PRETTY_FUNCTION__))
;
1046 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1047 }
1048
1049 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1050 unsigned N) const {
1051 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1051, __PRETTY_FUNCTION__))
;
1052 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1053 }
1054
1055 /// Render the operand to an MCInst as a GPR64
1056 /// Asserts if the wrong number of operands are requested, or the operand
1057 /// is not a k_RegisterIndex compatible with RegKind_GPR
1058 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1059 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1059, __PRETTY_FUNCTION__))
;
1060 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1061 }
1062
1063 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1064 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1064, __PRETTY_FUNCTION__))
;
1065 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1066 }
1067
1068 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1069 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1069, __PRETTY_FUNCTION__))
;
1070 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1071 }
1072
1073 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1074 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1074, __PRETTY_FUNCTION__))
;
1075 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1076 }
1077
1078 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1079 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1079, __PRETTY_FUNCTION__))
;
1080 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1081 }
1082
1083 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1084 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1084, __PRETTY_FUNCTION__))
;
1085 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1086 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1087 // FIXME: This should propagate failure up to parseStatement.
1088 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1089 AsmParser.getParser().printError(
1090 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1091 "registers");
1092 }
1093
1094 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1095 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1095, __PRETTY_FUNCTION__))
;
1096 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1097 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1098 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1099 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1100 "registers");
1101 }
1102
1103 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1104 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1104, __PRETTY_FUNCTION__))
;
1105 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1106 }
1107
1108 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1109 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1109, __PRETTY_FUNCTION__))
;
1110 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1111 }
1112
1113 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1114 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1114, __PRETTY_FUNCTION__))
;
1115 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1116 }
1117
1118 void addMSACtrlAsmRegOperands(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!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1119, __PRETTY_FUNCTION__))
;
1120 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1121 }
1122
1123 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1124 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1124, __PRETTY_FUNCTION__))
;
1125 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1126 }
1127
1128 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1129 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1129, __PRETTY_FUNCTION__))
;
1130 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1131 }
1132
1133 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1134 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1134, __PRETTY_FUNCTION__))
;
1135 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1136 }
1137
1138 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1139 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1139, __PRETTY_FUNCTION__))
;
1140 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1141 }
1142
1143 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1144 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1144, __PRETTY_FUNCTION__))
;
1145 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1146 }
1147
1148 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1149 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1149, __PRETTY_FUNCTION__))
;
1150 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1151 }
1152
1153 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1154 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1154, __PRETTY_FUNCTION__))
;
1155 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1156 }
1157
1158 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1159 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1159, __PRETTY_FUNCTION__))
;
1160 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1161 }
1162
1163 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1164 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1165, __PRETTY_FUNCTION__))
;
1166 uint64_t Imm = getConstantImm() - Offset;
1167 Imm &= (1ULL << Bits) - 1;
1168 Imm += Offset;
1169 Imm += AdjustOffset;
1170 Inst.addOperand(MCOperand::createImm(Imm));
1171 }
1172
1173 template <unsigned Bits>
1174 void addSImmOperands(MCInst &Inst, unsigned N) const {
1175 if (isImm() && !isConstantImm()) {
1176 addExpr(Inst, getImm());
1177 return;
1178 }
1179 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1180 }
1181
1182 template <unsigned Bits>
1183 void addUImmOperands(MCInst &Inst, unsigned N) const {
1184 if (isImm() && !isConstantImm()) {
1185 addExpr(Inst, getImm());
1186 return;
1187 }
1188 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1189 }
1190
1191 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1192 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1193, __PRETTY_FUNCTION__))
;
1194 int64_t Imm = getConstantImm() - Offset;
1195 Imm = SignExtend64<Bits>(Imm);
1196 Imm += Offset;
1197 Imm += AdjustOffset;
1198 Inst.addOperand(MCOperand::createImm(Imm));
1199 }
1200
1201 void addImmOperands(MCInst &Inst, unsigned N) const {
1202 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1202, __PRETTY_FUNCTION__))
;
1203 const MCExpr *Expr = getImm();
1204 addExpr(Inst, Expr);
1205 }
1206
1207 void addMemOperands(MCInst &Inst, unsigned N) const {
1208 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1208, __PRETTY_FUNCTION__))
;
1209
1210 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1211 ? getMemBase()->getGPR64Reg()
1212 : getMemBase()->getGPR32Reg()));
1213
1214 const MCExpr *Expr = getMemOff();
1215 addExpr(Inst, Expr);
1216 }
1217
1218 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1219 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1219, __PRETTY_FUNCTION__))
;
1220
1221 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1222
1223 const MCExpr *Expr = getMemOff();
1224 addExpr(Inst, Expr);
1225 }
1226
1227 void addRegListOperands(MCInst &Inst, unsigned N) const {
1228 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1228, __PRETTY_FUNCTION__))
;
1229
1230 for (auto RegNo : getRegList())
1231 Inst.addOperand(MCOperand::createReg(RegNo));
1232 }
1233
1234 bool isReg() const override {
1235 // As a special case until we sort out the definition of div/divu, accept
1236 // $0/$zero here so that MCK_ZERO works correctly.
1237 return isGPRAsmReg() && RegIdx.Index == 0;
1238 }
1239
1240 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1241 bool isImm() const override { return Kind == k_Immediate; }
1242
1243 bool isConstantImm() const {
1244 int64_t Res;
1245 return isImm() && getImm()->evaluateAsAbsolute(Res);
1246 }
1247
1248 bool isConstantImmz() const {
1249 return isConstantImm() && getConstantImm() == 0;
1250 }
1251
1252 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254 }
1255
1256 template <unsigned Bits> bool isSImm() const {
1257 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1258 }
1259
1260 template <unsigned Bits> bool isUImm() const {
1261 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1262 }
1263
1264 template <unsigned Bits> bool isAnyImm() const {
1265 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1266 isUInt<Bits>(getConstantImm()))
1267 : isImm();
1268 }
1269
1270 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1271 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1272 }
1273
1274 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1275 return isConstantImm() && getConstantImm() >= Bottom &&
1276 getConstantImm() <= Top;
1277 }
1278
1279 bool isToken() const override {
1280 // Note: It's not possible to pretend that other operand kinds are tokens.
1281 // The matcher emitter checks tokens first.
1282 return Kind == k_Token;
1283 }
1284
1285 bool isMem() const override { return Kind == k_Memory; }
1286
1287 bool isConstantMemOff() const {
1288 return isMem() && isa<MCConstantExpr>(getMemOff());
1289 }
1290
1291 // Allow relocation operators.
1292 // FIXME: This predicate and others need to look through binary expressions
1293 // and determine whether a Value is a constant or not.
1294 template <unsigned Bits, unsigned ShiftAmount = 0>
1295 bool isMemWithSimmOffset() const {
1296 if (!isMem())
1297 return false;
1298 if (!getMemBase()->isGPRAsmReg())
1299 return false;
1300 if (isa<MCTargetExpr>(getMemOff()) ||
1301 (isConstantMemOff() &&
1302 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303 return true;
1304 MCValue Res;
1305 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307 }
1308
1309 bool isMemWithPtrSizeOffset() const {
1310 if (!isMem())
1311 return false;
1312 if (!getMemBase()->isGPRAsmReg())
1313 return false;
1314 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1315 if (isa<MCTargetExpr>(getMemOff()) ||
1316 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1317 return true;
1318 MCValue Res;
1319 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1320 return IsReloc && isIntN(PtrBits, Res.getConstant());
1321 }
1322
1323 bool isMemWithGRPMM16Base() const {
1324 return isMem() && getMemBase()->isMM16AsmReg();
1325 }
1326
1327 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1328 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1329 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1330 }
1331
1332 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1333 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1334 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1335 && (getMemBase()->getGPR32Reg() == Mips::SP);
1336 }
1337
1338 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1339 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1340 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1341 && (getMemBase()->getGPR32Reg() == Mips::GP);
1342 }
1343
1344 template <unsigned Bits, unsigned ShiftLeftAmount>
1345 bool isScaledUImm() const {
1346 return isConstantImm() &&
1347 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1348 }
1349
1350 template <unsigned Bits, unsigned ShiftLeftAmount>
1351 bool isScaledSImm() const {
1352 if (isConstantImm() &&
1353 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1354 return true;
1355 // Operand can also be a symbol or symbol plus
1356 // offset in case of relocations.
1357 if (Kind != k_Immediate)
1358 return false;
1359 MCValue Res;
1360 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1361 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1362 }
1363
1364 bool isRegList16() const {
1365 if (!isRegList())
1366 return false;
1367
1368 int Size = RegList.List->size();
1369 if (Size < 2 || Size > 5)
1370 return false;
1371
1372 unsigned R0 = RegList.List->front();
1373 unsigned R1 = RegList.List->back();
1374 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1375 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1376 return false;
1377
1378 int PrevReg = *RegList.List->begin();
1379 for (int i = 1; i < Size - 1; i++) {
1380 int Reg = (*(RegList.List))[i];
1381 if ( Reg != PrevReg + 1)
1382 return false;
1383 PrevReg = Reg;
1384 }
1385
1386 return true;
1387 }
1388
1389 bool isInvNum() const { return Kind == k_Immediate; }
1390
1391 bool isLSAImm() const {
1392 if (!isConstantImm())
1393 return false;
1394 int64_t Val = getConstantImm();
1395 return 1 <= Val && Val <= 4;
1396 }
1397
1398 bool isRegList() const { return Kind == k_RegList; }
1399
1400 StringRef getToken() const {
1401 assert(Kind == k_Token && "Invalid access!")((Kind == k_Token && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Token && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1401, __PRETTY_FUNCTION__))
;
1402 return StringRef(Tok.Data, Tok.Length);
1403 }
1404
1405 unsigned getReg() const override {
1406 // As a special case until we sort out the definition of div/divu, accept
1407 // $0/$zero here so that MCK_ZERO works correctly.
1408 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1409 RegIdx.Kind & RegKind_GPR)
1410 return getGPR32Reg(); // FIXME: GPR64 too
1411
1412 llvm_unreachable("Invalid access!")::llvm::llvm_unreachable_internal("Invalid access!", "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1412)
;
1413 return 0;
1414 }
1415
1416 const MCExpr *getImm() const {
1417 assert((Kind == k_Immediate) && "Invalid access!")(((Kind == k_Immediate) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Immediate) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1417, __PRETTY_FUNCTION__))
;
1418 return Imm.Val;
1419 }
1420
1421 int64_t getConstantImm() const {
1422 const MCExpr *Val = getImm();
1423 int64_t Value = 0;
1424 (void)Val->evaluateAsAbsolute(Value);
1425 return Value;
1426 }
1427
1428 MipsOperand *getMemBase() const {
1429 assert((Kind == k_Memory) && "Invalid access!")(((Kind == k_Memory) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Memory) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1429, __PRETTY_FUNCTION__))
;
1430 return Mem.Base;
1431 }
1432
1433 const MCExpr *getMemOff() const {
1434 assert((Kind == k_Memory) && "Invalid access!")(((Kind == k_Memory) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Memory) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1434, __PRETTY_FUNCTION__))
;
1435 return Mem.Off;
1436 }
1437
1438 int64_t getConstantMemOff() const {
1439 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1440 }
1441
1442 const SmallVectorImpl<unsigned> &getRegList() const {
1443 assert((Kind == k_RegList) && "Invalid access!")(((Kind == k_RegList) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_RegList) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1443, __PRETTY_FUNCTION__))
;
1444 return *(RegList.List);
1445 }
1446
1447 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1448 MipsAsmParser &Parser) {
1449 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1450 Op->Tok.Data = Str.data();
1451 Op->Tok.Length = Str.size();
1452 Op->StartLoc = S;
1453 Op->EndLoc = S;
1454 return Op;
1455 }
1456
1457 /// Create a numeric register (e.g. $1). The exact register remains
1458 /// unresolved until an instruction successfully matches
1459 static std::unique_ptr<MipsOperand>
1460 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1461 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1462 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "createNumericReg(" <<
Index << ", ...)\n"; } } while (false)
;
1463 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1464 }
1465
1466 /// Create a register that is definitely a GPR.
1467 /// This is typically only used for named registers such as $gp.
1468 static std::unique_ptr<MipsOperand>
1469 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1470 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1471 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1472 }
1473
1474 /// Create a register that is definitely a FGR.
1475 /// This is typically only used for named registers such as $f0.
1476 static std::unique_ptr<MipsOperand>
1477 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1478 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1479 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1480 }
1481
1482 /// Create a register that is definitely a HWReg.
1483 /// This is typically only used for named registers such as $hwr_cpunum.
1484 static std::unique_ptr<MipsOperand>
1485 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1486 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1487 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1488 }
1489
1490 /// Create a register that is definitely an FCC.
1491 /// This is typically only used for named registers such as $fcc0.
1492 static std::unique_ptr<MipsOperand>
1493 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1494 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1495 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1496 }
1497
1498 /// Create a register that is definitely an ACC.
1499 /// This is typically only used for named registers such as $ac0.
1500 static std::unique_ptr<MipsOperand>
1501 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1502 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1503 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1504 }
1505
1506 /// Create a register that is definitely an MSA128.
1507 /// This is typically only used for named registers such as $w0.
1508 static std::unique_ptr<MipsOperand>
1509 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1510 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1511 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1512 }
1513
1514 /// Create a register that is definitely an MSACtrl.
1515 /// This is typically only used for named registers such as $msaaccess.
1516 static std::unique_ptr<MipsOperand>
1517 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1518 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1519 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1520 }
1521
1522 static std::unique_ptr<MipsOperand>
1523 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1524 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1525 Op->Imm.Val = Val;
1526 Op->StartLoc = S;
1527 Op->EndLoc = E;
1528 return Op;
1529 }
1530
1531 static std::unique_ptr<MipsOperand>
1532 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1533 SMLoc E, MipsAsmParser &Parser) {
1534 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1535 Op->Mem.Base = Base.release();
1536 Op->Mem.Off = Off;
1537 Op->StartLoc = S;
1538 Op->EndLoc = E;
1539 return Op;
1540 }
1541
1542 static std::unique_ptr<MipsOperand>
1543 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1544 MipsAsmParser &Parser) {
1545 assert(Regs.size() > 0 && "Empty list not allowed")((Regs.size() > 0 && "Empty list not allowed") ? static_cast
<void> (0) : __assert_fail ("Regs.size() > 0 && \"Empty list not allowed\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1545, __PRETTY_FUNCTION__))
;
1546
1547 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1548 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1549 Op->StartLoc = StartLoc;
1550 Op->EndLoc = EndLoc;
1551 return Op;
1552 }
1553
1554 bool isGPRZeroAsmReg() const {
1555 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1556 }
1557
1558 bool isGPRNonZeroAsmReg() const {
1559 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1560 RegIdx.Index <= 31;
1561 }
1562
1563 bool isGPRAsmReg() const {
1564 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1565 }
1566
1567 bool isMM16AsmReg() const {
1568 if (!(isRegIdx() && RegIdx.Kind))
1569 return false;
1570 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1571 || RegIdx.Index == 16 || RegIdx.Index == 17);
1572
1573 }
1574 bool isMM16AsmRegZero() const {
1575 if (!(isRegIdx() && RegIdx.Kind))
1576 return false;
1577 return (RegIdx.Index == 0 ||
1578 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1579 RegIdx.Index == 17);
1580 }
1581
1582 bool isMM16AsmRegMoveP() const {
1583 if (!(isRegIdx() && RegIdx.Kind))
1584 return false;
1585 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1586 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1587 }
1588
1589 bool isMM16AsmRegMovePPairFirst() const {
1590 if (!(isRegIdx() && RegIdx.Kind))
1591 return false;
1592 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1593 }
1594
1595 bool isMM16AsmRegMovePPairSecond() const {
1596 if (!(isRegIdx() && RegIdx.Kind))
1597 return false;
1598 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1599 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1600 }
1601
1602 bool isFGRAsmReg() const {
1603 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1604 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1605 }
1606
1607 bool isStrictlyFGRAsmReg() const {
1608 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1609 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1610 }
1611
1612 bool isHWRegsAsmReg() const {
1613 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1614 }
1615
1616 bool isCCRAsmReg() const {
1617 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1618 }
1619
1620 bool isFCCAsmReg() const {
1621 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1622 return false;
1623 return RegIdx.Index <= 7;
1624 }
1625
1626 bool isACCAsmReg() const {
1627 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1628 }
1629
1630 bool isCOP0AsmReg() const {
1631 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1632 }
1633
1634 bool isCOP2AsmReg() const {
1635 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1636 }
1637
1638 bool isCOP3AsmReg() const {
1639 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1640 }
1641
1642 bool isMSA128AsmReg() const {
1643 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1644 }
1645
1646 bool isMSACtrlAsmReg() const {
1647 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1648 }
1649
1650 /// getStartLoc - Get the location of the first token of this operand.
1651 SMLoc getStartLoc() const override { return StartLoc; }
1652 /// getEndLoc - Get the location of the last token of this operand.
1653 SMLoc getEndLoc() const override { return EndLoc; }
1654
1655 void print(raw_ostream &OS) const override {
1656 switch (Kind) {
1657 case k_Immediate:
1658 OS << "Imm<";
1659 OS << *Imm.Val;
1660 OS << ">";
1661 break;
1662 case k_Memory:
1663 OS << "Mem<";
1664 Mem.Base->print(OS);
1665 OS << ", ";
1666 OS << *Mem.Off;
1667 OS << ">";
1668 break;
1669 case k_RegisterIndex:
1670 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1671 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1672 break;
1673 case k_Token:
1674 OS << getToken();
1675 break;
1676 case k_RegList:
1677 OS << "RegList< ";
1678 for (auto Reg : (*RegList.List))
1679 OS << Reg << " ";
1680 OS << ">";
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", "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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\""
, "/build/llvm-toolchain-snapshot-8~svn349319/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 LLVM_FALLTHROUGH[[clang::fallthrough]];
1970 case Mips::SDivMacro:
1971 case Mips::DSDivMacro:
1972 case Mips::UDivMacro:
1973 case Mips::DUDivMacro:
1974 case Mips::DIV:
1975 case Mips::DIVU:
1976 case Mips::DDIV:
1977 case Mips::DDIVU:
1978 case Mips::DIVU_MMR6:
1979 case Mips::DIV_MMR6:
1980 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1981 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1982 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1983 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1984 Warning(IDLoc, "dividing zero by zero");
1985 else
1986 Warning(IDLoc, "division by zero");
1987 }
1988 break;
1989 }
1990
1991 // For PIC code convert unconditional jump to unconditional branch.
1992 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1993 inPicMode()) {
1994 MCInst BInst;
1995 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1996 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1997 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1998 BInst.addOperand(Inst.getOperand(0));
1999 Inst = BInst;
2000 }
2001
2002 // This expansion is not in a function called by tryExpandInstruction()
2003 // because the pseudo-instruction doesn't have a distinct opcode.
2004 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2005 inPicMode()) {
2006 warnIfNoMacro(IDLoc);
2007
2008 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2009
2010 // We can do this expansion if there's only 1 symbol in the argument
2011 // expression.
2012 if (countMCSymbolRefExpr(JalExpr) > 1)
2013 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2014
2015 // FIXME: This is checking the expression can be handled by the later stages
2016 // of the assembler. We ought to leave it to those later stages.
2017 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2018
2019 // FIXME: Add support for label+offset operands (currently causes an error).
2020 // FIXME: Add support for forward-declared local symbols.
2021 // FIXME: Add expansion for when the LargeGOT option is enabled.
2022 if (JalSym->isInSection() || JalSym->isTemporary() ||
2023 (JalSym->isELF() &&
2024 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 if (EmitJalrReloc) {
2075 // As an optimization hint for the linker, before the JALR we add:
2076 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2077 // tmplabel:
2078 MCSymbol *TmpLabel = getContext().createTempSymbol();
2079 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2080 const MCExpr *RelocJalrExpr =
2081 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2082 getContext(), IDLoc);
2083
2084 TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2085 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2086 RelocJalrExpr, IDLoc, *STI);
2087 TOut.getStreamer().EmitLabel(TmpLabel);
2088 }
2089
2090 Inst = JalrInst;
2091 ExpandedJalSym = true;
2092 }
2093
2094 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2095 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2096 // Check the offset of memory operand, if it is a symbol
2097 // reference or immediate we may have to expand instructions.
2098 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2099 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2100 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2101 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2102 MCOperand &Op = Inst.getOperand(i);
2103 if (Op.isImm()) {
2104 int64_t MemOffset = Op.getImm();
2105 if (MemOffset < -32768 || MemOffset > 32767) {
2106 // Offset can't exceed 16bit value.
2107 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2108 return getParser().hasPendingError();
2109 }
2110 } else if (Op.isExpr()) {
2111 const MCExpr *Expr = Op.getExpr();
2112 if (Expr->getKind() == MCExpr::SymbolRef) {
2113 const MCSymbolRefExpr *SR =
2114 static_cast<const MCSymbolRefExpr *>(Expr);
2115 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2116 // Expand symbol.
2117 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2118 return getParser().hasPendingError();
2119 }
2120 } else if (!isEvaluated(Expr)) {
2121 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2122 return getParser().hasPendingError();
2123 }
2124 }
2125 }
2126 } // for
2127 } // if load/store
2128
2129 if (inMicroMipsMode()) {
2130 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2131 // Try to create 16-bit GP relative load instruction.
2132 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2133 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2134 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2135 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2136 MCOperand &Op = Inst.getOperand(i);
2137 if (Op.isImm()) {
2138 int MemOffset = Op.getImm();
2139 MCOperand &DstReg = Inst.getOperand(0);
2140 MCOperand &BaseReg = Inst.getOperand(1);
2141 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2142 getContext().getRegisterInfo()->getRegClass(
2143 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2144 (BaseReg.getReg() == Mips::GP ||
2145 BaseReg.getReg() == Mips::GP_64)) {
2146
2147 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2148 IDLoc, STI);
2149 return false;
2150 }
2151 }
2152 }
2153 } // for
2154 } // if load
2155
2156 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2157
2158 MCOperand Opnd;
2159 int Imm;
2160
2161 switch (Inst.getOpcode()) {
2162 default:
2163 break;
2164 case Mips::ADDIUSP_MM:
2165 Opnd = Inst.getOperand(0);
2166 if (!Opnd.isImm())
2167 return Error(IDLoc, "expected immediate operand kind");
2168 Imm = Opnd.getImm();
2169 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2170 Imm % 4 != 0)
2171 return Error(IDLoc, "immediate operand value out of range");
2172 break;
2173 case Mips::SLL16_MM:
2174 case Mips::SRL16_MM:
2175 Opnd = Inst.getOperand(2);
2176 if (!Opnd.isImm())
2177 return Error(IDLoc, "expected immediate operand kind");
2178 Imm = Opnd.getImm();
2179 if (Imm < 1 || Imm > 8)
2180 return Error(IDLoc, "immediate operand value out of range");
2181 break;
2182 case Mips::LI16_MM:
2183 Opnd = Inst.getOperand(1);
2184 if (!Opnd.isImm())
2185 return Error(IDLoc, "expected immediate operand kind");
2186 Imm = Opnd.getImm();
2187 if (Imm < -1 || Imm > 126)
2188 return Error(IDLoc, "immediate operand value out of range");
2189 break;
2190 case Mips::ADDIUR2_MM:
2191 Opnd = Inst.getOperand(2);
2192 if (!Opnd.isImm())
2193 return Error(IDLoc, "expected immediate operand kind");
2194 Imm = Opnd.getImm();
2195 if (!(Imm == 1 || Imm == -1 ||
2196 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2197 return Error(IDLoc, "immediate operand value out of range");
2198 break;
2199 case Mips::ANDI16_MM:
2200 Opnd = Inst.getOperand(2);
2201 if (!Opnd.isImm())
2202 return Error(IDLoc, "expected immediate operand kind");
2203 Imm = Opnd.getImm();
2204 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2205 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2206 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2207 return Error(IDLoc, "immediate operand value out of range");
2208 break;
2209 case Mips::LBU16_MM:
2210 Opnd = Inst.getOperand(2);
2211 if (!Opnd.isImm())
2212 return Error(IDLoc, "expected immediate operand kind");
2213 Imm = Opnd.getImm();
2214 if (Imm < -1 || Imm > 14)
2215 return Error(IDLoc, "immediate operand value out of range");
2216 break;
2217 case Mips::SB16_MM:
2218 case Mips::SB16_MMR6:
2219 Opnd = Inst.getOperand(2);
2220 if (!Opnd.isImm())
2221 return Error(IDLoc, "expected immediate operand kind");
2222 Imm = Opnd.getImm();
2223 if (Imm < 0 || Imm > 15)
2224 return Error(IDLoc, "immediate operand value out of range");
2225 break;
2226 case Mips::LHU16_MM:
2227 case Mips::SH16_MM:
2228 case Mips::SH16_MMR6:
2229 Opnd = Inst.getOperand(2);
2230 if (!Opnd.isImm())
2231 return Error(IDLoc, "expected immediate operand kind");
2232 Imm = Opnd.getImm();
2233 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2234 return Error(IDLoc, "immediate operand value out of range");
2235 break;
2236 case Mips::LW16_MM:
2237 case Mips::SW16_MM:
2238 case Mips::SW16_MMR6:
2239 Opnd = Inst.getOperand(2);
2240 if (!Opnd.isImm())
2241 return Error(IDLoc, "expected immediate operand kind");
2242 Imm = Opnd.getImm();
2243 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2244 return Error(IDLoc, "immediate operand value out of range");
2245 break;
2246 case Mips::ADDIUPC_MM:
2247 Opnd = Inst.getOperand(1);
2248 if (!Opnd.isImm())
2249 return Error(IDLoc, "expected immediate operand kind");
2250 Imm = Opnd.getImm();
2251 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2252 return Error(IDLoc, "immediate operand value out of range");
2253 break;
2254 case Mips::LWP_MM:
2255 case Mips::SWP_MM:
2256 if (Inst.getOperand(0).getReg() == Mips::RA)
2257 return Error(IDLoc, "invalid operand for instruction");
2258 break;
2259 case Mips::MOVEP_MM:
2260 case Mips::MOVEP_MMR6: {
2261 unsigned R0 = Inst.getOperand(0).getReg();
2262 unsigned R1 = Inst.getOperand(1).getReg();
2263 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2264 (R0 == Mips::A1 && R1 == Mips::A3) ||
2265 (R0 == Mips::A2 && R1 == Mips::A3) ||
2266 (R0 == Mips::A0 && R1 == Mips::S5) ||
2267 (R0 == Mips::A0 && R1 == Mips::S6) ||
2268 (R0 == Mips::A0 && R1 == Mips::A1) ||
2269 (R0 == Mips::A0 && R1 == Mips::A2) ||
2270 (R0 == Mips::A0 && R1 == Mips::A3));
2271 if (!RegPair)
2272 return Error(IDLoc, "invalid operand for instruction");
2273 break;
2274 }
2275 }
2276 }
2277
2278 bool FillDelaySlot =
2279 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2280 if (FillDelaySlot)
2281 TOut.emitDirectiveSetNoReorder();
2282
2283 MacroExpanderResultTy ExpandResult =
2284 tryExpandInstruction(Inst, IDLoc, Out, STI);
2285 switch (ExpandResult) {
2286 case MER_NotAMacro:
2287 Out.EmitInstruction(Inst, *STI);
2288 break;
2289 case MER_Success:
2290 break;
2291 case MER_Fail:
2292 return true;
2293 }
2294
2295 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2296 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2297 if (inMicroMipsMode()) {
2298 TOut.setUsesMicroMips();
2299 TOut.updateABIInfo(*this);
2300 }
2301
2302 // If this instruction has a delay slot and .set reorder is active,
2303 // emit a NOP after it.
2304 if (FillDelaySlot) {
2305 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2306 TOut.emitDirectiveSetReorder();
2307 }
2308
2309 if ((Inst.getOpcode() == Mips::JalOneReg ||
2310 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2311 isPicAndNotNxxAbi()) {
2312 if (IsCpRestoreSet) {
2313 // We need a NOP between the JALR and the LW:
2314 // If .set reorder has been used, we've already emitted a NOP.
2315 // If .set noreorder has been used, we need to emit a NOP at this point.
2316 if (!AssemblerOptions.back()->isReorder())
2317 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2318 STI);
2319
2320 // Load the $gp from the stack.
2321 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2322 } else
2323 Warning(IDLoc, "no .cprestore used in PIC mode");
2324 }
2325
2326 return false;
2327}
2328
2329MipsAsmParser::MacroExpanderResultTy
2330MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2331 const MCSubtargetInfo *STI) {
2332 switch (Inst.getOpcode()) {
2333 default:
2334 return MER_NotAMacro;
2335 case Mips::LoadImm32:
2336 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2337 case Mips::LoadImm64:
2338 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2339 case Mips::LoadAddrImm32:
2340 case Mips::LoadAddrImm64:
2341 assert(Inst.getOperand(0).isReg() && "expected register operand kind")((Inst.getOperand(0).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2341, __PRETTY_FUNCTION__))
;
2342 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&(((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2343, __PRETTY_FUNCTION__))
2343 "expected immediate operand kind")(((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2343, __PRETTY_FUNCTION__))
;
2344
2345 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2346 Inst.getOperand(1),
2347 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2348 Out, STI)
2349 ? MER_Fail
2350 : MER_Success;
2351 case Mips::LoadAddrReg32:
2352 case Mips::LoadAddrReg64:
2353 assert(Inst.getOperand(0).isReg() && "expected register operand kind")((Inst.getOperand(0).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2353, __PRETTY_FUNCTION__))
;
2354 assert(Inst.getOperand(1).isReg() && "expected register operand kind")((Inst.getOperand(1).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(1).isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2354, __PRETTY_FUNCTION__))
;
2355 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&(((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2356, __PRETTY_FUNCTION__))
2356 "expected immediate operand kind")(((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2356, __PRETTY_FUNCTION__))
;
2357
2358 return expandLoadAddress(Inst.getOperand(0).getReg(),
2359 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2360 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2361 Out, STI)
2362 ? MER_Fail
2363 : MER_Success;
2364 case Mips::B_MM_Pseudo:
2365 case Mips::B_MMR6_Pseudo:
2366 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2367 : MER_Success;
2368 case Mips::SWM_MM:
2369 case Mips::LWM_MM:
2370 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2371 : MER_Success;
2372 case Mips::JalOneReg:
2373 case Mips::JalTwoReg:
2374 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2375 case Mips::BneImm:
2376 case Mips::BeqImm:
2377 case Mips::BEQLImmMacro:
2378 case Mips::BNELImmMacro:
2379 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2380 case Mips::BLT:
2381 case Mips::BLE:
2382 case Mips::BGE:
2383 case Mips::BGT:
2384 case Mips::BLTU:
2385 case Mips::BLEU:
2386 case Mips::BGEU:
2387 case Mips::BGTU:
2388 case Mips::BLTL:
2389 case Mips::BLEL:
2390 case Mips::BGEL:
2391 case Mips::BGTL:
2392 case Mips::BLTUL:
2393 case Mips::BLEUL:
2394 case Mips::BGEUL:
2395 case Mips::BGTUL:
2396 case Mips::BLTImmMacro:
2397 case Mips::BLEImmMacro:
2398 case Mips::BGEImmMacro:
2399 case Mips::BGTImmMacro:
2400 case Mips::BLTUImmMacro:
2401 case Mips::BLEUImmMacro:
2402 case Mips::BGEUImmMacro:
2403 case Mips::BGTUImmMacro:
2404 case Mips::BLTLImmMacro:
2405 case Mips::BLELImmMacro:
2406 case Mips::BGELImmMacro:
2407 case Mips::BGTLImmMacro:
2408 case Mips::BLTULImmMacro:
2409 case Mips::BLEULImmMacro:
2410 case Mips::BGEULImmMacro:
2411 case Mips::BGTULImmMacro:
2412 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2413 case Mips::SDivMacro:
2414 case Mips::SDivIMacro:
2415 case Mips::SRemMacro:
2416 case Mips::SRemIMacro:
2417 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2418 : MER_Success;
2419 case Mips::DSDivMacro:
2420 case Mips::DSDivIMacro:
2421 case Mips::DSRemMacro:
2422 case Mips::DSRemIMacro:
2423 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2424 : MER_Success;
2425 case Mips::UDivMacro:
2426 case Mips::UDivIMacro:
2427 case Mips::URemMacro:
2428 case Mips::URemIMacro:
2429 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2430 : MER_Success;
2431 case Mips::DUDivMacro:
2432 case Mips::DUDivIMacro:
2433 case Mips::DURemMacro:
2434 case Mips::DURemIMacro:
2435 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2436 : MER_Success;
2437 case Mips::PseudoTRUNC_W_S:
2438 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2439 : MER_Success;
2440 case Mips::PseudoTRUNC_W_D32:
2441 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2442 : MER_Success;
2443 case Mips::PseudoTRUNC_W_D:
2444 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2445 : MER_Success;
2446
2447 case Mips::LoadImmSingleGPR:
2448 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2449 ? MER_Fail
2450 : MER_Success;
2451 case Mips::LoadImmSingleFGR:
2452 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2453 ? MER_Fail
2454 : MER_Success;
2455 case Mips::LoadImmDoubleGPR:
2456 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2457 ? MER_Fail
2458 : MER_Success;
2459 case Mips::LoadImmDoubleFGR:
2460 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2461 ? MER_Fail
2462 : MER_Success;
2463 case Mips::LoadImmDoubleFGR_32:
2464 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2465 ? MER_Fail
2466 : MER_Success;
2467 case Mips::Ulh:
2468 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2469 case Mips::Ulhu:
2470 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2471 case Mips::Ush:
2472 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2473 case Mips::Ulw:
2474 case Mips::Usw:
2475 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2476 case Mips::NORImm:
2477 case Mips::NORImm64:
2478 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2479 case Mips::SLTImm64:
2480 if (isInt<16>(Inst.getOperand(2).getImm())) {
2481 Inst.setOpcode(Mips::SLTi64);
2482 return MER_NotAMacro;
2483 }
2484 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2485 case Mips::SLTUImm64:
2486 if (isInt<16>(Inst.getOperand(2).getImm())) {
2487 Inst.setOpcode(Mips::SLTiu64);
2488 return MER_NotAMacro;
2489 }
2490 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2491 case Mips::ADDi: case Mips::ADDi_MM:
2492 case Mips::ADDiu: case Mips::ADDiu_MM:
2493 case Mips::SLTi: case Mips::SLTi_MM:
2494 case Mips::SLTiu: case Mips::SLTiu_MM:
2495 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2496 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2497 int64_t ImmValue = Inst.getOperand(2).getImm();
2498 if (isInt<16>(ImmValue))
2499 return MER_NotAMacro;
2500 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2501 : MER_Success;
2502 }
2503 return MER_NotAMacro;
2504 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2505 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2506 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2507 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2508 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2509 int64_t ImmValue = Inst.getOperand(2).getImm();
2510 if (isUInt<16>(ImmValue))
2511 return MER_NotAMacro;
2512 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2513 : MER_Success;
2514 }
2515 return MER_NotAMacro;
2516 case Mips::ROL:
2517 case Mips::ROR:
2518 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2519 case Mips::ROLImm:
2520 case Mips::RORImm:
2521 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2522 case Mips::DROL:
2523 case Mips::DROR:
2524 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2525 case Mips::DROLImm:
2526 case Mips::DRORImm:
2527 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2528 case Mips::ABSMacro:
2529 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2530 case Mips::MULImmMacro:
2531 case Mips::DMULImmMacro:
2532 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2533 case Mips::MULOMacro:
2534 case Mips::DMULOMacro:
2535 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::MULOUMacro:
2537 case Mips::DMULOUMacro:
2538 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 case Mips::DMULMacro:
2540 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2541 case Mips::LDMacro:
2542 case Mips::SDMacro:
2543 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2544 Inst.getOpcode() == Mips::LDMacro)
2545 ? MER_Fail
2546 : MER_Success;
2547 case Mips::SEQMacro:
2548 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 case Mips::SEQIMacro:
2550 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2551 case Mips::MFTC0: case Mips::MTTC0:
2552 case Mips::MFTGPR: case Mips::MTTGPR:
2553 case Mips::MFTLO: case Mips::MTTLO:
2554 case Mips::MFTHI: case Mips::MTTHI:
2555 case Mips::MFTACX: case Mips::MTTACX:
2556 case Mips::MFTDSP: case Mips::MTTDSP:
2557 case Mips::MFTC1: case Mips::MTTC1:
2558 case Mips::MFTHC1: case Mips::MTTHC1:
2559 case Mips::CFTC1: case Mips::CTTC1:
2560 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2561 }
2562}
2563
2564bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2565 MCStreamer &Out,
2566 const MCSubtargetInfo *STI) {
2567 MipsTargetStreamer &TOut = getTargetStreamer();
2568
2569 // Create a JALR instruction which is going to replace the pseudo-JAL.
2570 MCInst JalrInst;
2571 JalrInst.setLoc(IDLoc);
2572 const MCOperand FirstRegOp = Inst.getOperand(0);
2573 const unsigned Opcode = Inst.getOpcode();
2574
2575 if (Opcode == Mips::JalOneReg) {
2576 // jal $rs => jalr $rs
2577 if (IsCpRestoreSet && inMicroMipsMode()) {
2578 JalrInst.setOpcode(Mips::JALRS16_MM);
2579 JalrInst.addOperand(FirstRegOp);
2580 } else if (inMicroMipsMode()) {
2581 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2582 JalrInst.addOperand(FirstRegOp);
2583 } else {
2584 JalrInst.setOpcode(Mips::JALR);
2585 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2586 JalrInst.addOperand(FirstRegOp);
2587 }
2588 } else if (Opcode == Mips::JalTwoReg) {
2589 // jal $rd, $rs => jalr $rd, $rs
2590 if (IsCpRestoreSet && inMicroMipsMode())
2591 JalrInst.setOpcode(Mips::JALRS_MM);
2592 else
2593 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2594 JalrInst.addOperand(FirstRegOp);
2595 const MCOperand SecondRegOp = Inst.getOperand(1);
2596 JalrInst.addOperand(SecondRegOp);
2597 }
2598 Out.EmitInstruction(JalrInst, *STI);
2599
2600 // If .set reorder is active and branch instruction has a delay slot,
2601 // emit a NOP after it.
2602 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2603 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2604 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2605 STI);
2606
2607 return false;
2608}
2609
2610/// Can the value be represented by a unsigned N-bit value and a shift left?
2611template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2612 unsigned BitNum = findFirstSet(x);
1
Calling 'findFirstSet<unsigned long>'
8
Returning from 'findFirstSet<unsigned long>'
9
'BitNum' initialized to 4294967295
2613
2614 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
10
The result of the right shift is undefined due to shifting by '4294967295', which is greater or equal to the width of type 'uint64_t'
2615}
2616
2617/// Load (or add) an immediate into a register.
2618///
2619/// @param ImmValue The immediate to load.
2620/// @param DstReg The register that will hold the immediate.
2621/// @param SrcReg A register to add to the immediate or Mips::NoRegister
2622/// for a simple initialization.
2623/// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2624/// @param IsAddress True if the immediate represents an address. False if it
2625/// is an integer.
2626/// @param IDLoc Location of the immediate in the source file.
2627bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2628 unsigned SrcReg, bool Is32BitImm,
2629 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2630 const MCSubtargetInfo *STI) {
2631 MipsTargetStreamer &TOut = getTargetStreamer();
2632
2633 if (!Is32BitImm && !isGP64bit()) {
2634 Error(IDLoc, "instruction requires a 64-bit architecture");
2635 return true;
2636 }
2637
2638 if (Is32BitImm) {
2639 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2640 // Sign extend up to 64-bit so that the predicates match the hardware
2641 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2642 // true.
2643 ImmValue = SignExtend64<32>(ImmValue);
2644 } else {
2645 Error(IDLoc, "instruction requires a 32-bit immediate");
2646 return true;
2647 }
2648 }
2649
2650 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2651 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2652
2653 bool UseSrcReg = false;
2654 if (SrcReg != Mips::NoRegister)
2655 UseSrcReg = true;
2656
2657 unsigned TmpReg = DstReg;
2658 if (UseSrcReg &&
2659 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2660 // At this point we need AT to perform the expansions and we exit if it is
2661 // not available.
2662 unsigned ATReg = getATReg(IDLoc);
2663 if (!ATReg)
2664 return true;
2665 TmpReg = ATReg;
2666 }
2667
2668 if (isInt<16>(ImmValue)) {
2669 if (!UseSrcReg)
2670 SrcReg = ZeroReg;
2671
2672 // This doesn't quite follow the usual ABI expectations for N32 but matches
2673 // traditional assembler behaviour. N32 would normally use addiu for both
2674 // integers and addresses.
2675 if (IsAddress && !Is32BitImm) {
2676 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2677 return false;
2678 }
2679
2680 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2681 return false;
2682 }
2683
2684 if (isUInt<16>(ImmValue)) {
2685 unsigned TmpReg = DstReg;
2686 if (SrcReg == DstReg) {
2687 TmpReg = getATReg(IDLoc);
2688 if (!TmpReg)
2689 return true;
2690 }
2691
2692 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2693 if (UseSrcReg)
2694 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2695 return false;
2696 }
2697
2698 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2699 warnIfNoMacro(IDLoc);
2700
2701 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2702 uint16_t Bits15To0 = ImmValue & 0xffff;
2703 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2704 // Traditional behaviour seems to special case this particular value. It's
2705 // not clear why other masks are handled differently.
2706 if (ImmValue == 0xffffffff) {
2707 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2708 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2709 if (UseSrcReg)
2710 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2711 return false;
2712 }
2713
2714 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2715 // upper 32 bits.
2716 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2717 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2718 if (Bits15To0)
2719 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2720 if (UseSrcReg)
2721 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2722 return false;
2723 }
2724
2725 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2726 if (Bits15To0)
2727 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2728 if (UseSrcReg)
2729 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2730 return false;
2731 }
2732
2733 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2734 if (Is32BitImm) {
2735 Error(IDLoc, "instruction requires a 32-bit immediate");
2736 return true;
2737 }
2738
2739 // Traditionally, these immediates are shifted as little as possible and as
2740 // such we align the most significant bit to bit 15 of our temporary.
2741 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2742 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2743 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2744 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2745 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2746 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2747
2748 if (UseSrcReg)
2749 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2750
2751 return false;
2752 }
2753
2754 warnIfNoMacro(IDLoc);
2755
2756 // The remaining case is packed with a sequence of dsll and ori with zeros
2757 // being omitted and any neighbouring dsll's being coalesced.
2758 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2759
2760 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2761 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2762 IDLoc, Out, STI))
2763 return false;
2764
2765 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2766 // skip it and defer the shift to the next chunk.
2767 unsigned ShiftCarriedForwards = 16;
2768 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2769 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2770
2771 if (ImmChunk != 0) {
2772 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2773 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2774 ShiftCarriedForwards = 0;
2775 }
2776
2777 ShiftCarriedForwards += 16;
2778 }
2779 ShiftCarriedForwards -= 16;
2780
2781 // Finish any remaining shifts left by trailing zeros.
2782 if (ShiftCarriedForwards)
2783 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2784
2785 if (UseSrcReg)
2786 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2787
2788 return false;
2789}
2790
2791bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2792 MCStreamer &Out, const MCSubtargetInfo *STI) {
2793 const MCOperand &ImmOp = Inst.getOperand(1);
2794 assert(ImmOp.isImm() && "expected immediate operand kind")((ImmOp.isImm() && "expected immediate operand kind")
? static_cast<void> (0) : __assert_fail ("ImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2794, __PRETTY_FUNCTION__))
;
2795 const MCOperand &DstRegOp = Inst.getOperand(0);
2796 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2796, __PRETTY_FUNCTION__))
;
2797
2798 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2799 Is32BitImm, false, IDLoc, Out, STI))
2800 return true;
2801
2802 return false;
2803}
2804
2805bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2806 const MCOperand &Offset,
2807 bool Is32BitAddress, SMLoc IDLoc,
2808 MCStreamer &Out,
2809 const MCSubtargetInfo *STI) {
2810 // la can't produce a usable address when addresses are 64-bit.
2811 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2812 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2813 // We currently can't do this because we depend on the equality
2814 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2815 Error(IDLoc, "la used to load 64-bit address");
2816 // Continue as if we had 'dla' instead.
2817 Is32BitAddress = false;
2818 return true;
2819 }
2820
2821 // dla requires 64-bit addresses.
2822 if (!Is32BitAddress && !hasMips3()) {
2823 Error(IDLoc, "instruction requires a 64-bit architecture");
2824 return true;
2825 }
2826
2827 if (!Offset.isImm())
2828 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2829 Is32BitAddress, IDLoc, Out, STI);
2830
2831 if (!ABI.ArePtrs64bit()) {
2832 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2833 Is32BitAddress = true;
2834 }
2835
2836 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2837 IDLoc, Out, STI);
2838}
2839
2840bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2841 unsigned DstReg, unsigned SrcReg,
2842 bool Is32BitSym, SMLoc IDLoc,
2843 MCStreamer &Out,
2844 const MCSubtargetInfo *STI) {
2845 // FIXME: These expansions do not respect -mxgot.
2846 MipsTargetStreamer &TOut = getTargetStreamer();
2847 bool UseSrcReg = SrcReg != Mips::NoRegister;
2848 warnIfNoMacro(IDLoc);
2849
2850 if (inPicMode() && ABI.IsO32()) {
2851 MCValue Res;
2852 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2853 Error(IDLoc, "expected relocatable expression");
2854 return true;
2855 }
2856 if (Res.getSymB() != nullptr) {
2857 Error(IDLoc, "expected relocatable expression with only one symbol");
2858 return true;
2859 }
2860
2861 // The case where the result register is $25 is somewhat special. If the
2862 // symbol in the final relocation is external and not modified with a
2863 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2864 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2865 Res.getConstant() == 0 &&
2866 !(Res.getSymA()->getSymbol().isInSection() ||
2867 Res.getSymA()->getSymbol().isTemporary() ||
2868 (Res.getSymA()->getSymbol().isELF() &&
2869 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2870 ELF::STB_LOCAL))) {
2871 const MCExpr *CallExpr =
2872 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2873 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2874 MCOperand::createExpr(CallExpr), IDLoc, STI);
2875 return false;
2876 }
2877
2878 // The remaining cases are:
2879 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2880 // >addiu $tmp, $tmp, %lo(offset)
2881 // >addiu $rd, $tmp, $rs
2882 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2883 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2884 // >addiu $rd, $tmp, $rs
2885 // The addiu's marked with a '>' may be omitted if they are redundant. If
2886 // this happens then the last instruction must use $rd as the result
2887 // register.
2888 const MipsMCExpr *GotExpr =
2889 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2890 const MCExpr *LoExpr = nullptr;
2891 if (Res.getSymA()->getSymbol().isInSection() ||
2892 Res.getSymA()->getSymbol().isTemporary())
2893 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2894 else if (Res.getConstant() != 0) {
2895 // External symbols fully resolve the symbol with just the %got(symbol)
2896 // but we must still account for any offset to the symbol for expressions
2897 // like symbol+8.
2898 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2899 }
2900
2901 unsigned TmpReg = DstReg;
2902 if (UseSrcReg &&
2903 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2904 SrcReg)) {
2905 // If $rs is the same as $rd, we need to use AT.
2906 // If it is not available we exit.
2907 unsigned ATReg = getATReg(IDLoc);
2908 if (!ATReg)
2909 return true;
2910 TmpReg = ATReg;
2911 }
2912
2913 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2914 MCOperand::createExpr(GotExpr), IDLoc, STI);
2915
2916 if (LoExpr)
2917 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2918 IDLoc, STI);
2919
2920 if (UseSrcReg)
2921 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2922
2923 return false;
2924 }
2925
2926 if (inPicMode() && ABI.ArePtrs64bit()) {
2927 MCValue Res;
2928 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2929 Error(IDLoc, "expected relocatable expression");
2930 return true;
2931 }
2932 if (Res.getSymB() != nullptr) {
2933 Error(IDLoc, "expected relocatable expression with only one symbol");
2934 return true;
2935 }
2936
2937 // The case where the result register is $25 is somewhat special. If the
2938 // symbol in the final relocation is external and not modified with a
2939 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2940 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2941 Res.getConstant() == 0 &&
2942 !(Res.getSymA()->getSymbol().isInSection() ||
2943 Res.getSymA()->getSymbol().isTemporary() ||
2944 (Res.getSymA()->getSymbol().isELF() &&
2945 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2946 ELF::STB_LOCAL))) {
2947 const MCExpr *CallExpr =
2948 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2949 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2950 MCOperand::createExpr(CallExpr), IDLoc, STI);
2951 return false;
2952 }
2953
2954 // The remaining cases are:
2955 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2956 // >daddiu $tmp, $tmp, offset
2957 // >daddu $rd, $tmp, $rs
2958 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2959 // this happens then the last instruction must use $rd as the result
2960 // register.
2961 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2962 Res.getSymA(),
2963 getContext());
2964 const MCExpr *LoExpr = nullptr;
2965 if (Res.getConstant() != 0) {
2966 // Symbols fully resolve with just the %got_disp(symbol) but we
2967 // must still account for any offset to the symbol for
2968 // expressions like symbol+8.
2969 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2970
2971 // FIXME: Offsets greater than 16 bits are not yet implemented.
2972 // FIXME: The correct range is a 32-bit sign-extended number.
2973 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2974 Error(IDLoc, "macro instruction uses large offset, which is not "
2975 "currently supported");
2976 return true;
2977 }
2978 }
2979
2980 unsigned TmpReg = DstReg;
2981 if (UseSrcReg &&
2982 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2983 SrcReg)) {
2984 // If $rs is the same as $rd, we need to use AT.
2985 // If it is not available we exit.
2986 unsigned ATReg = getATReg(IDLoc);
2987 if (!ATReg)
2988 return true;
2989 TmpReg = ATReg;
2990 }
2991
2992 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
2993 MCOperand::createExpr(GotExpr), IDLoc, STI);
2994
2995 if (LoExpr)
2996 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2997 IDLoc, STI);
2998
2999 if (UseSrcReg)
3000 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3001
3002 return false;
3003 }
3004
3005 const MipsMCExpr *HiExpr =
3006 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3007 const MipsMCExpr *LoExpr =
3008 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3009
3010 // This is the 64-bit symbol address expansion.
3011 if (ABI.ArePtrs64bit() && isGP64bit()) {
3012 // We need AT for the 64-bit expansion in the cases where the optional
3013 // source register is the destination register and for the superscalar
3014 // scheduled form.
3015 //
3016 // If it is not available we exit if the destination is the same as the
3017 // source register.
3018
3019 const MipsMCExpr *HighestExpr =
3020 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3021 const MipsMCExpr *HigherExpr =
3022 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3023
3024 bool RdRegIsRsReg =
3025 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3026
3027 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3028 unsigned ATReg = getATReg(IDLoc);
3029
3030 // If $rs is the same as $rd:
3031 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3032 // daddiu $at, $at, %higher(sym)
3033 // dsll $at, $at, 16
3034 // daddiu $at, $at, %hi(sym)
3035 // dsll $at, $at, 16
3036 // daddiu $at, $at, %lo(sym)
3037 // daddu $rd, $at, $rd
3038 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3039 STI);
3040 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3041 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3042 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3043 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3044 IDLoc, STI);
3045 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3046 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3047 IDLoc, STI);
3048 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3049
3050 return false;
3051 } else if (canUseATReg() && !RdRegIsRsReg) {
3052 unsigned ATReg = getATReg(IDLoc);
3053
3054 // If the $rs is different from $rd or if $rs isn't specified and we
3055 // have $at available:
3056 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3057 // lui $at, %hi(sym)
3058 // daddiu $rd, $rd, %higher(sym)
3059 // daddiu $at, $at, %lo(sym)
3060 // dsll32 $rd, $rd, 0
3061 // daddu $rd, $rd, $at
3062 // (daddu $rd, $rd, $rs)
3063 //
3064 // Which is preferred for superscalar issue.
3065 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3066 STI);
3067 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3068 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3069 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3070 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3071 IDLoc, STI);
3072 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3073 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3074 if (UseSrcReg)
3075 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3076
3077 return false;
3078 } else if (!canUseATReg() && !RdRegIsRsReg) {
3079 // Otherwise, synthesize the address in the destination register
3080 // serially:
3081 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3082 // daddiu $rd, $rd, %higher(sym)
3083 // dsll $rd, $rd, 16
3084 // daddiu $rd, $rd, %hi(sym)
3085 // dsll $rd, $rd, 16
3086 // daddiu $rd, $rd, %lo(sym)
3087 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3088 STI);
3089 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3090 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3091 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3092 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3093 MCOperand::createExpr(HiExpr), IDLoc, STI);
3094 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3095 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3096 MCOperand::createExpr(LoExpr), IDLoc, STI);
3097 if (UseSrcReg)
3098 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3099
3100 return false;
3101 } else {
3102 // We have a case where SrcReg == DstReg and we don't have $at
3103 // available. We can't expand this case, so error out appropriately.
3104 assert(SrcReg == DstReg && !canUseATReg() &&((SrcReg == DstReg && !canUseATReg() && "Could have expanded dla but didn't?"
) ? static_cast<void> (0) : __assert_fail ("SrcReg == DstReg && !canUseATReg() && \"Could have expanded dla but didn't?\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3105, __PRETTY_FUNCTION__))
3105 "Could have expanded dla but didn't?")((SrcReg == DstReg && !canUseATReg() && "Could have expanded dla but didn't?"
) ? static_cast<void> (0) : __assert_fail ("SrcReg == DstReg && !canUseATReg() && \"Could have expanded dla but didn't?\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3105, __PRETTY_FUNCTION__))
;
3106 reportParseError(IDLoc,
3107 "pseudo-instruction requires $at, which is not available");
3108 return true;
3109 }
3110 }
3111
3112 // And now, the 32-bit symbol address expansion:
3113 // If $rs is the same as $rd:
3114 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3115 // ori $at, $at, %lo(sym)
3116 // addu $rd, $at, $rd
3117 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3118 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3119 // ori $rd, $rd, %lo(sym)
3120 // (addu $rd, $rd, $rs)
3121 unsigned TmpReg = DstReg;
3122 if (UseSrcReg &&
3123 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3124 // If $rs is the same as $rd, we need to use AT.
3125 // If it is not available we exit.
3126 unsigned ATReg = getATReg(IDLoc);
3127 if (!ATReg)
3128 return true;
3129 TmpReg = ATReg;
3130 }
3131
3132 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3133 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3134 IDLoc, STI);
3135
3136 if (UseSrcReg)
3137 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3138 else
3139 assert(((getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg)) ? static_cast<void> (0) : __assert_fail ("getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3140, __PRETTY_FUNCTION__))
3140 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg))((getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg)) ? static_cast<void> (0) : __assert_fail ("getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3140, __PRETTY_FUNCTION__))
;
3141
3142 return false;
3143}
3144
3145// Each double-precision register DO-D15 overlaps with two of the single
3146// precision registers F0-F31. As an example, all of the following hold true:
3147// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3148static unsigned nextReg(unsigned Reg) {
3149 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3150 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3151 switch (Reg) {
3152 default: llvm_unreachable("Unknown register in assembly macro expansion!")::llvm::llvm_unreachable_internal("Unknown register in assembly macro expansion!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3152)
;
3153 case Mips::ZERO: return Mips::AT;
3154 case Mips::AT: return Mips::V0;
3155 case Mips::V0: return Mips::V1;
3156 case Mips::V1: return Mips::A0;
3157 case Mips::A0: return Mips::A1;
3158 case Mips::A1: return Mips::A2;
3159 case Mips::A2: return Mips::A3;
3160 case Mips::A3: return Mips::T0;
3161 case Mips::T0: return Mips::T1;
3162 case Mips::T1: return Mips::T2;
3163 case Mips::T2: return Mips::T3;
3164 case Mips::T3: return Mips::T4;
3165 case Mips::T4: return Mips::T5;
3166 case Mips::T5: return Mips::T6;
3167 case Mips::T6: return Mips::T7;
3168 case Mips::T7: return Mips::S0;
3169 case Mips::S0: return Mips::S1;
3170 case Mips::S1: return Mips::S2;
3171 case Mips::S2: return Mips::S3;
3172 case Mips::S3: return Mips::S4;
3173 case Mips::S4: return Mips::S5;
3174 case Mips::S5: return Mips::S6;
3175 case Mips::S6: return Mips::S7;
3176 case Mips::S7: return Mips::T8;
3177 case Mips::T8: return Mips::T9;
3178 case Mips::T9: return Mips::K0;
3179 case Mips::K0: return Mips::K1;
3180 case Mips::K1: return Mips::GP;
3181 case Mips::GP: return Mips::SP;
3182 case Mips::SP: return Mips::FP;
3183 case Mips::FP: return Mips::RA;
3184 case Mips::RA: return Mips::ZERO;
3185 case Mips::D0: return Mips::F1;
3186 case Mips::D1: return Mips::F3;
3187 case Mips::D2: return Mips::F5;
3188 case Mips::D3: return Mips::F7;
3189 case Mips::D4: return Mips::F9;
3190 case Mips::D5: return Mips::F11;
3191 case Mips::D6: return Mips::F13;
3192 case Mips::D7: return Mips::F15;
3193 case Mips::D8: return Mips::F17;
3194 case Mips::D9: return Mips::F19;
3195 case Mips::D10: return Mips::F21;
3196 case Mips::D11: return Mips::F23;
3197 case Mips::D12: return Mips::F25;
3198 case Mips::D13: return Mips::F27;
3199 case Mips::D14: return Mips::F29;
3200 case Mips::D15: return Mips::F31;
3201 }
3202}
3203
3204// FIXME: This method is too general. In principle we should compute the number
3205// of instructions required to synthesize the immediate inline compared to
3206// synthesizing the address inline and relying on non .text sections.
3207// For static O32 and N32 this may yield a small benefit, for static N64 this is
3208// likely to yield a much larger benefit as we have to synthesize a 64bit
3209// address to load a 64 bit value.
3210bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3211 MCSymbol *Sym) {
3212 unsigned ATReg = getATReg(IDLoc);
3213 if (!ATReg)
3214 return true;
3215
3216 if(IsPicEnabled) {
3217 const MCExpr *GotSym =
3218 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3219 const MipsMCExpr *GotExpr =
3220 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3221
3222 if(isABI_O32() || isABI_N32()) {
3223 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3224 IDLoc, STI);
3225 } else { //isABI_N64()
3226 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3227 IDLoc, STI);
3228 }
3229 } else { //!IsPicEnabled
3230 const MCExpr *HiSym =
3231 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3232 const MipsMCExpr *HiExpr =
3233 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3234
3235 // FIXME: This is technically correct but gives a different result to gas,
3236 // but gas is incomplete there (it has a fixme noting it doesn't work with
3237 // 64-bit addresses).
3238 // FIXME: With -msym32 option, the address expansion for N64 should probably
3239 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3240 // symbol's value is considered sign extended.
3241 if(isABI_O32() || isABI_N32()) {
3242 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3243 } else { //isABI_N64()
3244 const MCExpr *HighestSym =
3245 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3246 const MipsMCExpr *HighestExpr =
3247 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3248 const MCExpr *HigherSym =
3249 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3250 const MipsMCExpr *HigherExpr =
3251 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3252
3253 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3254 STI);
3255 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3256 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3257 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3258 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3259 IDLoc, STI);
3260 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3261 }
3262 }
3263 return false;
3264}
3265
3266bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3267 bool Is64FPU, SMLoc IDLoc,
3268 MCStreamer &Out,
3269 const MCSubtargetInfo *STI) {
3270 MipsTargetStreamer &TOut = getTargetStreamer();
3271 assert(Inst.getNumOperands() == 2 && "Invalid operand count")((Inst.getNumOperands() == 2 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 2 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3271, __PRETTY_FUNCTION__))
;
3272 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3273, __PRETTY_FUNCTION__))
3273 "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3273, __PRETTY_FUNCTION__))
;
3274
3275 unsigned FirstReg = Inst.getOperand(0).getReg();
3276 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3277
3278 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3279 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3280 // exponent field), convert it to double (e.g. 1 to 1.0)
3281 if ((HiImmOp64 & 0x7ff00000) == 0) {
3282 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3283 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3284 }
3285
3286 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3287 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3288
3289 if (IsSingle) {
3290 // Conversion of a double in an uint64_t to a float in a uint32_t,
3291 // retaining the bit pattern of a float.
3292 uint32_t ImmOp32;
3293 double doubleImm = BitsToDouble(ImmOp64);
3294 float tmp_float = static_cast<float>(doubleImm);
3295 ImmOp32 = FloatToBits(tmp_float);
3296
3297 if (IsGPR) {
3298 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3299 Out, STI))
3300 return true;
3301 return false;
3302 } else {
3303 unsigned ATReg = getATReg(IDLoc);
3304 if (!ATReg)
3305 return true;
3306 if (LoImmOp64 == 0) {
3307 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3308 Out, STI))
3309 return true;
3310 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3311 return false;
3312 }
3313
3314 MCSection *CS = getStreamer().getCurrentSectionOnly();
3315 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3316 // where appropriate.
3317 MCSection *ReadOnlySection = getContext().getELFSection(
3318 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3319
3320 MCSymbol *Sym = getContext().createTempSymbol();
3321 const MCExpr *LoSym =
3322 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3323 const MipsMCExpr *LoExpr =
3324 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3325
3326 getStreamer().SwitchSection(ReadOnlySection);
3327 getStreamer().EmitLabel(Sym, IDLoc);
3328 getStreamer().EmitIntValue(ImmOp32, 4);
3329 getStreamer().SwitchSection(CS);
3330
3331 if(emitPartialAddress(TOut, IDLoc, Sym))
3332 return true;
3333 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3334 MCOperand::createExpr(LoExpr), IDLoc, STI);
3335 }
3336 return false;
3337 }
3338
3339 // if(!IsSingle)
3340 unsigned ATReg = getATReg(IDLoc);
3341 if (!ATReg)
3342 return true;
3343
3344 if (IsGPR) {
3345 if (LoImmOp64 == 0) {
3346 if(isABI_N32() || isABI_N64()) {
3347 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3348 IDLoc, Out, STI))
3349 return true;
3350 return false;
3351 } else {
3352 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3353 IDLoc, Out, STI))
3354 return true;
3355
3356 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3357 IDLoc, Out, STI))
3358 return true;
3359 return false;
3360 }
3361 }
3362
3363 MCSection *CS = getStreamer().getCurrentSectionOnly();
3364 MCSection *ReadOnlySection = getContext().getELFSection(
3365 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3366
3367 MCSymbol *Sym = getContext().createTempSymbol();
3368 const MCExpr *LoSym =
3369 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3370 const MipsMCExpr *LoExpr =
3371 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3372
3373 getStreamer().SwitchSection(ReadOnlySection);
3374 getStreamer().EmitLabel(Sym, IDLoc);
3375 getStreamer().EmitIntValue(HiImmOp64, 4);
3376 getStreamer().EmitIntValue(LoImmOp64, 4);
3377 getStreamer().SwitchSection(CS);
3378
3379 if(emitPartialAddress(TOut, IDLoc, Sym))
3380 return true;
3381 if(isABI_N64())
3382 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3383 MCOperand::createExpr(LoExpr), IDLoc, STI);
3384 else
3385 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3386 MCOperand::createExpr(LoExpr), IDLoc, STI);
3387
3388 if(isABI_N32() || isABI_N64())
3389 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3390 else {
3391 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3392 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3393 }
3394 return false;
3395 } else { // if(!IsGPR && !IsSingle)
3396 if ((LoImmOp64 == 0) &&
3397 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3398 // FIXME: In the case where the constant is zero, we can load the
3399 // register directly from the zero register.
3400 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3401 Out, STI))
3402 return true;
3403 if (isABI_N32() || isABI_N64())
3404 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3405 else if (hasMips32r2()) {
3406 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3407 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3408 } else {
3409 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3410 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3411 }
3412 return false;
3413 }
3414
3415 MCSection *CS = getStreamer().getCurrentSectionOnly();
3416 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3417 // where appropriate.
3418 MCSection *ReadOnlySection = getContext().getELFSection(
3419 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3420
3421 MCSymbol *Sym = getContext().createTempSymbol();
3422 const MCExpr *LoSym =
3423 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3424 const MipsMCExpr *LoExpr =
3425 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3426
3427 getStreamer().SwitchSection(ReadOnlySection);
3428 getStreamer().EmitLabel(Sym, IDLoc);
3429 getStreamer().EmitIntValue(HiImmOp64, 4);
3430 getStreamer().EmitIntValue(LoImmOp64, 4);
3431 getStreamer().SwitchSection(CS);
3432
3433 if(emitPartialAddress(TOut, IDLoc, Sym))
3434 return true;
3435 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3436 MCOperand::createExpr(LoExpr), IDLoc, STI);
3437 }
3438 return false;
3439}
3440
3441bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3442 MCStreamer &Out,
3443 const MCSubtargetInfo *STI) {
3444 MipsTargetStreamer &TOut = getTargetStreamer();
3445
3446 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&((getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
"unexpected number of operands") ? static_cast<void> (
0) : __assert_fail ("getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3447, __PRETTY_FUNCTION__))
3447 "unexpected number of operands")((getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
"unexpected number of operands") ? static_cast<void> (
0) : __assert_fail ("getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3447, __PRETTY_FUNCTION__))
;
3448
3449 MCOperand Offset = Inst.getOperand(0);
3450 if (Offset.isExpr()) {
3451 Inst.clear();
3452 Inst.setOpcode(Mips::BEQ_MM);
3453 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3454 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3455 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3456 } else {
3457 assert(Offset.isImm() && "expected immediate operand kind")((Offset.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("Offset.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3457, __PRETTY_FUNCTION__))
;
3458 if (isInt<11>(Offset.getImm())) {
3459 // If offset fits into 11 bits then this instruction becomes microMIPS
3460 // 16-bit unconditional branch instruction.
3461 if (inMicroMipsMode())
3462 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3463 } else {
3464 if (!isInt<17>(Offset.getImm()))
3465 return Error(IDLoc, "branch target out of range");
3466 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3467 return Error(IDLoc, "branch to misaligned address");
3468 Inst.clear();
3469 Inst.setOpcode(Mips::BEQ_MM);
3470 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3471 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3472 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3473 }
3474 }
3475 Out.EmitInstruction(Inst, *STI);
3476
3477 // If .set reorder is active and branch instruction has a delay slot,
3478 // emit a NOP after it.
3479 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3480 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3481 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3482
3483 return false;
3484}
3485
3486bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3487 const MCSubtargetInfo *STI) {
3488 MipsTargetStreamer &TOut = getTargetStreamer();
3489 const MCOperand &DstRegOp = Inst.getOperand(0);
3490 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3490, __PRETTY_FUNCTION__))
;
3491
3492 const MCOperand &ImmOp = Inst.getOperand(1);
3493 assert(ImmOp.isImm() && "expected immediate operand kind")((ImmOp.isImm() && "expected immediate operand kind")
? static_cast<void> (0) : __assert_fail ("ImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3493, __PRETTY_FUNCTION__))
;
3494
3495 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3496 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&(((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && "expected immediate or expression operand"
) ? static_cast<void> (0) : __assert_fail ("(MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && \"expected immediate or expression operand\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3497, __PRETTY_FUNCTION__))
3497 "expected immediate or expression operand")(((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && "expected immediate or expression operand"
) ? static_cast<void> (0) : __assert_fail ("(MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && \"expected immediate or expression operand\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3497, __PRETTY_FUNCTION__))
;
3498
3499 bool IsLikely = false;
3500
3501 unsigned OpCode = 0;
3502 switch(Inst.getOpcode()) {
3503 case Mips::BneImm:
3504 OpCode = Mips::BNE;
3505 break;
3506 case Mips::BeqImm:
3507 OpCode = Mips::BEQ;
3508 break;
3509 case Mips::BEQLImmMacro:
3510 OpCode = Mips::BEQL;
3511 IsLikely = true;
3512 break;
3513 case Mips::BNELImmMacro:
3514 OpCode = Mips::BNEL;
3515 IsLikely = true;
3516 break;
3517 default:
3518 llvm_unreachable("Unknown immediate branch pseudo-instruction.")::llvm::llvm_unreachable_internal("Unknown immediate branch pseudo-instruction."
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3518)
;
3519 break;
3520 }
3521
3522 int64_t ImmValue = ImmOp.getImm();
3523 if (ImmValue == 0) {
3524 if (IsLikely) {
3525 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3526 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3527 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3528 } else
3529 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3530 STI);
3531 } else {
3532 warnIfNoMacro(IDLoc);
3533
3534 unsigned ATReg = getATReg(IDLoc);
3535 if (!ATReg)
3536 return true;
3537
3538 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3539 IDLoc, Out, STI))
3540 return true;
3541
3542 if (IsLikely) {
3543 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3544 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3545 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3546 } else
3547 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3548 }
3549 return false;
3550}
3551
3552void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3553 const MCSubtargetInfo *STI, bool IsLoad) {
3554 const MCOperand &DstRegOp = Inst.getOperand(0);
3555 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3555, __PRETTY_FUNCTION__))
;
3556 const MCOperand &BaseRegOp = Inst.getOperand(1);
3557 assert(BaseRegOp.isReg() && "expected register operand kind")((BaseRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("BaseRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3557, __PRETTY_FUNCTION__))
;
3558 const MCOperand &OffsetOp = Inst.getOperand(2);
3559
3560 MipsTargetStreamer &TOut = getTargetStreamer();
3561 unsigned DstReg = DstRegOp.getReg();
3562 unsigned BaseReg = BaseRegOp.getReg();
3563 unsigned TmpReg = DstReg;
3564
3565 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3566 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3567 unsigned DstRegClassID =
3568 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3569 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3570 (DstRegClassID == Mips::GPR64RegClassID);
3571
3572 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3573 // At this point we need AT to perform the expansions
3574 // and we exit if it is not available.
3575 TmpReg = getATReg(IDLoc);
3576 if (!TmpReg)
3577 return;
3578 }
3579
3580 if (OffsetOp.isImm()) {
3581 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3582 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3583
3584 // If msb of LoOffset is 1(negative number) we must increment
3585 // HiOffset to account for the sign-extension of the low part.
3586 if (LoOffset & 0x8000)
3587 HiOffset += 0x10000;
3588
3589 bool IsLargeOffset = HiOffset != 0;
3590
3591 if (IsLargeOffset) {
3592 bool Is32BitImm = (HiOffset >> 32) == 0;
3593 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3594 IDLoc, Out, STI))
3595 return;
3596 }
3597
3598 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3599 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3600 BaseReg, IDLoc, STI);
3601 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3602 } else {
3603 assert(OffsetOp.isExpr() && "expected expression operand kind")((OffsetOp.isExpr() && "expected expression operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetOp.isExpr() && \"expected expression operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3603, __PRETTY_FUNCTION__))
;
3604 const MCExpr *ExprOffset = OffsetOp.getExpr();
3605 MCOperand LoOperand = MCOperand::createExpr(
3606 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3607 MCOperand HiOperand = MCOperand::createExpr(
3608 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3609
3610 if (IsLoad)
3611 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3612 LoOperand, TmpReg, IDLoc, STI);
3613 else
3614 TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3615 LoOperand, TmpReg, IDLoc, STI);
3616 }
3617}
3618
3619bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3620 MCStreamer &Out,
3621 const MCSubtargetInfo *STI) {
3622 unsigned OpNum = Inst.getNumOperands();
3623 unsigned Opcode = Inst.getOpcode();
3624 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3625
3626 assert(Inst.getOperand(OpNum - 1).isImm() &&((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3628, __PRETTY_FUNCTION__))
3627 Inst.getOperand(OpNum - 2).isReg() &&((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3628, __PRETTY_FUNCTION__))
3628 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.")((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3628, __PRETTY_FUNCTION__))
;
3629
3630 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3631 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3632 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3633 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3634 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3635 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3636 // It can be implemented as SWM16 or LWM16 instruction.
3637 if (inMicroMipsMode() && hasMips32r6())
3638 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3639 else
3640 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3641 }
3642
3643 Inst.setOpcode(NewOpcode);
3644 Out.EmitInstruction(Inst, *STI);
3645 return false;
3646}
3647
3648bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3649 MCStreamer &Out,
3650 const MCSubtargetInfo *STI) {
3651 MipsTargetStreamer &TOut = getTargetStreamer();
3652 bool EmittedNoMacroWarning = false;
3653 unsigned PseudoOpcode = Inst.getOpcode();
3654 unsigned SrcReg = Inst.getOperand(0).getReg();
3655 const MCOperand &TrgOp = Inst.getOperand(1);
3656 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3657
3658 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3659 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3660
3661 unsigned TrgReg;
3662 if (TrgOp.isReg())
3663 TrgReg = TrgOp.getReg();
3664 else if (TrgOp.isImm()) {
3665 warnIfNoMacro(IDLoc);
3666 EmittedNoMacroWarning = true;
3667
3668 TrgReg = getATReg(IDLoc);
3669 if (!TrgReg)
3670 return true;
3671
3672 switch(PseudoOpcode) {
3673 default:
3674 llvm_unreachable("unknown opcode for branch pseudo-instruction")::llvm::llvm_unreachable_internal("unknown opcode for branch pseudo-instruction"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3674)
;
3675 case Mips::BLTImmMacro:
3676 PseudoOpcode = Mips::BLT;
3677 break;
3678 case Mips::BLEImmMacro:
3679 PseudoOpcode = Mips::BLE;
3680 break;
3681 case Mips::BGEImmMacro:
3682 PseudoOpcode = Mips::BGE;
3683 break;
3684 case Mips::BGTImmMacro:
3685 PseudoOpcode = Mips::BGT;
3686 break;
3687 case Mips::BLTUImmMacro:
3688 PseudoOpcode = Mips::BLTU;
3689 break;
3690 case Mips::BLEUImmMacro:
3691 PseudoOpcode = Mips::BLEU;
3692 break;
3693 case Mips::BGEUImmMacro:
3694 PseudoOpcode = Mips::BGEU;
3695 break;
3696 case Mips::BGTUImmMacro:
3697 PseudoOpcode = Mips::BGTU;
3698 break;
3699 case Mips::BLTLImmMacro:
3700 PseudoOpcode = Mips::BLTL;
3701 break;
3702 case Mips::BLELImmMacro:
3703 PseudoOpcode = Mips::BLEL;
3704 break;
3705 case Mips::BGELImmMacro:
3706 PseudoOpcode = Mips::BGEL;
3707 break;
3708 case Mips::BGTLImmMacro:
3709 PseudoOpcode = Mips::BGTL;
3710 break;
3711 case Mips::BLTULImmMacro:
3712 PseudoOpcode = Mips::BLTUL;
3713 break;
3714 case Mips::BLEULImmMacro:
3715 PseudoOpcode = Mips::BLEUL;
3716 break;
3717 case Mips::BGEULImmMacro:
3718 PseudoOpcode = Mips::BGEUL;
3719 break;
3720 case Mips::BGTULImmMacro:
3721 PseudoOpcode = Mips::BGTUL;
3722 break;
3723 }
3724
3725 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3726 false, IDLoc, Out, STI))
3727 return true;
3728 }
3729
3730 switch (PseudoOpcode) {
3731 case Mips::BLT:
3732 case Mips::BLTU:
3733 case Mips::BLTL:
3734 case Mips::BLTUL:
3735 AcceptsEquality = false;
3736 ReverseOrderSLT = false;
3737 IsUnsigned =
3738 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3739 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3740 ZeroSrcOpcode = Mips::BGTZ;
3741 ZeroTrgOpcode = Mips::BLTZ;
3742 break;
3743 case Mips::BLE:
3744 case Mips::BLEU:
3745 case Mips::BLEL:
3746 case Mips::BLEUL:
3747 AcceptsEquality = true;
3748 ReverseOrderSLT = true;
3749 IsUnsigned =
3750 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3751 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3752 ZeroSrcOpcode = Mips::BGEZ;
3753 ZeroTrgOpcode = Mips::BLEZ;
3754 break;
3755 case Mips::BGE:
3756 case Mips::BGEU:
3757 case Mips::BGEL:
3758 case Mips::BGEUL:
3759 AcceptsEquality = true;
3760 ReverseOrderSLT = false;
3761 IsUnsigned =
3762 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3763 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3764 ZeroSrcOpcode = Mips::BLEZ;
3765 ZeroTrgOpcode = Mips::BGEZ;
3766 break;
3767 case Mips::BGT:
3768 case Mips::BGTU:
3769 case Mips::BGTL:
3770 case Mips::BGTUL:
3771 AcceptsEquality = false;
3772 ReverseOrderSLT = true;
3773 IsUnsigned =
3774 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3775 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3776 ZeroSrcOpcode = Mips::BLTZ;
3777 ZeroTrgOpcode = Mips::BGTZ;
3778 break;
3779 default:
3780 llvm_unreachable("unknown opcode for branch pseudo-instruction")::llvm::llvm_unreachable_internal("unknown opcode for branch pseudo-instruction"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3780)
;
3781 }
3782
3783 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3784 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3785 if (IsSrcRegZero && IsTrgRegZero) {
3786 // FIXME: All of these Opcode-specific if's are needed for compatibility
3787 // with GAS' behaviour. However, they may not generate the most efficient
3788 // code in some circumstances.
3789 if (PseudoOpcode == Mips::BLT) {
3790 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3791 IDLoc, STI);
3792 return false;
3793 }
3794 if (PseudoOpcode == Mips::BLE) {
3795 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3796 IDLoc, STI);
3797 Warning(IDLoc, "branch is always taken");
3798 return false;
3799 }
3800 if (PseudoOpcode == Mips::BGE) {
3801 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3802 IDLoc, STI);
3803 Warning(IDLoc, "branch is always taken");
3804 return false;
3805 }
3806 if (PseudoOpcode == Mips::BGT) {
3807 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3808 IDLoc, STI);
3809 return false;
3810 }
3811 if (PseudoOpcode == Mips::BGTU) {
3812 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3813 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3814 return false;
3815 }
3816 if (AcceptsEquality) {
3817 // If both registers are $0 and the pseudo-branch accepts equality, it
3818 // will always be taken, so we emit an unconditional branch.
3819 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3820 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3821 Warning(IDLoc, "branch is always taken");
3822 return false;
3823 }
3824 // If both registers are $0 and the pseudo-branch does not accept
3825 // equality, it will never be taken, so we don't have to emit anything.
3826 return false;
3827 }
3828 if (IsSrcRegZero || IsTrgRegZero) {
3829 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3830 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3831 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3832 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3833 // the pseudo-branch will never be taken, so we don't emit anything.
3834 // This only applies to unsigned pseudo-branches.
3835 return false;
3836 }
3837 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3838 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3839 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3840 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3841 // the pseudo-branch will always be taken, so we emit an unconditional
3842 // branch.
3843 // This only applies to unsigned pseudo-branches.
3844 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3845 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3846 Warning(IDLoc, "branch is always taken");
3847 return false;
3848 }
3849 if (IsUnsigned) {
3850 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3851 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3852 // the pseudo-branch will be taken only when the non-zero register is
3853 // different from 0, so we emit a BNEZ.
3854 //
3855 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3856 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3857 // the pseudo-branch will be taken only when the non-zero register is
3858 // equal to 0, so we emit a BEQZ.
3859 //
3860 // Because only BLEU and BGEU branch on equality, we can use the
3861 // AcceptsEquality variable to decide when to emit the BEQZ.
3862 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3863 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3864 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3865 return false;
3866 }
3867 // If we have a signed pseudo-branch and one of the registers is $0,
3868 // we can use an appropriate compare-to-zero branch. We select which one
3869 // to use in the switch statement above.
3870 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3871 IsSrcRegZero ? TrgReg : SrcReg,
3872 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3873 return false;
3874 }
3875
3876 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3877 // expansions. If it is not available, we return.
3878 unsigned ATRegNum = getATReg(IDLoc);
3879 if (!ATRegNum)
3880 return true;
3881
3882 if (!EmittedNoMacroWarning)
3883 warnIfNoMacro(IDLoc);
3884
3885 // SLT fits well with 2 of our 4 pseudo-branches:
3886 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3887 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3888 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3889 // This is accomplished by using a BNEZ with the result of the SLT.
3890 //
3891 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3892 // and BLE with BGT), so we change the BNEZ into a BEQZ.
3893 // Because only BGE and BLE branch on equality, we can use the
3894 // AcceptsEquality variable to decide when to emit the BEQZ.
3895 // Note that the order of the SLT arguments doesn't change between
3896 // opposites.
3897 //
3898 // The same applies to the unsigned variants, except that SLTu is used
3899 // instead of SLT.
3900 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3901 ReverseOrderSLT ? TrgReg : SrcReg,
3902 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3903
3904 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3905 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3906 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3907 STI);
3908 return false;
3909}
3910
3911// Expand a integer division macro.
3912//
3913// Notably we don't have to emit a warning when encountering $rt as the $zero
3914// register, or 0 as an immediate. processInstruction() has already done that.
3915//
3916// The destination register can only be $zero when expanding (S)DivIMacro or
3917// D(S)DivMacro.
3918
3919bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3920 const MCSubtargetInfo *STI, const bool IsMips64,
3921 const bool Signed) {
3922 MipsTargetStreamer &TOut = getTargetStreamer();
3923
3924 warnIfNoMacro(IDLoc);
3925
3926 const MCOperand &RdRegOp = Inst.getOperand(0);
3927 assert(RdRegOp.isReg() && "expected register operand kind")((RdRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("RdRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3927, __PRETTY_FUNCTION__))
;
3928 unsigned RdReg = RdRegOp.getReg();
3929
3930 const MCOperand &RsRegOp = Inst.getOperand(1);
3931 assert(RsRegOp.isReg() && "expected register operand kind")((RsRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("RsRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3931, __PRETTY_FUNCTION__))
;
3932 unsigned RsReg = RsRegOp.getReg();
3933
3934 unsigned RtReg;
3935 int64_t ImmValue;
3936
3937 const MCOperand &RtOp = Inst.getOperand(2);
3938 assert((RtOp.isReg() || RtOp.isImm()) &&(((RtOp.isReg() || RtOp.isImm()) && "expected register or immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("(RtOp.isReg() || RtOp.isImm()) && \"expected register or immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3939, __PRETTY_FUNCTION__))
3939 "expected register or immediate operand kind")(((RtOp.isReg() || RtOp.isImm()) && "expected register or immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("(RtOp.isReg() || RtOp.isImm()) && \"expected register or immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3939, __PRETTY_FUNCTION__))
;
3940 if (RtOp.isReg())
3941 RtReg = RtOp.getReg();
3942 else
3943 ImmValue = RtOp.getImm();
3944
3945 unsigned DivOp;
3946 unsigned ZeroReg;
3947 unsigned SubOp;
3948
3949 if (IsMips64) {
3950 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3951 ZeroReg = Mips::ZERO_64;
3952 SubOp = Mips::DSUB;
3953 } else {
3954 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3955 ZeroReg = Mips::ZERO;
3956 SubOp = Mips::SUB;
3957 }
3958
3959 bool UseTraps = useTraps();
3960
3961 unsigned Opcode = Inst.getOpcode();
3962 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
3963 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
3964 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
3965 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
3966
3967 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
3968 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
3969 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
3970 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
3971
3972 if (RtOp.isImm()) {
3973 unsigned ATReg = getATReg(IDLoc);
3974 if (!ATReg)
3975 return true;
3976
3977 if (ImmValue == 0) {
3978 if (UseTraps)
3979 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3980 else
3981 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3982 return false;
3983 }
3984
3985 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
3986 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
3987 return false;
3988 } else if (isDiv && ImmValue == 1) {
3989 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3990 return false;
3991 } else if (isDiv && Signed && ImmValue == -1) {
3992 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3993 return false;
3994 } else {
3995 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
3996 false, Inst.getLoc(), Out, STI))
3997 return true;
3998 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
3999 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4000 return false;
4001 }
4002 return true;
4003 }
4004
4005 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4006 // break, insert the trap/break and exit. This gives a different result to
4007 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4008 // are handled equivalently. As the observed behaviour is the same, we're ok.
4009 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4010 if (UseTraps) {
4011 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4012 return false;
4013 }
4014 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4015 return false;
4016 }
4017
4018 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4019 // not expand to macro sequence.
4020 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4021 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4022 return false;
4023 }
4024
4025 // Temporary label for first branch traget
4026 MCContext &Context = TOut.getStreamer().getContext();
4027 MCSymbol *BrTarget;
4028 MCOperand LabelOp;
4029
4030 if (UseTraps) {
4031 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4032 } else {
4033 // Branch to the li instruction.
4034 BrTarget = Context.createTempSymbol();
4035 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4036 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4037 }
4038
4039 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4040
4041 if (!UseTraps)
4042 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4043
4044 if (!Signed) {
4045 if (!UseTraps)
4046 TOut.getStreamer().EmitLabel(BrTarget);
4047
4048 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4049 return false;
4050 }
4051
4052 unsigned ATReg = getATReg(IDLoc);
4053 if (!ATReg)
4054 return true;
4055
4056 if (!UseTraps)
4057 TOut.getStreamer().EmitLabel(BrTarget);
4058
4059 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4060
4061 // Temporary label for the second branch target.
4062 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4063 MCOperand LabelOpEnd =
4064 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4065
4066 // Branch to the mflo instruction.
4067 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4068
4069 if (IsMips64) {
4070 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4071 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4072 } else {
4073 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4074 }
4075
4076 if (UseTraps)
4077 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4078 else {
4079 // Branch to the mflo instruction.
4080 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4081 TOut.emitNop(IDLoc, STI);
4082 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4083 }
4084
4085 TOut.getStreamer().EmitLabel(BrTargetEnd);
4086 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4087 return false;
4088}
4089
4090bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4091 SMLoc IDLoc, MCStreamer &Out,
4092 const MCSubtargetInfo *STI) {
4093 MipsTargetStreamer &TOut = getTargetStreamer();
4094
4095 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4095, __PRETTY_FUNCTION__))
;
4096 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4097, __PRETTY_FUNCTION__))
4097 Inst.getOperand(2).isReg() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4097, __PRETTY_FUNCTION__))
;
4098
4099 unsigned FirstReg = Inst.getOperand(0).getReg();
4100 unsigned SecondReg = Inst.getOperand(1).getReg();
4101 unsigned ThirdReg = Inst.getOperand(2).getReg();
4102
4103 if (hasMips1() && !hasMips2()) {
4104 unsigned ATReg = getATReg(IDLoc);
4105 if (!ATReg)
4106 return true;
4107 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4108 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4109 TOut.emitNop(IDLoc, STI);
4110 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4111 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4112 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4113 TOut.emitNop(IDLoc, STI);
4114 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4115 : Mips::CVT_W_S,
4116 FirstReg, SecondReg, IDLoc, STI);
4117 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4118 TOut.emitNop(IDLoc, STI);
4119 return false;
4120 }
4121
4122 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4123 : Mips::TRUNC_W_S,
4124 FirstReg, SecondReg, IDLoc, STI);
4125
4126 return false;
4127}
4128
4129bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4130 MCStreamer &Out, const MCSubtargetInfo *STI) {
4131 if (hasMips32r6() || hasMips64r6()) {
4132 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4133 }
4134
4135 const MCOperand &DstRegOp = Inst.getOperand(0);
4136 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4136, __PRETTY_FUNCTION__))
;
4137 const MCOperand &SrcRegOp = Inst.getOperand(1);
4138 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4138, __PRETTY_FUNCTION__))
;
4139 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4140 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4140, __PRETTY_FUNCTION__))
;
4141
4142 MipsTargetStreamer &TOut = getTargetStreamer();
4143 unsigned DstReg = DstRegOp.getReg();
4144 unsigned SrcReg = SrcRegOp.getReg();
4145 int64_t OffsetValue = OffsetImmOp.getImm();
4146
4147 // NOTE: We always need AT for ULHU, as it is always used as the source
4148 // register for one of the LBu's.
4149 warnIfNoMacro(IDLoc);
4150 unsigned ATReg = getATReg(IDLoc);
4151 if (!ATReg)
4152 return true;
4153
4154 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4155 if (IsLargeOffset) {
4156 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4157 IDLoc, Out, STI))
4158 return true;
4159 }
4160
4161 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4162 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4163 if (isLittle())
4164 std::swap(FirstOffset, SecondOffset);
4165
4166 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4167 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4168
4169 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4170 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4171
4172 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4173 FirstOffset, IDLoc, STI);
4174 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4175 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4176 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4177
4178 return false;
4179}
4180
4181bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4182 const MCSubtargetInfo *STI) {
4183 if (hasMips32r6() || hasMips64r6()) {
4184 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4185 }
4186
4187 const MCOperand &DstRegOp = Inst.getOperand(0);
4188 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4188, __PRETTY_FUNCTION__))
;
4189 const MCOperand &SrcRegOp = Inst.getOperand(1);
4190 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4190, __PRETTY_FUNCTION__))
;
4191 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4192 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4192, __PRETTY_FUNCTION__))
;
4193
4194 MipsTargetStreamer &TOut = getTargetStreamer();
4195 unsigned DstReg = DstRegOp.getReg();
4196 unsigned SrcReg = SrcRegOp.getReg();
4197 int64_t OffsetValue = OffsetImmOp.getImm();
4198
4199 warnIfNoMacro(IDLoc);
4200 unsigned ATReg = getATReg(IDLoc);
4201 if (!ATReg)
4202 return true;
4203
4204 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4205 if (IsLargeOffset) {
4206 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4207 IDLoc, Out, STI))
4208 return true;
4209 }
4210
4211 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4212 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4213 if (isLittle())
4214 std::swap(FirstOffset, SecondOffset);
4215
4216 if (IsLargeOffset) {
4217 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4218 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4219 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4220 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4221 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4222 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4223 } else {
4224 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4225 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4226 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4227 }
4228
4229 return false;
4230}
4231
4232bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4233 const MCSubtargetInfo *STI) {
4234 if (hasMips32r6() || hasMips64r6()) {
4235 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4236 }
4237
4238 const MCOperand &DstRegOp = Inst.getOperand(0);
4239 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4239, __PRETTY_FUNCTION__))
;
4240 const MCOperand &SrcRegOp = Inst.getOperand(1);
4241 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4241, __PRETTY_FUNCTION__))
;
4242 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4243 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4243, __PRETTY_FUNCTION__))
;
4244
4245 MipsTargetStreamer &TOut = getTargetStreamer();
4246 unsigned DstReg = DstRegOp.getReg();
4247 unsigned SrcReg = SrcRegOp.getReg();
4248 int64_t OffsetValue = OffsetImmOp.getImm();
4249
4250 // Compute left/right load/store offsets.
4251 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4252 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4253 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4254 if (isLittle())
4255 std::swap(LxlOffset, LxrOffset);
4256
4257 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4258 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4259 unsigned TmpReg = SrcReg;
4260 if (IsLargeOffset || DoMove) {
4261 warnIfNoMacro(IDLoc);
4262 TmpReg = getATReg(IDLoc);
4263 if (!TmpReg)
4264 return true;
4265 }
4266
4267 if (IsLargeOffset) {
4268 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4269 IDLoc, Out, STI))
4270 return true;
4271 }
4272
4273 if (DoMove)
4274 std::swap(DstReg, TmpReg);
4275
4276 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4277 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4278 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4279 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4280
4281 if (DoMove)
4282 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4283
4284 return false;
4285}
4286
4287bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4288 MCStreamer &Out,
4289 const MCSubtargetInfo *STI) {
4290 MipsTargetStreamer &TOut = getTargetStreamer();
4291
4292 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4292, __PRETTY_FUNCTION__))
;
4293 assert(Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4295, __PRETTY_FUNCTION__))
4294 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4295, __PRETTY_FUNCTION__))
4295 Inst.getOperand(2).isImm() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4295, __PRETTY_FUNCTION__))
;
4296
4297 unsigned ATReg = Mips::NoRegister;
4298 unsigned FinalDstReg = Mips::NoRegister;
4299 unsigned DstReg = Inst.getOperand(0).getReg();
4300 unsigned SrcReg = Inst.getOperand(1).getReg();
4301 int64_t ImmValue = Inst.getOperand(2).getImm();
4302
4303 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4304
4305 unsigned FinalOpcode = Inst.getOpcode();
4306
4307 if (DstReg == SrcReg) {
4308 ATReg = getATReg(Inst.getLoc());
4309 if (!ATReg)
4310 return true;
4311 FinalDstReg = DstReg;
4312 DstReg = ATReg;
4313 }
4314
4315 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4316 Inst.getLoc(), Out, STI)) {
4317 switch (FinalOpcode) {
4318 default:
4319 llvm_unreachable("unimplemented expansion")::llvm::llvm_unreachable_internal("unimplemented expansion", "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4319)
;
4320 case Mips::ADDi:
4321 FinalOpcode = Mips::ADD;
4322 break;
4323 case Mips::ADDiu:
4324 FinalOpcode = Mips::ADDu;
4325 break;
4326 case Mips::ANDi:
4327 FinalOpcode = Mips::AND;
4328 break;
4329 case Mips::NORImm:
4330 FinalOpcode = Mips::NOR;
4331 break;
4332 case Mips::ORi:
4333 FinalOpcode = Mips::OR;
4334 break;
4335 case Mips::SLTi:
4336 FinalOpcode = Mips::SLT;
4337 break;
4338 case Mips::SLTiu:
4339 FinalOpcode = Mips::SLTu;
4340 break;
4341 case Mips::XORi:
4342 FinalOpcode = Mips::XOR;
4343 break;
4344 case Mips::ADDi_MM:
4345 FinalOpcode = Mips::ADD_MM;
4346 break;
4347 case Mips::ADDiu_MM:
4348 FinalOpcode = Mips::ADDu_MM;
4349 break;
4350 case Mips::ANDi_MM:
4351 FinalOpcode = Mips::AND_MM;
4352 break;
4353 case Mips::ORi_MM:
4354 FinalOpcode = Mips::OR_MM;
4355 break;
4356 case Mips::SLTi_MM:
4357 FinalOpcode = Mips::SLT_MM;
4358 break;
4359 case Mips::SLTiu_MM:
4360 FinalOpcode = Mips::SLTu_MM;
4361 break;
4362 case Mips::XORi_MM:
4363 FinalOpcode = Mips::XOR_MM;
4364 break;
4365 case Mips::ANDi64:
4366 FinalOpcode = Mips::AND64;
4367 break;
4368 case Mips::NORImm64:
4369 FinalOpcode = Mips::NOR64;
4370 break;
4371 case Mips::ORi64:
4372 FinalOpcode = Mips::OR64;
4373 break;
4374 case Mips::SLTImm64:
4375 FinalOpcode = Mips::SLT64;
4376 break;
4377 case Mips::SLTUImm64:
4378 FinalOpcode = Mips::SLTu64;
4379 break;
4380 case Mips::XORi64:
4381 FinalOpcode = Mips::XOR64;
4382 break;
4383 }
4384
4385 if (FinalDstReg == Mips::NoRegister)
4386 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4387 else
4388 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4389 return false;
4390 }
4391 return true;
4392}
4393
4394bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4395 const MCSubtargetInfo *STI) {
4396 MipsTargetStreamer &TOut = getTargetStreamer();
4397 unsigned ATReg = Mips::NoRegister;
4398 unsigned DReg = Inst.getOperand(0).getReg();
4399 unsigned SReg = Inst.getOperand(1).getReg();
4400 unsigned TReg = Inst.getOperand(2).getReg();
4401 unsigned TmpReg = DReg;
4402
4403 unsigned FirstShift = Mips::NOP;
4404 unsigned SecondShift = Mips::NOP;
4405
4406 if (hasMips32r2()) {
4407 if (DReg == SReg) {
4408 TmpReg = getATReg(Inst.getLoc());
4409 if (!TmpReg)
4410 return true;
4411 }
4412
4413 if (Inst.getOpcode() == Mips::ROL) {
4414 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4415 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4416 return false;
4417 }
4418
4419 if (Inst.getOpcode() == Mips::ROR) {
4420 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4421 return false;
4422 }
4423
4424 return true;
4425 }
4426
4427 if (hasMips32()) {
4428 switch (Inst.getOpcode()) {
4429 default:
4430 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4430)
;
4431 case Mips::ROL:
4432 FirstShift = Mips::SRLV;
4433 SecondShift = Mips::SLLV;
4434 break;
4435 case Mips::ROR:
4436 FirstShift = Mips::SLLV;
4437 SecondShift = Mips::SRLV;
4438 break;
4439 }
4440
4441 ATReg = getATReg(Inst.getLoc());
4442 if (!ATReg)
4443 return true;
4444
4445 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4446 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4447 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4448 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4449
4450 return false;
4451 }
4452
4453 return true;
4454}
4455
4456bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4457 MCStreamer &Out,
4458 const MCSubtargetInfo *STI) {
4459 MipsTargetStreamer &TOut = getTargetStreamer();
4460 unsigned ATReg = Mips::NoRegister;
4461 unsigned DReg = Inst.getOperand(0).getReg();
4462 unsigned SReg = Inst.getOperand(1).getReg();
4463 int64_t ImmValue = Inst.getOperand(2).getImm();
4464
4465 unsigned FirstShift = Mips::NOP;
4466 unsigned SecondShift = Mips::NOP;
4467
4468 if (hasMips32r2()) {
4469 if (Inst.getOpcode() == Mips::ROLImm) {
4470 uint64_t MaxShift = 32;
4471 uint64_t ShiftValue = ImmValue;
4472 if (ImmValue != 0)
4473 ShiftValue = MaxShift - ImmValue;
4474 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4475 return false;
4476 }
4477
4478 if (Inst.getOpcode() == Mips::RORImm) {
4479 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4480 return false;
4481 }
4482
4483 return true;
4484 }
4485
4486 if (hasMips32()) {
4487 if (ImmValue == 0) {
4488 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4489 return false;
4490 }
4491
4492 switch (Inst.getOpcode()) {
4493 default:
4494 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4494)
;
4495 case Mips::ROLImm:
4496 FirstShift = Mips::SLL;
4497 SecondShift = Mips::SRL;
4498 break;
4499 case Mips::RORImm:
4500 FirstShift = Mips::SRL;
4501 SecondShift = Mips::SLL;
4502 break;
4503 }
4504
4505 ATReg = getATReg(Inst.getLoc());
4506 if (!ATReg)
4507 return true;
4508
4509 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4510 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4511 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4512
4513 return false;
4514 }
4515
4516 return true;
4517}
4518
4519bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4520 const MCSubtargetInfo *STI) {
4521 MipsTargetStreamer &TOut = getTargetStreamer();
4522 unsigned ATReg = Mips::NoRegister;
4523 unsigned DReg = Inst.getOperand(0).getReg();
4524 unsigned SReg = Inst.getOperand(1).getReg();
4525 unsigned TReg = Inst.getOperand(2).getReg();
4526 unsigned TmpReg = DReg;
4527
4528 unsigned FirstShift = Mips::NOP;
4529 unsigned SecondShift = Mips::NOP;
4530
4531 if (hasMips64r2()) {
4532 if (TmpReg == SReg) {
4533 TmpReg = getATReg(Inst.getLoc());
4534 if (!TmpReg)
4535 return true;
4536 }
4537
4538 if (Inst.getOpcode() == Mips::DROL) {
4539 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4540 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4541 return false;
4542 }
4543
4544 if (Inst.getOpcode() == Mips::DROR) {
4545 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4546 return false;
4547 }
4548
4549 return true;
4550 }
4551
4552 if (hasMips64()) {
4553 switch (Inst.getOpcode()) {
4554 default:
4555 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4555)
;
4556 case Mips::DROL:
4557 FirstShift = Mips::DSRLV;
4558 SecondShift = Mips::DSLLV;
4559 break;
4560 case Mips::DROR:
4561 FirstShift = Mips::DSLLV;
4562 SecondShift = Mips::DSRLV;
4563 break;
4564 }
4565
4566 ATReg = getATReg(Inst.getLoc());
4567 if (!ATReg)
4568 return true;
4569
4570 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4571 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4572 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4573 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4574
4575 return false;
4576 }
4577
4578 return true;
4579}
4580
4581bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4582 MCStreamer &Out,
4583 const MCSubtargetInfo *STI) {
4584 MipsTargetStreamer &TOut = getTargetStreamer();
4585 unsigned ATReg = Mips::NoRegister;
4586 unsigned DReg = Inst.getOperand(0).getReg();
4587 unsigned SReg = Inst.getOperand(1).getReg();
4588 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4589
4590 unsigned FirstShift = Mips::NOP;
4591 unsigned SecondShift = Mips::NOP;
4592
4593 MCInst TmpInst;
4594
4595 if (hasMips64r2()) {
4596 unsigned FinalOpcode = Mips::NOP;
4597 if (ImmValue == 0)
4598 FinalOpcode = Mips::DROTR;
4599 else if (ImmValue % 32 == 0)
4600 FinalOpcode = Mips::DROTR32;
4601 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4602 if (Inst.getOpcode() == Mips::DROLImm)
4603 FinalOpcode = Mips::DROTR32;
4604 else
4605 FinalOpcode = Mips::DROTR;
4606 } else if (ImmValue >= 33) {
4607 if (Inst.getOpcode() == Mips::DROLImm)
4608 FinalOpcode = Mips::DROTR;
4609 else
4610 FinalOpcode = Mips::DROTR32;
4611 }
4612
4613 uint64_t ShiftValue = ImmValue % 32;
4614 if (Inst.getOpcode() == Mips::DROLImm)
4615 ShiftValue = (32 - ImmValue % 32) % 32;
4616
4617 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4618
4619 return false;
4620 }
4621
4622 if (hasMips64()) {
4623 if (ImmValue == 0) {
4624 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4625 return false;
4626 }
4627
4628 switch (Inst.getOpcode()) {
4629 default:
4630 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4630)
;
4631 case Mips::DROLImm:
4632 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4633 FirstShift = Mips::DSLL;
4634 SecondShift = Mips::DSRL32;
4635 }
4636 if (ImmValue == 32) {
4637 FirstShift = Mips::DSLL32;
4638 SecondShift = Mips::DSRL32;
4639 }
4640 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4641 FirstShift = Mips::DSLL32;
4642 SecondShift = Mips::DSRL;
4643 }
4644 break;
4645 case Mips::DRORImm:
4646 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4647 FirstShift = Mips::DSRL;
4648 SecondShift = Mips::DSLL32;
4649 }
4650 if (ImmValue == 32) {
4651 FirstShift = Mips::DSRL32;
4652 SecondShift = Mips::DSLL32;
4653 }
4654 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4655 FirstShift = Mips::DSRL32;
4656 SecondShift = Mips::DSLL;
4657 }
4658 break;
4659 }
4660
4661 ATReg = getATReg(Inst.getLoc());
4662 if (!ATReg)
4663 return true;
4664
4665 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4666 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4667 Inst.getLoc(), STI);
4668 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4669
4670 return false;
4671 }
4672
4673 return true;
4674}
4675
4676bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4677 const MCSubtargetInfo *STI) {
4678 MipsTargetStreamer &TOut = getTargetStreamer();
4679 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4680 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4681
4682 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4683 if (FirstRegOp != SecondRegOp)
4684 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4685 else
4686 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4687 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4688
4689 return false;
4690}
4691
4692bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4693 const MCSubtargetInfo *STI) {
4694 MipsTargetStreamer &TOut = getTargetStreamer();
4695 unsigned ATReg = Mips::NoRegister;
4696 unsigned DstReg = Inst.getOperand(0).getReg();
4697 unsigned SrcReg = Inst.getOperand(1).getReg();
4698 int32_t ImmValue = Inst.getOperand(2).getImm();
4699
4700 ATReg = getATReg(IDLoc);
4701 if (!ATReg)
4702 return true;
4703
4704 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4705 STI);
4706
4707 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4708 SrcReg, ATReg, IDLoc, STI);
4709
4710 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4711
4712 return false;
4713}
4714
4715bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4716 const MCSubtargetInfo *STI) {
4717 MipsTargetStreamer &TOut = getTargetStreamer();
4718 unsigned ATReg = Mips::NoRegister;
4719 unsigned DstReg = Inst.getOperand(0).getReg();
4720 unsigned SrcReg = Inst.getOperand(1).getReg();
4721 unsigned TmpReg = Inst.getOperand(2).getReg();
4722
4723 ATReg = getATReg(Inst.getLoc());
4724 if (!ATReg)
4725 return true;
4726
4727 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4728 SrcReg, TmpReg, IDLoc, STI);
4729
4730 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4731
4732 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4733 DstReg, DstReg, 0x1F, IDLoc, STI);
4734
4735 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4736
4737 if (useTraps()) {
4738 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4739 } else {
4740 MCContext & Context = TOut.getStreamer().getContext();
4741 MCSymbol * BrTarget = Context.createTempSymbol();
4742 MCOperand LabelOp =
4743 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4744
4745 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4746 if (AssemblerOptions.back()->isReorder())
4747 TOut.emitNop(IDLoc, STI);
4748 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4749
4750 TOut.getStreamer().EmitLabel(BrTarget);
4751 }
4752 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4753
4754 return false;
4755}
4756
4757bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4758 const MCSubtargetInfo *STI) {
4759 MipsTargetStreamer &TOut = getTargetStreamer();
4760 unsigned ATReg = Mips::NoRegister;
4761 unsigned DstReg = Inst.getOperand(0).getReg();
4762 unsigned SrcReg = Inst.getOperand(1).getReg();
4763 unsigned TmpReg = Inst.getOperand(2).getReg();
4764
4765 ATReg = getATReg(IDLoc);
4766 if (!ATReg)
4767 return true;
4768
4769 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4770 SrcReg, TmpReg, IDLoc, STI);
4771
4772 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4773 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4774 if (useTraps()) {
4775 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4776 } else {
4777 MCContext & Context = TOut.getStreamer().getContext();
4778 MCSymbol * BrTarget = Context.createTempSymbol();
4779 MCOperand LabelOp =
4780 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4781
4782 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4783 if (AssemblerOptions.back()->isReorder())
4784 TOut.emitNop(IDLoc, STI);
4785 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4786
4787 TOut.getStreamer().EmitLabel(BrTarget);
4788 }
4789
4790 return false;
4791}
4792
4793bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4794 const MCSubtargetInfo *STI) {
4795 MipsTargetStreamer &TOut = getTargetStreamer();
4796 unsigned DstReg = Inst.getOperand(0).getReg();
4797 unsigned SrcReg = Inst.getOperand(1).getReg();
4798 unsigned TmpReg = Inst.getOperand(2).getReg();
4799
4800 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4801 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4802
4803 return false;
4804}
4805
4806// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4807// lw $<reg+1>>, offset+4($reg2)'
4808// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4809// sw $<reg+1>>, offset+4($reg2)'
4810// for O32.
4811bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4812 MCStreamer &Out,
4813 const MCSubtargetInfo *STI,
4814 bool IsLoad) {
4815 if (!isABI_O32())
4816 return true;
4817
4818 warnIfNoMacro(IDLoc);
4819
4820 MipsTargetStreamer &TOut = getTargetStreamer();
4821 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4822 unsigned FirstReg = Inst.getOperand(0).getReg();
4823 unsigned SecondReg = nextReg(FirstReg);
4824 unsigned BaseReg = Inst.getOperand(1).getReg();
4825 if (!SecondReg)
4826 return true;
4827
4828 warnIfRegIndexIsAT(FirstReg, IDLoc);
4829
4830 assert(Inst.getOperand(2).isImm() &&((Inst.getOperand(2).isImm() && "Offset for load macro is not immediate!"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && \"Offset for load macro is not immediate!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4831, __PRETTY_FUNCTION__))
4831 "Offset for load macro is not immediate!")((Inst.getOperand(2).isImm() && "Offset for load macro is not immediate!"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && \"Offset for load macro is not immediate!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4831, __PRETTY_FUNCTION__))
;
4832
4833 MCOperand &FirstOffset = Inst.getOperand(2);
4834 signed NextOffset = FirstOffset.getImm() + 4;
4835 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4836
4837 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4838 return true;
4839
4840 // For loads, clobber the base register with the second load instead of the
4841 // first if the BaseReg == FirstReg.
4842 if (FirstReg != BaseReg || !IsLoad) {
4843 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4844 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4845 } else {
4846 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4847 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4848 }
4849
4850 return false;
4851}
4852
4853bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4854 const MCSubtargetInfo *STI) {
4855
4856 warnIfNoMacro(IDLoc);
4857 MipsTargetStreamer &TOut = getTargetStreamer();
4858
4859 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4860 Inst.getOperand(2).getReg() != Mips::ZERO) {
4861 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4862 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4863 IDLoc, STI);
4864 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4865 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4866 return false;
4867 }
4868
4869 unsigned Reg = 0;
4870 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4871 Reg = Inst.getOperand(2).getReg();
4872 } else {
4873 Reg = Inst.getOperand(1).getReg();
4874 }
4875 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4876 return false;
4877}
4878
4879bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4880 const MCSubtargetInfo *STI) {
4881 warnIfNoMacro(IDLoc);
4882 MipsTargetStreamer &TOut = getTargetStreamer();
4883
4884 unsigned Opc;
4885 int64_t Imm = Inst.getOperand(2).getImm();
4886 unsigned Reg = Inst.getOperand(1).getReg();
4887
4888 if (Imm == 0) {
4889 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4890 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4891 return false;
4892 } else {
4893
4894 if (Reg == Mips::ZERO) {
4895 Warning(IDLoc, "comparison is always false");
4896 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4897 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4898 return false;
4899 }
4900
4901 if (Imm > -0x8000 && Imm < 0) {
4902 Imm = -Imm;
4903 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4904 } else {
4905 Opc = Mips::XORi;
4906 }
4907 }
4908 if (!isUInt<16>(Imm)) {
4909 unsigned ATReg = getATReg(IDLoc);
4910 if (!ATReg)
4911 return true;
4912
4913 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4914 Out, STI))
4915 return true;
4916
4917 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4918 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4919 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4920 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4921 return false;
4922 }
4923
4924 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4925 Imm, IDLoc, STI);
4926 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4927 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4928 return false;
4929}
4930
4931// Map the DSP accumulator and control register to the corresponding gpr
4932// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
4933// do not map the DSP registers contigously to gpr registers.
4934static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
4935 switch (Inst.getOpcode()) {
4936 case Mips::MFTLO:
4937 case Mips::MTTLO:
4938 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4939 case Mips::AC0:
4940 return Mips::ZERO;
4941 case Mips::AC1:
4942 return Mips::A0;
4943 case Mips::AC2:
4944 return Mips::T0;
4945 case Mips::AC3:
4946 return Mips::T4;
4947 default:
4948 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4948)
;
4949 }
4950 case Mips::MFTHI:
4951 case Mips::MTTHI:
4952 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4953 case Mips::AC0:
4954 return Mips::AT;
4955 case Mips::AC1:
4956 return Mips::A1;
4957 case Mips::AC2:
4958 return Mips::T1;
4959 case Mips::AC3:
4960 return Mips::T5;
4961 default:
4962 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4962)
;
4963 }
4964 case Mips::MFTACX:
4965 case Mips::MTTACX:
4966 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4967 case Mips::AC0:
4968 return Mips::V0;
4969 case Mips::AC1:
4970 return Mips::A2;
4971 case Mips::AC2:
4972 return Mips::T2;
4973 case Mips::AC3:
4974 return Mips::T6;
4975 default:
4976 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4976)
;
4977 }
4978 case Mips::MFTDSP:
4979 case Mips::MTTDSP:
4980 return Mips::S0;
4981 default:
4982 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!")::llvm::llvm_unreachable_internal("Unknown instruction for 'mttr' dsp alias!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4982)
;
4983 }
4984}
4985
4986// Map the floating point register operand to the corresponding register
4987// operand.
4988static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
4989 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
4990 case Mips::F0: return Mips::ZERO;
4991 case Mips::F1: return Mips::AT;
4992 case Mips::F2: return Mips::V0;
4993 case Mips::F3: return Mips::V1;
4994 case Mips::F4: return Mips::A0;
4995 case Mips::F5: return Mips::A1;
4996 case Mips::F6: return Mips::A2;
4997 case Mips::F7: return Mips::A3;
4998 case Mips::F8: return Mips::T0;
4999 case Mips::F9: return Mips::T1;
5000 case Mips::F10: return Mips::T2;
5001 case Mips::F11: return Mips::T3;
5002 case Mips::F12: return Mips::T4;
5003 case Mips::F13: return Mips::T5;
5004 case Mips::F14: return Mips::T6;
5005 case Mips::F15: return Mips::T7;
5006 case Mips::F16: return Mips::S0;
5007 case Mips::F17: return Mips::S1;
5008 case Mips::F18: return Mips::S2;
5009 case Mips::F19: return Mips::S3;
5010 case Mips::F20: return Mips::S4;
5011 case Mips::F21: return Mips::S5;
5012 case Mips::F22: return Mips::S6;
5013 case Mips::F23: return Mips::S7;
5014 case Mips::F24: return Mips::T8;
5015 case Mips::F25: return Mips::T9;
5016 case Mips::F26: return Mips::K0;
5017 case Mips::F27: return Mips::K1;
5018 case Mips::F28: return Mips::GP;
5019 case Mips::F29: return Mips::SP;
5020 case Mips::F30: return Mips::FP;
5021 case Mips::F31: return Mips::RA;
5022 default: llvm_unreachable("Unknown register for mttc1 alias!")::llvm::llvm_unreachable_internal("Unknown register for mttc1 alias!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5022)
;
5023 }
5024}
5025
5026// Map the coprocessor operand the corresponding gpr register operand.
5027static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5028 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5029 case Mips::COP00: return Mips::ZERO;
5030 case Mips::COP01: return Mips::AT;
5031 case Mips::COP02: return Mips::V0;
5032 case Mips::COP03: return Mips::V1;
5033 case Mips::COP04: return Mips::A0;
5034 case Mips::COP05: return Mips::A1;
5035 case Mips::COP06: return Mips::A2;
5036 case Mips::COP07: return Mips::A3;
5037 case Mips::COP08: return Mips::T0;
5038 case Mips::COP09: return Mips::T1;
5039 case Mips::COP010: return Mips::T2;
5040 case Mips::COP011: return Mips::T3;
5041 case Mips::COP012: return Mips::T4;
5042 case Mips::COP013: return Mips::T5;
5043 case Mips::COP014: return Mips::T6;
5044 case Mips::COP015: return Mips::T7;
5045 case Mips::COP016: return Mips::S0;
5046 case Mips::COP017: return Mips::S1;
5047 case Mips::COP018: return Mips::S2;
5048 case Mips::COP019: return Mips::S3;
5049 case Mips::COP020: return Mips::S4;
5050 case Mips::COP021: return Mips::S5;
5051 case Mips::COP022: return Mips::S6;
5052 case Mips::COP023: return Mips::S7;
5053 case Mips::COP024: return Mips::T8;
5054 case Mips::COP025: return Mips::T9;
5055 case Mips::COP026: return Mips::K0;
5056 case Mips::COP027: return Mips::K1;
5057 case Mips::COP028: return Mips::GP;
5058 case Mips::COP029: return Mips::SP;
5059 case Mips::COP030: return Mips::FP;
5060 case Mips::COP031: return Mips::RA;
5061 default: llvm_unreachable("Unknown register for mttc0 alias!")::llvm::llvm_unreachable_internal("Unknown register for mttc0 alias!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5061)
;
5062 }
5063}
5064
5065/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5066/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5067bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5068 const MCSubtargetInfo *STI) {
5069 MipsTargetStreamer &TOut = getTargetStreamer();
5070 unsigned rd = 0;
5071 unsigned u = 1;
5072 unsigned sel = 0;
5073 unsigned h = 0;
5074 bool IsMFTR = false;
5075 switch (Inst.getOpcode()) {
5076 case Mips::MFTC0:
5077 IsMFTR = true;
5078 LLVM_FALLTHROUGH[[clang::fallthrough]];
5079 case Mips::MTTC0:
5080 u = 0;
5081 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5082 sel = Inst.getOperand(2).getImm();
5083 break;
5084 case Mips::MFTGPR:
5085 IsMFTR = true;
5086 LLVM_FALLTHROUGH[[clang::fallthrough]];
5087 case Mips::MTTGPR:
5088 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5089 break;
5090 case Mips::MFTLO:
5091 case Mips::MFTHI:
5092 case Mips::MFTACX:
5093 case Mips::MFTDSP:
5094 IsMFTR = true;
5095 LLVM_FALLTHROUGH[[clang::fallthrough]];
5096 case Mips::MTTLO:
5097 case Mips::MTTHI:
5098 case Mips::MTTACX:
5099 case Mips::MTTDSP:
5100 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5101 sel = 1;
5102 break;
5103 case Mips::MFTHC1:
5104 h = 1;
5105 LLVM_FALLTHROUGH[[clang::fallthrough]];
5106 case Mips::MFTC1:
5107 IsMFTR = true;
5108 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5109 sel = 2;
5110 break;
5111 case Mips::MTTHC1:
5112 h = 1;
5113 LLVM_FALLTHROUGH[[clang::fallthrough]];
5114 case Mips::MTTC1:
5115 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5116 sel = 2;
5117 break;
5118 case Mips::CFTC1:
5119 IsMFTR = true;
5120 LLVM_FALLTHROUGH[[clang::fallthrough]];
5121 case Mips::CTTC1:
5122 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5123 sel = 3;
5124 break;
5125 }
5126 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5127 unsigned Op1 =
5128 IsMFTR ? rd
5129 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5130 : Inst.getOperand(0).getReg());
5131
5132 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5133 STI);
5134 return false;
5135}
5136
5137unsigned
5138MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5139 const OperandVector &Operands) {
5140 switch (Inst.getOpcode()) {
5141 default:
5142 return Match_Success;
5143 case Mips::DATI:
5144 case Mips::DAHI:
5145 if (static_cast<MipsOperand &>(*Operands[1])
5146 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5147 return Match_Success;
5148 return Match_RequiresSameSrcAndDst;
5149 }
5150}
5151
5152unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5153 switch (Inst.getOpcode()) {
5154 // As described by the MIPSR6 spec, daui must not use the zero operand for
5155 // its source operand.
5156 case Mips::DAUI:
5157 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5158 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5159 return Match_RequiresNoZeroRegister;
5160 return Match_Success;
5161 // As described by the Mips32r2 spec, the registers Rd and Rs for
5162 // jalr.hb must be different.
5163 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5164 // and registers Rd and Base for microMIPS lwp instruction
5165 case Mips::JALR_HB:
5166 case Mips::JALR_HB64:
5167 case Mips::JALRC_HB_MMR6:
5168 case Mips::JALRC_MMR6:
5169 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5170 return Match_RequiresDifferentSrcAndDst;
5171 return Match_Success;
5172 case Mips::LWP_MM:
5173 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5174 return Match_RequiresDifferentSrcAndDst;
5175 return Match_Success;
5176 case Mips::SYNC:
5177 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5178 return Match_NonZeroOperandForSync;
5179 return Match_Success;
5180 case Mips::MFC0:
5181 case Mips::MTC0:
5182 case Mips::MTC2:
5183 case Mips::MFC2:
5184 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5185 return Match_NonZeroOperandForMTCX;
5186 return Match_Success;
5187 // As described the MIPSR6 spec, the compact branches that compare registers
5188 // must:
5189 // a) Not use the zero register.
5190 // b) Not use the same register twice.
5191 // c) rs < rt for bnec, beqc.
5192 // NB: For this case, the encoding will swap the operands as their
5193 // ordering doesn't matter. GAS performs this transformation too.
5194 // Hence, that constraint does not have to be enforced.
5195 //
5196 // The compact branches that branch iff the signed addition of two registers
5197 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5198 // operand swapping. They do not have restriction of using the zero register.
5199 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5200 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5201 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5202 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5203 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5204 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5205 case Mips::BLEZC64:
5206 case Mips::BGEZC64:
5207 case Mips::BGTZC64:
5208 case Mips::BLTZC64:
5209 case Mips::BEQZC64:
5210 case Mips::BNEZC64:
5211 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5212 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5213 return Match_RequiresNoZeroRegister;
5214 return Match_Success;
5215 case Mips::BGEC: case Mips::BGEC_MMR6:
5216 case Mips::BLTC: case Mips::BLTC_MMR6:
5217 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5218 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5219 case Mips::BEQC: case Mips::BEQC_MMR6:
5220 case Mips::BNEC: case Mips::BNEC_MMR6:
5221 case Mips::BGEC64:
5222 case Mips::BLTC64:
5223 case Mips::BGEUC64:
5224 case Mips::BLTUC64:
5225 case Mips::BEQC64:
5226 case Mips::BNEC64:
5227 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5228 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5229 return Match_RequiresNoZeroRegister;
5230 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5231 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5232 return Match_RequiresNoZeroRegister;
5233 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5234 return Match_RequiresDifferentOperands;
5235 return Match_Success;
5236 case Mips::DINS: {
5237 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dins!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dins!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5238, __PRETTY_FUNCTION__))
5238 "Operands must be immediates for dins!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dins!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dins!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5238, __PRETTY_FUNCTION__))
;
5239 const signed Pos = Inst.getOperand(2).getImm();
5240 const signed Size = Inst.getOperand(3).getImm();
5241 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5242 return Match_RequiresPosSizeRange0_32;
5243 return Match_Success;
5244 }
5245 case Mips::DINSM:
5246 case Mips::DINSU: {
5247 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dinsm/dinsu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dinsm/dinsu!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5248, __PRETTY_FUNCTION__))
5248 "Operands must be immediates for dinsm/dinsu!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dinsm/dinsu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dinsm/dinsu!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5248, __PRETTY_FUNCTION__))
;
5249 const signed Pos = Inst.getOperand(2).getImm();
5250 const signed Size = Inst.getOperand(3).getImm();
5251 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5252 return Match_RequiresPosSizeRange33_64;
5253 return Match_Success;
5254 }
5255 case Mips::DEXT: {
5256 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for DEXTM!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for DEXTM!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5257, __PRETTY_FUNCTION__))
5257 "Operands must be immediates for DEXTM!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for DEXTM!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for DEXTM!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5257, __PRETTY_FUNCTION__))
;
5258 const signed Pos = Inst.getOperand(2).getImm();
5259 const signed Size = Inst.getOperand(3).getImm();
5260 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5261 return Match_RequiresPosSizeUImm6;
5262 return Match_Success;
5263 }
5264 case Mips::DEXTM:
5265 case Mips::DEXTU: {
5266 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dextm/dextu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dextm/dextu!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5267, __PRETTY_FUNCTION__))
5267 "Operands must be immediates for dextm/dextu!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dextm/dextu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dextm/dextu!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5267, __PRETTY_FUNCTION__))
;
5268 const signed Pos = Inst.getOperand(2).getImm();
5269 const signed Size = Inst.getOperand(3).getImm();
5270 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5271 return Match_RequiresPosSizeRange33_64;
5272 return Match_Success;
5273 }
5274 case Mips::CRC32B: case Mips::CRC32CB:
5275 case Mips::CRC32H: case Mips::CRC32CH:
5276 case Mips::CRC32W: case Mips::CRC32CW:
5277 case Mips::CRC32D: case Mips::CRC32CD:
5278 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5279 return Match_RequiresSameSrcAndDst;
5280 return Match_Success;
5281 }
5282
5283 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5284 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5285 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5286 return Match_NoFCCRegisterForCurrentISA;
5287
5288 return Match_Success;
5289
5290}
5291
5292static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5293 uint64_t ErrorInfo) {
5294 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5295 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5296 if (ErrorLoc == SMLoc())
5297 return Loc;
5298 return ErrorLoc;
5299 }
5300 return Loc;
5301}
5302
5303bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5304 OperandVector &Operands,
5305 MCStreamer &Out,
5306 uint64_t &ErrorInfo,
5307 bool MatchingInlineAsm) {
5308 MCInst Inst;
5309 unsigned MatchResult =
5310 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5311
5312 switch (MatchResult) {
5313 case Match_Success:
5314 if (processInstruction(Inst, IDLoc, Out, STI))
5315 return true;
5316 return false;
5317 case Match_MissingFeature:
5318 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5319 return true;
5320 case Match_InvalidOperand: {
5321 SMLoc ErrorLoc = IDLoc;
5322 if (ErrorInfo != ~0ULL) {
5323 if (ErrorInfo >= Operands.size())
5324 return Error(IDLoc, "too few operands for instruction");
5325
5326 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5327 if (ErrorLoc == SMLoc())
5328 ErrorLoc = IDLoc;
5329 }
5330
5331 return Error(ErrorLoc, "invalid operand for instruction");
5332 }
5333 case Match_NonZeroOperandForSync:
5334 return Error(IDLoc,
5335 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5336 case Match_NonZeroOperandForMTCX:
5337 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5338 case Match_MnemonicFail:
5339 return Error(IDLoc, "invalid instruction");
5340 case Match_RequiresDifferentSrcAndDst:
5341 return Error(IDLoc, "source and destination must be different");
5342 case Match_RequiresDifferentOperands:
5343 return Error(IDLoc, "registers must be different");
5344 case Match_RequiresNoZeroRegister:
5345 return Error(IDLoc, "invalid operand ($zero) for instruction");
5346 case Match_RequiresSameSrcAndDst:
5347 return Error(IDLoc, "source and destination must match");
5348 case Match_NoFCCRegisterForCurrentISA:
5349 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5350 "non-zero fcc register doesn't exist in current ISA level");
5351 case Match_Immz:
5352 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5353 case Match_UImm1_0:
5354 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5355 "expected 1-bit unsigned immediate");
5356 case Match_UImm2_0:
5357 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5358 "expected 2-bit unsigned immediate");
5359 case Match_UImm2_1:
5360 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5361 "expected immediate in range 1 .. 4");
5362 case Match_UImm3_0:
5363 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5364 "expected 3-bit unsigned immediate");
5365 case Match_UImm4_0:
5366 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5367 "expected 4-bit unsigned immediate");
5368 case Match_SImm4_0:
5369 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5370 "expected 4-bit signed immediate");
5371 case Match_UImm5_0:
5372 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5373 "expected 5-bit unsigned immediate");
5374 case Match_SImm5_0:
5375 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5376 "expected 5-bit signed immediate");
5377 case Match_UImm5_1:
5378 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5379 "expected immediate in range 1 .. 32");
5380 case Match_UImm5_32:
5381 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5382 "expected immediate in range 32 .. 63");
5383 case Match_UImm5_33:
5384 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5385 "expected immediate in range 33 .. 64");
5386 case Match_UImm5_0_Report_UImm6:
5387 // This is used on UImm5 operands that have a corresponding UImm5_32
5388 // operand to avoid confusing the user.
5389 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5390 "expected 6-bit unsigned immediate");
5391 case Match_UImm5_Lsl2:
5392 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5393 "expected both 7-bit unsigned immediate and multiple of 4");
5394 case Match_UImmRange2_64:
5395 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5396 "expected immediate in range 2 .. 64");
5397 case Match_UImm6_0:
5398 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5399 "expected 6-bit unsigned immediate");
5400 case Match_UImm6_Lsl2:
5401 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5402 "expected both 8-bit unsigned immediate and multiple of 4");
5403 case Match_SImm6_0:
5404 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5405 "expected 6-bit signed immediate");
5406 case Match_UImm7_0:
5407 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5408 "expected 7-bit unsigned immediate");
5409 case Match_UImm7_N1:
5410 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5411 "expected immediate in range -1 .. 126");
5412 case Match_SImm7_Lsl2:
5413 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5414 "expected both 9-bit signed immediate and multiple of 4");
5415 case Match_UImm8_0:
5416 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5417 "expected 8-bit unsigned immediate");
5418 case Match_UImm10_0:
5419 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5420 "expected 10-bit unsigned immediate");
5421 case Match_SImm10_0:
5422 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5423 "expected 10-bit signed immediate");
5424 case Match_SImm11_0:
5425 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5426 "expected 11-bit signed immediate");
5427 case Match_UImm16:
5428 case Match_UImm16_Relaxed:
5429 case Match_UImm16_AltRelaxed:
5430 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5431 "expected 16-bit unsigned immediate");
5432 case Match_SImm16:
5433 case Match_SImm16_Relaxed:
5434 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5435 "expected 16-bit signed immediate");
5436 case Match_SImm19_Lsl2:
5437 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5438 "expected both 19-bit signed immediate and multiple of 4");
5439 case Match_UImm20_0:
5440 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5441 "expected 20-bit unsigned immediate");
5442 case Match_UImm26_0:
5443 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5444 "expected 26-bit unsigned immediate");
5445 case Match_SImm32:
5446 case Match_SImm32_Relaxed:
5447 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5448 "expected 32-bit signed immediate");
5449 case Match_UImm32_Coerced:
5450 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5451 "expected 32-bit immediate");
5452 case Match_MemSImm9:
5453 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5454 "expected memory with 9-bit signed offset");
5455 case Match_MemSImm10:
5456 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5457 "expected memory with 10-bit signed offset");
5458 case Match_MemSImm10Lsl1:
5459 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5460 "expected memory with 11-bit signed offset and multiple of 2");
5461 case Match_MemSImm10Lsl2:
5462 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5463 "expected memory with 12-bit signed offset and multiple of 4");
5464 case Match_MemSImm10Lsl3:
5465 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5466 "expected memory with 13-bit signed offset and multiple of 8");
5467 case Match_MemSImm11:
5468 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5469 "expected memory with 11-bit signed offset");
5470 case Match_MemSImm12:
5471 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5472 "expected memory with 12-bit signed offset");
5473 case Match_MemSImm16:
5474 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5475 "expected memory with 16-bit signed offset");
5476 case Match_MemSImmPtr:
5477 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5478 "expected memory with 32-bit signed offset");
5479 case Match_RequiresPosSizeRange0_32: {
5480 SMLoc ErrorStart = Operands[3]->getStartLoc();
5481 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5482 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5483 SMRange(ErrorStart, ErrorEnd));
5484 }
5485 case Match_RequiresPosSizeUImm6: {
5486 SMLoc ErrorStart = Operands[3]->getStartLoc();
5487 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5488 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5489 SMRange(ErrorStart, ErrorEnd));
5490 }
5491 case Match_RequiresPosSizeRange33_64: {
5492 SMLoc ErrorStart = Operands[3]->getStartLoc();
5493 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5494 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5495 SMRange(ErrorStart, ErrorEnd));
5496 }
5497 }
5498
5499 llvm_unreachable("Implement any new match types added!")::llvm::llvm_unreachable_internal("Implement any new match types added!"
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5499)
;
5500}
5501
5502void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5503 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5504 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5505 ") without \".set noat\"");
5506}
5507
5508void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5509 if (!AssemblerOptions.back()->isMacro())
5510 Warning(Loc, "macro instruction expanded into multiple instructions");
5511}
5512
5513void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5514 const OperandVector &Operands) {
5515 assert((((Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips
::SWP_MM) && "Unexpected instruction!") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) && \"Unexpected instruction!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5517, __PRETTY_FUNCTION__))
5516 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&(((Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips
::SWP_MM) && "Unexpected instruction!") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) && \"Unexpected instruction!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5517, __PRETTY_FUNCTION__))
5517 "Unexpected instruction!")(((Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips
::SWP_MM) && "Unexpected instruction!") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) && \"Unexpected instruction!\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5517, __PRETTY_FUNCTION__))
;
5518 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5519 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5520 Inst.addOperand(MCOperand::createReg(NextReg));
5521 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5522}
5523
5524void
5525MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5526 SMRange Range, bool ShowColors) {
5527 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5528 Range, SMFixIt(Range, FixMsg),
5529 ShowColors);
5530}
5531
5532int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5533 int CC;
5534
5535 CC = StringSwitch<unsigned>(Name)
5536 .Case("zero", 0)
5537 .Cases("at", "AT", 1)
5538 .Case("a0", 4)
5539 .Case("a1", 5)
5540 .Case("a2", 6)
5541 .Case("a3", 7)
5542 .Case("v0", 2)
5543 .Case("v1", 3)
5544 .Case("s0", 16)
5545 .Case("s1", 17)
5546 .Case("s2", 18)
5547 .Case("s3", 19)
5548 .Case("s4", 20)
5549 .Case("s5", 21)
5550 .Case("s6", 22)
5551 .Case("s7", 23)
5552 .Case("k0", 26)
5553 .Case("k1", 27)
5554 .Case("gp", 28)
5555 .Case("sp", 29)
5556 .Case("fp", 30)
5557 .Case("s8", 30)
5558 .Case("ra", 31)
5559 .Case("t0", 8)
5560 .Case("t1", 9)
5561 .Case("t2", 10)
5562 .Case("t3", 11)
5563 .Case("t4", 12)
5564 .Case("t5", 13)
5565 .Case("t6", 14)
5566 .Case("t7", 15)
5567 .Case("t8", 24)
5568 .Case("t9", 25)
5569 .Default(-1);
5570
5571 if (!(isABI_N32() || isABI_N64()))
5572 return CC;
5573
5574 if (12 <= CC && CC <= 15) {
5575 // Name is one of t4-t7
5576 AsmToken RegTok = getLexer().peekTok();
5577 SMRange RegRange = RegTok.getLocRange();
5578
5579 StringRef FixedName = StringSwitch<StringRef>(Name)
5580 .Case("t4", "t0")
5581 .Case("t5", "t1")
5582 .Case("t6", "t2")
5583 .Case("t7", "t3")
5584 .Default("");
5585 assert(FixedName != "" && "Register name is not one of t4-t7.")((FixedName != "" && "Register name is not one of t4-t7."
) ? static_cast<void> (0) : __assert_fail ("FixedName != \"\" && \"Register name is not one of t4-t7.\""
, "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5585, __PRETTY_FUNCTION__))
;
5586
5587 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5588 "Did you mean $" + FixedName + "?", RegRange);
5589 }
5590
5591 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5592 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5593 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5594 if (8 <= CC && CC <= 11)
5595 CC += 4;
5596
5597 if (CC == -1)
5598 CC = StringSwitch<unsigned>(Name)
5599 .Case("a4", 8)
5600 .Case("a5", 9)
5601 .Case("a6", 10)
5602 .Case("a7", 11)
5603 .Case("kt0", 26)
5604 .Case("kt1", 27)
5605 .Default(-1);
5606
5607 return CC;
5608}
5609
5610int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5611 int CC;
5612
5613 CC = StringSwitch<unsigned>(Name)
5614 .Case("hwr_cpunum", 0)
5615 .Case("hwr_synci_step", 1)
5616 .Case("hwr_cc", 2)
5617 .Case("hwr_ccres", 3)
5618 .Case("hwr_ulr", 29)
5619 .Default(-1);
5620
5621 return CC;
5622}
5623
5624int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5625 if (Name[0] == 'f') {
5626 StringRef NumString = Name.substr(1);
5627 unsigned IntVal;
5628 if (NumString.getAsInteger(10, IntVal))
5629 return -1; // This is not an integer.
5630 if (IntVal > 31) // Maximum index for fpu register.
5631 return -1;
5632 return IntVal;
5633 }
5634 return -1;
5635}
5636
5637int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5638 if (Name.startswith("fcc")) {
5639 StringRef NumString = Name.substr(3);
5640 unsigned IntVal;
5641 if (NumString.getAsInteger(10, IntVal))
5642 return -1; // This is not an integer.
5643 if (IntVal > 7) // There are only 8 fcc registers.
5644 return -1;
5645 return IntVal;
5646 }
5647 return -1;
5648}
5649
5650int MipsAsmParser::matchACRegisterName(StringRef Name) {
5651 if (Name.startswith("ac")) {
5652 StringRef NumString = Name.substr(2);
5653 unsigned IntVal;
5654 if (NumString.getAsInteger(10, IntVal))
5655 return -1; // This is not an integer.
5656 if (IntVal > 3) // There are only 3 acc registers.
5657 return -1;
5658 return IntVal;
5659 }
5660 return -1;
5661}
5662
5663int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5664 unsigned IntVal;
5665
5666 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5667 return -1;
5668
5669 if (IntVal > 31)
5670 return -1;
5671
5672 return IntVal;
5673}
5674
5675int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5676 int CC;
5677
5678 CC = StringSwitch<unsigned>(Name)
5679 .Case("msair", 0)
5680 .Case("msacsr", 1)
5681 .Case("msaaccess", 2)
5682 .Case("msasave", 3)
5683 .Case("msamodify", 4)
5684 .Case("msarequest", 5)
5685 .Case("msamap", 6)
5686 .Case("msaunmap", 7)
5687 .Default(-1);
5688
5689 return CC;
5690}
5691
5692bool MipsAsmParser::canUseATReg() {
5693 return AssemblerOptions.back()->getATRegIndex() != 0;
5694}
5695
5696unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5697 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5698 if (ATIndex == 0) {
5699 reportParseError(Loc,
5700 "pseudo-instruction requires $at, which is not available");
5701 return 0;
5702 }
5703 unsigned AT = getReg(
5704 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5705 return AT;
5706}
5707
5708unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5709 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5710}
5711
5712bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5713 MCAsmParser &Parser = getParser();
5714 LLVM_DEBUG(dbgs() << "parseOperand\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseOperand\n"; } } while
(false)
;
5715
5716 // Check if the current operand has a custom associated parser, if so, try to
5717 // custom parse the operand, or fallback to the general approach.
5718 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5719 if (ResTy == MatchOperand_Success)
5720 return false;
5721 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5722 // there was a match, but an error occurred, in which case, just return that
5723 // the operand parsing failed.
5724 if (ResTy == MatchOperand_ParseFail)
5725 return true;
5726
5727 LLVM_DEBUG(dbgs() << ".. Generic Parser\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. Generic Parser\n";
} } while (false)
;
5728
5729 switch (getLexer().getKind()) {
5730 case AsmToken::Dollar: {
5731 // Parse the register.
5732 SMLoc S = Parser.getTok().getLoc();
5733
5734 // Almost all registers have been parsed by custom parsers. There is only
5735 // one exception to this. $zero (and it's alias $0) will reach this point
5736 // for div, divu, and similar instructions because it is not an operand
5737 // to the instruction definition but an explicit register. Special case
5738 // this situation for now.
5739 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5740 return false;
5741
5742 // Maybe it is a symbol reference.
5743 StringRef Identifier;
5744 if (Parser.parseIdentifier(Identifier))
5745 return true;
5746
5747 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5748 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5749 // Otherwise create a symbol reference.
5750 const MCExpr *Res =
5751 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5752
5753 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5754 return false;
5755 }
5756 default: {
5757 LLVM_DEBUG(dbgs() << ".. generic integer expression\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. generic integer expression\n"
; } } while (false)
;
5758
5759 const MCExpr *Expr;
5760 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5761 if (getParser().parseExpression(Expr))
5762 return true;
5763
5764 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5765
5766 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5767 return false;
5768 }
5769 } // switch(getLexer().getKind())
5770 return true;
5771}
5772
5773bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5774 switch (Expr->getKind()) {
5775 case MCExpr::Constant:
5776 return true;
5777 case MCExpr::SymbolRef:
5778 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5779 case MCExpr::Binary: {
5780 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
5781 if (!isEvaluated(BE->getLHS()))
5782 return false;
5783 return isEvaluated(BE->getRHS());
5784 }
5785 case MCExpr::Unary:
5786 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5787 case MCExpr::Target:
5788 return true;
5789 }
5790 return false;
5791}
5792
5793bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5794 SMLoc &EndLoc) {
5795 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5796 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5797 if (ResTy == MatchOperand_Success) {
5798 assert(Operands.size() == 1)((Operands.size() == 1) ? static_cast<void> (0) : __assert_fail
("Operands.size() == 1", "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5798, __PRETTY_FUNCTION__))
;
5799 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5800 StartLoc = Operand.getStartLoc();
5801 EndLoc = Operand.getEndLoc();
5802
5803 // AFAIK, we only support numeric registers and named GPR's in CFI
5804 // directives.
5805 // Don't worry about eating tokens before failing. Using an unrecognised
5806 // register is a parse error.
5807 if (Operand.isGPRAsmReg()) {
5808 // Resolve to GPR32 or GPR64 appropriately.
5809 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5810 }
5811
5812 return (RegNo == (unsigned)-1);
5813 }
5814
5815 assert(Operands.size() == 0)((Operands.size() == 0) ? static_cast<void> (0) : __assert_fail
("Operands.size() == 0", "/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5815, __PRETTY_FUNCTION__))
;
5816 return (RegNo == (unsigned)-1);
5817}
5818
5819bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5820 SMLoc S;
5821
5822 if (isParenExpr)
5823 return getParser().parseParenExprOfDepth(0, Res, S);
5824 return getParser().parseExpression(Res);
5825}
5826
5827OperandMatchResultTy
5828MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5829 MCAsmParser &Parser = getParser();
5830 LLVM_DEBUG(dbgs() << "parseMemOperand\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseMemOperand\n"; }
} while (false)
;
5831 const MCExpr *IdVal = nullptr;
5832 SMLoc S;
5833 bool isParenExpr = false;
5834 OperandMatchResultTy Res = MatchOperand_NoMatch;
5835 // First operand is the offset.
5836 S = Parser.getTok().getLoc();
5837
5838 if (getLexer().getKind() == AsmToken::LParen) {
5839 Parser.Lex();
5840 isParenExpr = true;
5841 }
5842
5843 if (getLexer().getKind() != AsmToken::Dollar) {
5844 if (parseMemOffset(IdVal, isParenExpr))
5845 return MatchOperand_ParseFail;
5846
5847 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5848 if (Tok.isNot(AsmToken::LParen)) {
5849 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);