Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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

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

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