Bug Summary

File:lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 2608, 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-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 -analyzer-config-compatibility-mode=true -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-9/lib/clang/9.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Mips -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/lib/Target/Mips -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/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/9.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.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-9~svn362543/build-llvm/lib/Target/Mips/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -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-2019-06-05-060531-1271-1 -x c++ /build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Mips/AsmParser/MipsAsmParser.cpp -faddrsig

/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

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