Bug Summary

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