Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 6821, column 11
Value stored to 'PrevReg' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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