Bug Summary

File:build/source/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 4018, column 31
The left operand of '==' is a garbage value

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