Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -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-16/lib/clang/16 -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 _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -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-16/lib/clang/16/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 1674602410 -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-01-25-024556-16494-1 -x c++ /build/source/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

/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/Triple.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/BinaryFormat/ELF.h"
24#include "llvm/MC/MCContext.h"
25#include "llvm/MC/MCExpr.h"
26#include "llvm/MC/MCInst.h"
27#include "llvm/MC/MCInstrDesc.h"
28#include "llvm/MC/MCInstrInfo.h"
29#include "llvm/MC/MCObjectFileInfo.h"
30#include "llvm/MC/MCParser/MCAsmLexer.h"
31#include "llvm/MC/MCParser/MCAsmParser.h"
32#include "llvm/MC/MCParser/MCAsmParserExtension.h"
33#include "llvm/MC/MCParser/MCAsmParserUtils.h"
34#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
35#include "llvm/MC/MCParser/MCTargetAsmParser.h"
36#include "llvm/MC/MCSectionELF.h"
37#include "llvm/MC/MCStreamer.h"
38#include "llvm/MC/MCSubtargetInfo.h"
39#include "llvm/MC/MCSymbol.h"
40#include "llvm/MC/MCSymbolELF.h"
41#include "llvm/MC/MCValue.h"
42#include "llvm/MC/SubtargetFeature.h"
43#include "llvm/MC/TargetRegistry.h"
44#include "llvm/Support/Alignment.h"
45#include "llvm/Support/Casting.h"
46#include "llvm/Support/CommandLine.h"
47#include "llvm/Support/Compiler.h"
48#include "llvm/Support/Debug.h"
49#include "llvm/Support/ErrorHandling.h"
50#include "llvm/Support/MathExtras.h"
51#include "llvm/Support/SMLoc.h"
52#include "llvm/Support/SourceMgr.h"
53#include "llvm/Support/raw_ostream.h"
54#include <algorithm>
55#include <cassert>
56#include <cstdint>
57#include <memory>
58#include <string>
59#include <utility>
60
61using namespace llvm;
62
63#define DEBUG_TYPE"mips-asm-parser" "mips-asm-parser"
64
65namespace llvm {
66
67class MCInstrInfo;
68
69} // end namespace llvm
70
71extern cl::opt<bool> EmitJalrReloc;
72
73namespace {
74
75class MipsAssemblerOptions {
76public:
77 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
78
79 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
80 ATReg = Opts->getATRegIndex();
81 Reorder = Opts->isReorder();
82 Macro = Opts->isMacro();
83 Features = Opts->getFeatures();
84 }
85
86 unsigned getATRegIndex() const { return ATReg; }
87 bool setATRegIndex(unsigned Reg) {
88 if (Reg > 31)
89 return false;
90
91 ATReg = Reg;
92 return true;
93 }
94
95 bool isReorder() const { return Reorder; }
96 void setReorder() { Reorder = true; }
97 void setNoReorder() { Reorder = false; }
98
99 bool isMacro() const { return Macro; }
100 void setMacro() { Macro = true; }
101 void setNoMacro() { Macro = false; }
102
103 const FeatureBitset &getFeatures() const { return Features; }
104 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
105
106 // Set of features that are either architecture features or referenced
107 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
108 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
109 // The reason we need this mask is explained in the selectArch function.
110 // FIXME: Ideally we would like TableGen to generate this information.
111 static const FeatureBitset AllArchRelatedMask;
112
113private:
114 unsigned ATReg = 1;
115 bool Reorder = true;
116 bool Macro = true;
117 FeatureBitset Features;
118};
119
120} // end anonymous namespace
121
122const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
131 Mips::FeatureNaN2008
132};
133
134namespace {
135
136class MipsAsmParser : public MCTargetAsmParser {
137 MipsTargetStreamer &getTargetStreamer() {
138 assert(getParser().getStreamer().getTargetStreamer() &&(static_cast <bool> (getParser().getStreamer().getTargetStreamer
() && "do not have a target streamer") ? void (0) : __assert_fail
("getParser().getStreamer().getTargetStreamer() && \"do not have a target streamer\""
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 139, __extension__
__PRETTY_FUNCTION__))
139 "do not have a target streamer")(static_cast <bool> (getParser().getStreamer().getTargetStreamer
() && "do not have a target streamer") ? void (0) : __assert_fail
("getParser().getStreamer().getTargetStreamer() && \"do not have a target streamer\""
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 139, __extension__
__PRETTY_FUNCTION__))
;
140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141 return static_cast<MipsTargetStreamer &>(TS);
142 }
143
144 MipsABIInfo ABI;
145 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
146 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
147 // nullptr, which indicates that no function is currently
148 // selected. This usually happens after an '.end func'
149 // directive.
150 bool IsLittleEndian;
151 bool IsPicEnabled;
152 bool IsCpRestoreSet;
153 int CpRestoreOffset;
154 unsigned GPReg;
155 unsigned CpSaveLocation;
156 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
157 bool CpSaveLocationIsRegister;
158
159 // Map of register aliases created via the .set directive.
160 StringMap<AsmToken> RegisterSets;
161
162 // Print a warning along with its fix-it message at the given range.
163 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
164 SMRange Range, bool ShowColors = true);
165
166 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
167
168#define GET_ASSEMBLER_HEADER
169#include "MipsGenAsmMatcher.inc"
170
171 unsigned
172 checkEarlyTargetMatchPredicate(MCInst &Inst,
173 const OperandVector &Operands) override;
174 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
175
176 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
177 OperandVector &Operands, MCStreamer &Out,
178 uint64_t &ErrorInfo,
179 bool MatchingInlineAsm) override;
180
181 /// Parse a register as used in CFI directives
182 bool parseRegister(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().getFeatureBits()[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().getFeatureBits()[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().getFeatureBits()[Mips::FeatureGP64Bit];
580 }
581
582 bool isFP64bit() const {
583 return getSTI().getFeatureBits()[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().getFeatureBits()[Mips::FeatureFPXX];
605 }
606
607 bool useOddSPReg() const {
608 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
609 }
610
611 bool inMicroMipsMode() const {
612 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
613 }
614
615 bool hasMips1() const {
616 return getSTI().getFeatureBits()[Mips::FeatureMips1];
617 }
618
619 bool hasMips2() const {
620 return getSTI().getFeatureBits()[Mips::FeatureMips2];
621 }
622
623 bool hasMips3() const {
624 return getSTI().getFeatureBits()[Mips::FeatureMips3];
625 }
626
627 bool hasMips4() const {
628 return getSTI().getFeatureBits()[Mips::FeatureMips4];
629 }
630
631 bool hasMips5() const {
632 return getSTI().getFeatureBits()[Mips::FeatureMips5];
633 }
634
635 bool hasMips32() const {
636 return getSTI().getFeatureBits()[Mips::FeatureMips32];
637 }
638
639 bool hasMips64() const {
640 return getSTI().getFeatureBits()[Mips::FeatureMips64];
641 }
642
643 bool hasMips32r2() const {
644 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
645 }
646
647 bool hasMips64r2() const {
648 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
649 }
650
651 bool hasMips32r3() const {
652 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
653 }
654
655 bool hasMips64r3() const {
656 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
657 }
658
659 bool hasMips32r5() const {
660 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
661 }
662
663 bool hasMips64r5() const {
664 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
665 }
666
667 bool hasMips32r6() const {
668 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
669 }
670
671 bool hasMips64r6() const {
672 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
673 }
674
675 bool hasDSP() const {
676 return getSTI().getFeatureBits()[Mips::FeatureDSP];
677 }
678
679 bool hasDSPR2() const {
680 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
681 }
682
683 bool hasDSPR3() const {
684 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
685 }
686
687 bool hasMSA() const {
688 return getSTI().getFeatureBits()[Mips::FeatureMSA];
689 }
690
691 bool hasCnMips() const {
692 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
693 }
694
695 bool hasCnMipsP() const {
696 return (getSTI().getFeatureBits()[Mips::FeatureCnMipsP]);
697 }
698
699 bool inPicMode() {
700 return IsPicEnabled;
701 }
702
703 bool inMips16Mode() const {
704 return getSTI().getFeatureBits()[Mips::FeatureMips16];
705 }
706
707 bool useTraps() const {
708 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
709 }
710
711 bool useSoftFloat() const {
712 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
713 }
714 bool hasMT() const {
715 return getSTI().getFeatureBits()[Mips::FeatureMT];
716 }
717
718 bool hasCRC() const {
719 return getSTI().getFeatureBits()[Mips::FeatureCRC];
720 }
721
722 bool hasVirt() const {
723 return getSTI().getFeatureBits()[Mips::FeatureVirt];
724 }
725
726 bool hasGINV() const {
727 return getSTI().getFeatureBits()[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 unsigned BitNum = findFirstSet(x);
1
Calling 'findFirstSet<unsigned long>'
8
Returning from 'findFirstSet<unsigned long>'
9
'BitNum' initialized to 4294967295
2675
2676 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
10
The result of the right shift is undefined due to shifting by '4294967295', which is greater or equal to the width of type 'uint64_t'
2677}
2678
2679/// Load (or add) an immediate into a register.
2680///
2681/// @param ImmValue The immediate to load.
2682/// @param DstReg The register that will hold the immediate.
2683/// @param SrcReg A register to add to the immediate or Mips::NoRegister
2684/// for a simple initialization.
2685/// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2686/// @param IsAddress True if the immediate represents an address. False if it
2687/// is an integer.
2688/// @param IDLoc Location of the immediate in the source file.
2689bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2690 unsigned SrcReg, bool Is32BitImm,
2691 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2692 const MCSubtargetInfo *STI) {
2693 MipsTargetStreamer &TOut = getTargetStreamer();
2694
2695 if (!Is32BitImm && !isGP64bit()) {
2696 Error(IDLoc, "instruction requires a 64-bit architecture");
2697 return true;
2698 }
2699
2700 if (Is32BitImm) {
2701 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2702 // Sign extend up to 64-bit so that the predicates match the hardware
2703 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2704 // true.
2705 ImmValue = SignExtend64<32>(ImmValue);
2706 } else {
2707 Error(IDLoc, "instruction requires a 32-bit immediate");
2708 return true;
2709 }
2710 }
2711
2712 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2713 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2714
2715 bool UseSrcReg = false;
2716 if (SrcReg != Mips::NoRegister)
2717 UseSrcReg = true;
2718
2719 unsigned TmpReg = DstReg;
2720 if (UseSrcReg &&
2721 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2722 // At this point we need AT to perform the expansions and we exit if it is
2723 // not available.
2724 unsigned ATReg = getATReg(IDLoc);
2725 if (!ATReg)
2726 return true;
2727 TmpReg = ATReg;
2728 }
2729
2730 if (isInt<16>(ImmValue)) {
2731 if (!UseSrcReg)
2732 SrcReg = ZeroReg;
2733
2734 // This doesn't quite follow the usual ABI expectations for N32 but matches
2735 // traditional assembler behaviour. N32 would normally use addiu for both
2736 // integers and addresses.
2737 if (IsAddress && !Is32BitImm) {
2738 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2739 return false;
2740 }
2741
2742 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2743 return false;
2744 }
2745
2746 if (isUInt<16>(ImmValue)) {
2747 unsigned TmpReg = DstReg;
2748 if (SrcReg == DstReg) {
2749 TmpReg = getATReg(IDLoc);
2750 if (!TmpReg)
2751 return true;
2752 }
2753
2754 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2755 if (UseSrcReg)
2756 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2757 return false;
2758 }
2759
2760 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2761 warnIfNoMacro(IDLoc);
2762
2763 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2764 uint16_t Bits15To0 = ImmValue & 0xffff;
2765 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2766 // Traditional behaviour seems to special case this particular value. It's
2767 // not clear why other masks are handled differently.
2768 if (ImmValue == 0xffffffff) {
2769 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2770 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2771 if (UseSrcReg)
2772 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2773 return false;
2774 }
2775
2776 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2777 // upper 32 bits.
2778 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2779 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2780 if (Bits15To0)
2781 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2782 if (UseSrcReg)
2783 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2784 return false;
2785 }
2786
2787 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2788 if (Bits15To0)
2789 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2790 if (UseSrcReg)
2791 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2792 return false;
2793 }
2794
2795 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2796 if (Is32BitImm) {
2797 Error(IDLoc, "instruction requires a 32-bit immediate");
2798 return true;
2799 }
2800
2801 // Traditionally, these immediates are shifted as little as possible and as
2802 // such we align the most significant bit to bit 15 of our temporary.
2803 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2804 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2805 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2806 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2807 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2808 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2809
2810 if (UseSrcReg)
2811 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2812
2813 return false;
2814 }
2815
2816 warnIfNoMacro(IDLoc);
2817
2818 // The remaining case is packed with a sequence of dsll and ori with zeros
2819 // being omitted and any neighbouring dsll's being coalesced.
2820 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2821
2822 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2823 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2824 IDLoc, Out, STI))
2825 return false;
2826
2827 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2828 // skip it and defer the shift to the next chunk.
2829 unsigned ShiftCarriedForwards = 16;
2830 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2831 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2832
2833 if (ImmChunk != 0) {
2834 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2835 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2836 ShiftCarriedForwards = 0;
2837 }
2838
2839 ShiftCarriedForwards += 16;
2840 }
2841 ShiftCarriedForwards -= 16;
2842
2843 // Finish any remaining shifts left by trailing zeros.
2844 if (ShiftCarriedForwards)
2845 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2846
2847 if (UseSrcReg)
2848 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2849
2850 return false;
2851}
2852
2853bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2854 MCStreamer &Out, const MCSubtargetInfo *STI) {
2855 const MCOperand &ImmOp = Inst.getOperand(1);
2856 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", 2856, __extension__
__PRETTY_FUNCTION__))
;
2857 const MCOperand &DstRegOp = Inst.getOperand(0);
2858 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", 2858, __extension__
__PRETTY_FUNCTION__))
;
2859
2860 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2861 Is32BitImm, false, IDLoc, Out, STI))
2862 return true;
2863
2864 return false;
2865}
2866
2867bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2868 const MCOperand &Offset,
2869 bool Is32BitAddress, SMLoc IDLoc,
2870 MCStreamer &Out,
2871 const MCSubtargetInfo *STI) {
2872 // la can't produce a usable address when addresses are 64-bit.
2873 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2874 Warning(IDLoc, "la used to load 64-bit address");
2875 // Continue as if we had 'dla' instead.
2876 Is32BitAddress = false;
2877 }
2878
2879 // dla requires 64-bit addresses.
2880 if (!Is32BitAddress && !hasMips3()) {
2881 Error(IDLoc, "instruction requires a 64-bit architecture");
2882 return true;
2883 }
2884
2885 if (!Offset.isImm())
2886 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2887 Is32BitAddress, IDLoc, Out, STI);
2888
2889 if (!ABI.ArePtrs64bit()) {
2890 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2891 Is32BitAddress = true;
2892 }
2893
2894 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2895 IDLoc, Out, STI);
2896}
2897
2898bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2899 unsigned DstReg, unsigned SrcReg,
2900 bool Is32BitSym, SMLoc IDLoc,
2901 MCStreamer &Out,
2902 const MCSubtargetInfo *STI) {
2903 MipsTargetStreamer &TOut = getTargetStreamer();
2904 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2905 SrcReg != Mips::ZERO_64;
2906 warnIfNoMacro(IDLoc);
2907
2908 if (inPicMode()) {
2909 MCValue Res;
2910 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2911 Error(IDLoc, "expected relocatable expression");
2912 return true;
2913 }
2914 if (Res.getSymB() != nullptr) {
2915 Error(IDLoc, "expected relocatable expression with only one symbol");
2916 return true;
2917 }
2918
2919 bool IsPtr64 = ABI.ArePtrs64bit();
2920 bool IsLocalSym =
2921 Res.getSymA()->getSymbol().isInSection() ||
2922 Res.getSymA()->getSymbol().isTemporary() ||
2923 (Res.getSymA()->getSymbol().isELF() &&
2924 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2925 ELF::STB_LOCAL);
2926 bool UseXGOT = STI->getFeatureBits()[Mips::FeatureXGOT] && !IsLocalSym;
2927
2928 // The case where the result register is $25 is somewhat special. If the
2929 // symbol in the final relocation is external and not modified with a
2930 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2931 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2932 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2933 Res.getConstant() == 0 && !IsLocalSym) {
2934 if (UseXGOT) {
2935 const MCExpr *CallHiExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16,
2936 SymExpr, getContext());
2937 const MCExpr *CallLoExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16,
2938 SymExpr, getContext());
2939 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2940 STI);
2941 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2942 IDLoc, STI);
2943 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2944 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2945 } else {
2946 const MCExpr *CallExpr =
2947 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2948 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2949 MCOperand::createExpr(CallExpr), IDLoc, STI);
2950 }
2951 return false;
2952 }
2953
2954 unsigned TmpReg = DstReg;
2955 if (UseSrcReg &&
2956 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2957 SrcReg)) {
2958 // If $rs is the same as $rd, we need to use AT.
2959 // If it is not available we exit.
2960 unsigned ATReg = getATReg(IDLoc);
2961 if (!ATReg)
2962 return true;
2963 TmpReg = ATReg;
2964 }
2965
2966 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
2967 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
2968 // FIXME: Implement XGOT for microMIPS.
2969 if (UseXGOT) {
2970 // Loading address from XGOT
2971 // External GOT: lui $tmp, %got_hi(symbol)($gp)
2972 // addu $tmp, $tmp, $gp
2973 // lw $tmp, %got_lo(symbol)($tmp)
2974 // >addiu $tmp, $tmp, offset
2975 // >addiu $rd, $tmp, $rs
2976 // The addiu's marked with a '>' may be omitted if they are redundant. If
2977 // this happens then the last instruction must use $rd as the result
2978 // register.
2979 const MCExpr *CallHiExpr =
2980 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
2981 const MCExpr *CallLoExpr = MipsMCExpr::create(
2982 MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
2983
2984 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2985 STI);
2986 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2987 IDLoc, STI);
2988 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
2989 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2990
2991 if (Res.getConstant() != 0)
2992 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
2993 MCOperand::createExpr(MCConstantExpr::create(
2994 Res.getConstant(), getContext())),
2995 IDLoc, STI);
2996
2997 if (UseSrcReg)
2998 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
2999 IDLoc, STI);
3000 return false;
3001 }
3002
3003 const MipsMCExpr *GotExpr = nullptr;
3004 const MCExpr *LoExpr = nullptr;
3005 if (ABI.IsN32() || ABI.IsN64()) {
3006 // The remaining cases are:
3007 // Small offset: ld $tmp, %got_disp(symbol)($gp)
3008 // >daddiu $tmp, $tmp, offset
3009 // >daddu $rd, $tmp, $rs
3010 // The daddiu's marked with a '>' may be omitted if they are redundant. If
3011 // this happens then the last instruction must use $rd as the result
3012 // register.
3013 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, Res.getSymA(),
3014 getContext());
3015 if (Res.getConstant() != 0) {
3016 // Symbols fully resolve with just the %got_disp(symbol) but we
3017 // must still account for any offset to the symbol for
3018 // expressions like symbol+8.
3019 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3020
3021 // FIXME: Offsets greater than 16 bits are not yet implemented.
3022 // FIXME: The correct range is a 32-bit sign-extended number.
3023 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3024 Error(IDLoc, "macro instruction uses large offset, which is not "
3025 "currently supported");
3026 return true;
3027 }
3028 }
3029 } else {
3030 // The remaining cases are:
3031 // External GOT: lw $tmp, %got(symbol)($gp)
3032 // >addiu $tmp, $tmp, offset
3033 // >addiu $rd, $tmp, $rs
3034 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3035 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3036 // >addiu $rd, $tmp, $rs
3037 // The addiu's marked with a '>' may be omitted if they are redundant. If
3038 // this happens then the last instruction must use $rd as the result
3039 // register.
3040 if (IsLocalSym) {
3041 GotExpr =
3042 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3043 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3044 } else {
3045 // External symbols fully resolve the symbol with just the %got(symbol)
3046 // but we must still account for any offset to the symbol for
3047 // expressions like symbol+8.
3048 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, Res.getSymA(),
3049 getContext());
3050 if (Res.getConstant() != 0)
3051 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3052 }
3053 }
3054
3055 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3056 MCOperand::createExpr(GotExpr), IDLoc, STI);
3057
3058 if (LoExpr)
3059 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3060 MCOperand::createExpr(LoExpr), IDLoc, STI);
3061
3062 if (UseSrcReg)
3063 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3064 IDLoc, STI);
3065
3066 return false;
3067 }
3068
3069 const MipsMCExpr *HiExpr =
3070 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3071 const MipsMCExpr *LoExpr =
3072 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3073
3074 // This is the 64-bit symbol address expansion.
3075 if (ABI.ArePtrs64bit() && isGP64bit()) {
3076 // We need AT for the 64-bit expansion in the cases where the optional
3077 // source register is the destination register and for the superscalar
3078 // scheduled form.
3079 //
3080 // If it is not available we exit if the destination is the same as the
3081 // source register.
3082
3083 const MipsMCExpr *HighestExpr =
3084 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3085 const MipsMCExpr *HigherExpr =
3086 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3087
3088 bool RdRegIsRsReg =
3089 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3090
3091 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3092 unsigned ATReg = getATReg(IDLoc);
3093
3094 // If $rs is the same as $rd:
3095 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3096 // daddiu $at, $at, %higher(sym)
3097 // dsll $at, $at, 16
3098 // daddiu $at, $at, %hi(sym)
3099 // dsll $at, $at, 16
3100 // daddiu $at, $at, %lo(sym)
3101 // daddu $rd, $at, $rd
3102 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3103 STI);
3104 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3105 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3106 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3107 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3108 IDLoc, STI);
3109 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3110 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3111 IDLoc, STI);
3112 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3113
3114 return false;
3115 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3116 unsigned ATReg = getATReg(IDLoc);
3117
3118 // If the $rs is different from $rd or if $rs isn't specified and we
3119 // have $at available:
3120 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3121 // lui $at, %hi(sym)
3122 // daddiu $rd, $rd, %higher(sym)
3123 // daddiu $at, $at, %lo(sym)
3124 // dsll32 $rd, $rd, 0
3125 // daddu $rd, $rd, $at
3126 // (daddu $rd, $rd, $rs)
3127 //
3128 // Which is preferred for superscalar issue.
3129 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3130 STI);
3131 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3132 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3133 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3134 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3135 IDLoc, STI);
3136 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3137 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3138 if (UseSrcReg)
3139 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3140
3141 return false;
3142 } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3143 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3144 // Otherwise, synthesize the address in the destination register
3145 // serially:
3146 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3147 // daddiu $rd, $rd, %higher(sym)
3148 // dsll $rd, $rd, 16
3149 // daddiu $rd, $rd, %hi(sym)
3150 // dsll $rd, $rd, 16
3151 // daddiu $rd, $rd, %lo(sym)
3152 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3153 STI);
3154 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3155 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3156 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3157 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3158 MCOperand::createExpr(HiExpr), IDLoc, STI);
3159 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3160 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3161 MCOperand::createExpr(LoExpr), IDLoc, STI);
3162 if (UseSrcReg)
3163 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3164
3165 return false;
3166 } else {
3167 // We have a case where SrcReg == DstReg and we don't have $at
3168 // available. We can't expand this case, so error out appropriately.
3169 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", 3170, __extension__
__PRETTY_FUNCTION__))
3170 "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", 3170, __extension__
__PRETTY_FUNCTION__))
;
3171 reportParseError(IDLoc,
3172 "pseudo-instruction requires $at, which is not available");
3173 return true;
3174 }
3175 }
3176
3177 // And now, the 32-bit symbol address expansion:
3178 // If $rs is the same as $rd:
3179 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3180 // ori $at, $at, %lo(sym)
3181 // addu $rd, $at, $rd
3182 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3183 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3184 // ori $rd, $rd, %lo(sym)
3185 // (addu $rd, $rd, $rs)
3186 unsigned TmpReg = DstReg;
3187 if (UseSrcReg &&
3188 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3189 // If $rs is the same as $rd, we need to use AT.
3190 // If it is not available we exit.
3191 unsigned ATReg = getATReg(IDLoc);
3192 if (!ATReg)
3193 return true;
3194 TmpReg = ATReg;
3195 }
3196
3197 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3198 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3199 IDLoc, STI);
3200
3201 if (UseSrcReg)
3202 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3203 else
3204 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", 3205, __extension__
__PRETTY_FUNCTION__))
3205 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", 3205, __extension__
__PRETTY_FUNCTION__))
;
3206
3207 return false;
3208}
3209
3210// Each double-precision register DO-D15 overlaps with two of the single
3211// precision registers F0-F31. As an example, all of the following hold true:
3212// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3213static unsigned nextReg(unsigned Reg) {
3214 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3215 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3216 switch (Reg) {
3217 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", 3217)
;
3218 case Mips::ZERO: return Mips::AT;
3219 case Mips::AT: return Mips::V0;
3220 case Mips::V0: return Mips::V1;
3221 case Mips::V1: return Mips::A0;
3222 case Mips::A0: return Mips::A1;
3223 case Mips::A1: return Mips::A2;
3224 case Mips::A2: return Mips::A3;
3225 case Mips::A3: return Mips::T0;
3226 case Mips::T0: return Mips::T1;
3227 case Mips::T1: return Mips::T2;
3228 case Mips::T2: return Mips::T3;
3229 case Mips::T3: return Mips::T4;
3230 case Mips::T4: return Mips::T5;
3231 case Mips::T5: return Mips::T6;
3232 case Mips::T6: return Mips::T7;
3233 case Mips::T7: return Mips::S0;
3234 case Mips::S0: return Mips::S1;
3235 case Mips::S1: return Mips::S2;
3236 case Mips::S2: return Mips::S3;
3237 case Mips::S3: return Mips::S4;
3238 case Mips::S4: return Mips::S5;
3239 case Mips::S5: return Mips::S6;
3240 case Mips::S6: return Mips::S7;
3241 case Mips::S7: return Mips::T8;
3242 case Mips::T8: return Mips::T9;
3243 case Mips::T9: return Mips::K0;
3244 case Mips::K0: return Mips::K1;
3245 case Mips::K1: return Mips::GP;
3246 case Mips::GP: return Mips::SP;
3247 case Mips::SP: return Mips::FP;
3248 case Mips::FP: return Mips::RA;
3249 case Mips::RA: return Mips::ZERO;
3250 case Mips::D0: return Mips::F1;
3251 case Mips::D1: return Mips::F3;
3252 case Mips::D2: return Mips::F5;
3253 case Mips::D3: return Mips::F7;
3254 case Mips::D4: return Mips::F9;
3255 case Mips::D5: return Mips::F11;
3256 case Mips::D6: return Mips::F13;
3257 case Mips::D7: return Mips::F15;
3258 case Mips::D8: return Mips::F17;
3259 case Mips::D9: return Mips::F19;
3260 case Mips::D10: return Mips::F21;
3261 case Mips::D11: return Mips::F23;
3262 case Mips::D12: return Mips::F25;
3263 case Mips::D13: return Mips::F27;
3264 case Mips::D14: return Mips::F29;
3265 case Mips::D15: return Mips::F31;
3266 }
3267}
3268
3269// FIXME: This method is too general. In principle we should compute the number
3270// of instructions required to synthesize the immediate inline compared to
3271// synthesizing the address inline and relying on non .text sections.
3272// For static O32 and N32 this may yield a small benefit, for static N64 this is
3273// likely to yield a much larger benefit as we have to synthesize a 64bit
3274// address to load a 64 bit value.
3275bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3276 MCSymbol *Sym) {
3277 unsigned ATReg = getATReg(IDLoc);
3278 if (!ATReg)
3279 return true;
3280
3281 if(IsPicEnabled) {
3282 const MCExpr *GotSym =
3283 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3284 const MipsMCExpr *GotExpr =
3285 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3286
3287 if(isABI_O32() || isABI_N32()) {
3288 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3289 IDLoc, STI);
3290 } else { //isABI_N64()
3291 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3292 IDLoc, STI);
3293 }
3294 } else { //!IsPicEnabled
3295 const MCExpr *HiSym =
3296 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3297 const MipsMCExpr *HiExpr =
3298 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3299
3300 // FIXME: This is technically correct but gives a different result to gas,
3301 // but gas is incomplete there (it has a fixme noting it doesn't work with
3302 // 64-bit addresses).
3303 // FIXME: With -msym32 option, the address expansion for N64 should probably
3304 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3305 // symbol's value is considered sign extended.
3306 if(isABI_O32() || isABI_N32()) {
3307 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3308 } else { //isABI_N64()
3309 const MCExpr *HighestSym =
3310 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3311 const MipsMCExpr *HighestExpr =
3312 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3313 const MCExpr *HigherSym =
3314 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3315 const MipsMCExpr *HigherExpr =
3316 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3317
3318 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3319 STI);
3320 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3321 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3322 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3323 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3324 IDLoc, STI);
3325 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3326 }
3327 }
3328 return false;
3329}
3330
3331static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) {
3332 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3333 // exponent field), convert it to double (e.g. 1 to 1.0)
3334 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3335 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3336 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3337 }
3338 return ImmOp64;
3339}
3340
3341static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) {
3342 // Conversion of a double in an uint64_t to a float in a uint32_t,
3343 // retaining the bit pattern of a float.
3344 double DoubleImm = BitsToDouble(ImmOp64);
3345 float TmpFloat = static_cast<float>(DoubleImm);
3346 return FloatToBits(TmpFloat);
3347}
3348
3349bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3350 MCStreamer &Out,
3351 const MCSubtargetInfo *STI) {
3352 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", 3352, __extension__
__PRETTY_FUNCTION__))
;
3353 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", 3354, __extension__
__PRETTY_FUNCTION__))
3354 "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", 3354, __extension__
__PRETTY_FUNCTION__))
;
3355
3356 unsigned FirstReg = Inst.getOperand(0).getReg();
3357 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3358
3359 uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3360
3361 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3362 Out, STI);
3363}
3364
3365bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3366 MCStreamer &Out,
3367 const MCSubtargetInfo *STI) {
3368 MipsTargetStreamer &TOut = getTargetStreamer();
3369 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", 3369, __extension__
__PRETTY_FUNCTION__))
;
3370 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", 3371, __extension__
__PRETTY_FUNCTION__))
3371 "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", 3371, __extension__
__PRETTY_FUNCTION__))
;
3372
3373 unsigned FirstReg = Inst.getOperand(0).getReg();
3374 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3375
3376 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3377
3378 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3379
3380 unsigned TmpReg = Mips::ZERO;
3381 if (ImmOp32 != 0) {
3382 TmpReg = getATReg(IDLoc);
3383 if (!TmpReg)
3384 return true;
3385 }
3386
3387 if (Lo_32(ImmOp64) == 0) {
3388 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3389 true, false, IDLoc, Out, STI))
3390 return true;
3391 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3392 return false;
3393 }
3394
3395 MCSection *CS = getStreamer().getCurrentSectionOnly();
3396 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3397 // where appropriate.
3398 MCSection *ReadOnlySection =
3399 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3400
3401 MCSymbol *Sym = getContext().createTempSymbol();
3402 const MCExpr *LoSym =
3403 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3404 const MipsMCExpr *LoExpr =
3405 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3406
3407 getStreamer().switchSection(ReadOnlySection);
3408 getStreamer().emitLabel(Sym, IDLoc);
3409 getStreamer().emitInt32(ImmOp32);
3410 getStreamer().switchSection(CS);
3411
3412 if (emitPartialAddress(TOut, IDLoc, Sym))
3413 return true;
3414 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3415 IDLoc, STI);
3416 return false;
3417}
3418
3419bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3420 MCStreamer &Out,
3421 const MCSubtargetInfo *STI) {
3422 MipsTargetStreamer &TOut = getTargetStreamer();
3423 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", 3423, __extension__
__PRETTY_FUNCTION__))
;
3424 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", 3425, __extension__
__PRETTY_FUNCTION__))
3425 "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", 3425, __extension__
__PRETTY_FUNCTION__))
;
3426
3427 unsigned FirstReg = Inst.getOperand(0).getReg();
3428 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3429
3430 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3431
3432 if (Lo_32(ImmOp64) == 0) {
3433 if (isGP64bit()) {
3434 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3435 IDLoc, Out, STI))
3436 return true;
3437 } else {
3438 if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3439 IDLoc, Out, STI))
3440 return true;
3441
3442 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3443 IDLoc, Out, STI))
3444 return true;
3445 }
3446 return false;
3447 }
3448
3449 MCSection *CS = getStreamer().getCurrentSectionOnly();
3450 MCSection *ReadOnlySection =
3451 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3452
3453 MCSymbol *Sym = getContext().createTempSymbol();
3454 const MCExpr *LoSym =
3455 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3456 const MipsMCExpr *LoExpr =
3457 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3458
3459 getStreamer().switchSection(ReadOnlySection);
3460 getStreamer().emitLabel(Sym, IDLoc);
3461 getStreamer().emitValueToAlignment(Align(8));
3462 getStreamer().emitIntValue(ImmOp64, 8);
3463 getStreamer().switchSection(CS);
3464
3465 unsigned TmpReg = getATReg(IDLoc);
3466 if (!TmpReg)
3467 return true;
3468
3469 if (emitPartialAddress(TOut, IDLoc, Sym))
3470 return true;
3471
3472 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3473 MCOperand::createExpr(LoExpr), IDLoc, STI);
3474
3475 if (isGP64bit())
3476 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3477 else {
3478 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3479 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3480 }
3481 return false;
3482}
3483
3484bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3485 SMLoc IDLoc, MCStreamer &Out,
3486 const MCSubtargetInfo *STI) {
3487 MipsTargetStreamer &TOut = getTargetStreamer();
3488 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", 3488, __extension__
__PRETTY_FUNCTION__))
;
3489 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", 3490, __extension__
__PRETTY_FUNCTION__))
3490 "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", 3490, __extension__
__PRETTY_FUNCTION__))
;
3491
3492 unsigned FirstReg = Inst.getOperand(0).getReg();
3493 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3494
3495 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3496
3497 unsigned TmpReg = Mips::ZERO;
3498 if (ImmOp64 != 0) {
3499 TmpReg = getATReg(IDLoc);
3500 if (!TmpReg)
3501 return true;
3502 }
3503
3504 if ((Lo_32(ImmOp64) == 0) &&
3505 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3506 if (isGP64bit()) {
3507 if (TmpReg != Mips::ZERO &&
3508 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3509 Out, STI))
3510 return true;
3511 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3512 return false;
3513 }
3514
3515 if (TmpReg != Mips::ZERO &&
3516 loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3517 IDLoc, Out, STI))
3518 return true;
3519
3520 if (hasMips32r2()) {
3521 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3522 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3523 } else {
3524 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3525 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3526 }
3527 return false;
3528 }
3529
3530 MCSection *CS = getStreamer().getCurrentSectionOnly();
3531 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3532 // where appropriate.
3533 MCSection *ReadOnlySection =
3534 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3535
3536 MCSymbol *Sym = getContext().createTempSymbol();
3537 const MCExpr *LoSym =
3538 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3539 const MipsMCExpr *LoExpr =
3540 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3541
3542 getStreamer().switchSection(ReadOnlySection);
3543 getStreamer().emitLabel(Sym, IDLoc);
3544 getStreamer().emitValueToAlignment(Align(8));
3545 getStreamer().emitIntValue(ImmOp64, 8);
3546 getStreamer().switchSection(CS);
3547
3548 if (emitPartialAddress(TOut, IDLoc, Sym))
3549 return true;
3550
3551 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3552 MCOperand::createExpr(LoExpr), IDLoc, STI);
3553
3554 return false;
3555}
3556
3557bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3558 MCStreamer &Out,
3559 const MCSubtargetInfo *STI) {
3560 MipsTargetStreamer &TOut = getTargetStreamer();
3561
3562 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", 3563, __extension__
__PRETTY_FUNCTION__))
3563 "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", 3563, __extension__
__PRETTY_FUNCTION__))
;
3564
3565 MCOperand Offset = Inst.getOperand(0);
3566 if (Offset.isExpr()) {
3567 Inst.clear();
3568 Inst.setOpcode(Mips::BEQ_MM);
3569 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3570 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3571 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3572 } else {
3573 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", 3573, __extension__
__PRETTY_FUNCTION__))
;
3574 if (isInt<11>(Offset.getImm())) {
3575 // If offset fits into 11 bits then this instruction becomes microMIPS
3576 // 16-bit unconditional branch instruction.
3577 if (inMicroMipsMode())
3578 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3579 } else {
3580 if (!isInt<17>(Offset.getImm()))
3581 return Error(IDLoc, "branch target out of range");
3582 if (offsetToAlignment(Offset.getImm(), Align(2)))
3583 return Error(IDLoc, "branch to misaligned address");
3584 Inst.clear();
3585 Inst.setOpcode(Mips::BEQ_MM);
3586 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3587 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3588 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3589 }
3590 }
3591 Out.emitInstruction(Inst, *STI);
3592
3593 // If .set reorder is active and branch instruction has a delay slot,
3594 // emit a NOP after it.
3595 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3596 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3597 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3598
3599 return false;
3600}
3601
3602bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3603 const MCSubtargetInfo *STI) {
3604 MipsTargetStreamer &TOut = getTargetStreamer();
3605 const MCOperand &DstRegOp = Inst.getOperand(0);
3606 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", 3606, __extension__
__PRETTY_FUNCTION__))
;
3607
3608 const MCOperand &ImmOp = Inst.getOperand(1);
3609 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", 3609, __extension__
__PRETTY_FUNCTION__))
;
3610
3611 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3612 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", 3613, __extension__
__PRETTY_FUNCTION__))
3613 "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", 3613, __extension__
__PRETTY_FUNCTION__))
;
3614
3615 bool IsLikely = false;
3616
3617 unsigned OpCode = 0;
3618 switch(Inst.getOpcode()) {
3619 case Mips::BneImm:
3620 OpCode = Mips::BNE;
3621 break;
3622 case Mips::BeqImm:
3623 OpCode = Mips::BEQ;
3624 break;
3625 case Mips::BEQLImmMacro:
3626 OpCode = Mips::BEQL;
3627 IsLikely = true;
3628 break;
3629 case Mips::BNELImmMacro:
3630 OpCode = Mips::BNEL;
3631 IsLikely = true;
3632 break;
3633 default:
3634 llvm_unreachable("Unknown immediate branch pseudo-instruction.")::llvm::llvm_unreachable_internal("Unknown immediate branch pseudo-instruction."
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 3634)
;
3635 break;
3636 }
3637
3638 int64_t ImmValue = ImmOp.getImm();
3639 if (ImmValue == 0) {
3640 if (IsLikely) {
3641 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3642 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3643 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3644 } else
3645 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3646 STI);
3647 } else {
3648 warnIfNoMacro(IDLoc);
3649
3650 unsigned ATReg = getATReg(IDLoc);
3651 if (!ATReg)
3652 return true;
3653
3654 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3655 IDLoc, Out, STI))
3656 return true;
3657
3658 if (IsLikely) {
3659 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3660 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3661 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3662 } else
3663 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3664 }
3665 return false;
3666}
3667
3668void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3669 const MCSubtargetInfo *STI, bool IsLoad) {
3670 unsigned NumOp = Inst.getNumOperands();
3671 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", 3671, __extension__
__PRETTY_FUNCTION__))
;
3672 unsigned StartOp = NumOp == 3 ? 0 : 1;
3673
3674 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3675 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", 3675, __extension__
__PRETTY_FUNCTION__))
;
3676 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3677 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", 3677, __extension__
__PRETTY_FUNCTION__))
;
3678 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3679
3680 MipsTargetStreamer &TOut = getTargetStreamer();
3681 unsigned OpCode = Inst.getOpcode();
3682 unsigned DstReg = DstRegOp.getReg();
3683 unsigned BaseReg = BaseRegOp.getReg();
3684 unsigned TmpReg = DstReg;
3685
3686 const MCInstrDesc &Desc = MII.get(OpCode);
3687 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3688 unsigned DstRegClassID =
3689 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3690 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3691 (DstRegClassID == Mips::GPR64RegClassID);
3692
3693 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3694 // At this point we need AT to perform the expansions
3695 // and we exit if it is not available.
3696 TmpReg = getATReg(IDLoc);
3697 if (!TmpReg)
3698 return;
3699 }
3700
3701 auto emitInstWithOffset = [&](const MCOperand &Off) {
3702 if (NumOp == 3)
3703 TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3704 else
3705 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3706 };
3707
3708 if (OffsetOp.isImm()) {
3709 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3710 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3711
3712 // If msb of LoOffset is 1(negative number) we must increment
3713 // HiOffset to account for the sign-extension of the low part.
3714 if (LoOffset & 0x8000)
3715 HiOffset += 0x10000;
3716
3717 bool IsLargeOffset = HiOffset != 0;
3718
3719 if (IsLargeOffset) {
3720 bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3721 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3722 IDLoc, Out, STI))
3723 return;
3724 }
3725
3726 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3727 TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3728 TmpReg, BaseReg, IDLoc, STI);
3729 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3730 return;
3731 }
3732
3733 if (OffsetOp.isExpr()) {
3734 if (inPicMode()) {
3735 // FIXME:
3736 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3737 // do not exceed 16-bit.
3738 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3739 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3740 // of GOT entries.
3741 MCValue Res;
3742 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3743 Error(IDLoc, "expected relocatable expression");
3744 return;
3745 }
3746 if (Res.getSymB() != nullptr) {
3747 Error(IDLoc, "expected relocatable expression with only one symbol");
3748 return;
3749 }
3750
3751 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3752 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3753 emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3754 } else {
3755 // FIXME: Implement 64-bit case.
3756 // 1) lw $8, sym => lui $8, %hi(sym)
3757 // lw $8, %lo(sym)($8)
3758 // 2) sw $8, sym => lui $at, %hi(sym)
3759 // sw $8, %lo(sym)($at)
3760 const MCExpr *OffExpr = OffsetOp.getExpr();
3761 MCOperand LoOperand = MCOperand::createExpr(
3762 MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
3763 MCOperand HiOperand = MCOperand::createExpr(
3764 MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
3765
3766 if (ABI.IsN64()) {
3767 MCOperand HighestOperand = MCOperand::createExpr(
3768 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
3769 MCOperand HigherOperand = MCOperand::createExpr(
3770 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
3771
3772 TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3773 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3774 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3775 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3776 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3777 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3778 TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3779 emitInstWithOffset(LoOperand);
3780 } else {
3781 // Generate the base address in TmpReg.
3782 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3783 if (BaseReg != Mips::ZERO)
3784 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3785 // Emit the load or store with the adjusted base and offset.
3786 emitInstWithOffset(LoOperand);
3787 }
3788 }
3789 return;
3790 }
3791
3792 llvm_unreachable("unexpected operand type")::llvm::llvm_unreachable_internal("unexpected operand type", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3792)
;
3793}
3794
3795void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3796 const MCSubtargetInfo *STI, bool IsLoad) {
3797 unsigned NumOp = Inst.getNumOperands();
3798 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", 3798, __extension__
__PRETTY_FUNCTION__))
;
3799 unsigned StartOp = NumOp == 3 ? 0 : 1;
3800
3801 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3802 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", 3802, __extension__
__PRETTY_FUNCTION__))
;
3803 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3804 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", 3804, __extension__
__PRETTY_FUNCTION__))
;
3805 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3806
3807 MipsTargetStreamer &TOut = getTargetStreamer();
3808 unsigned OpCode = Inst.getOpcode();
3809 unsigned DstReg = DstRegOp.getReg();
3810 unsigned BaseReg = BaseRegOp.getReg();
3811 unsigned TmpReg = DstReg;
3812
3813 const MCInstrDesc &Desc = MII.get(OpCode);
3814 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3815 unsigned DstRegClassID =
3816 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3817 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3818 (DstRegClassID == Mips::GPR64RegClassID);
3819
3820 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3821 // At this point we need AT to perform the expansions
3822 // and we exit if it is not available.
3823 TmpReg = getATReg(IDLoc);
3824 if (!TmpReg)
3825 return;
3826 }
3827
3828 auto emitInst = [&]() {
3829 if (NumOp == 3)
3830 TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3831 else
3832 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3833 IDLoc, STI);
3834 };
3835
3836 if (OffsetOp.isImm()) {
3837 loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3838 IDLoc, Out, STI);
3839 emitInst();
3840 return;
3841 }
3842
3843 if (OffsetOp.isExpr()) {
3844 loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3845 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3846 emitInst();
3847 return;
3848 }
3849
3850 llvm_unreachable("unexpected operand type")::llvm::llvm_unreachable_internal("unexpected operand type", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3850)
;
3851}
3852
3853bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3854 MCStreamer &Out,
3855 const MCSubtargetInfo *STI) {
3856 unsigned OpNum = Inst.getNumOperands();
3857 unsigned Opcode = Inst.getOpcode();
3858 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3859
3860 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", 3862, __extension__
__PRETTY_FUNCTION__))
3861 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", 3862, __extension__
__PRETTY_FUNCTION__))
3862 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", 3862, __extension__
__PRETTY_FUNCTION__))
;
3863
3864 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3865 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3866 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3867 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3868 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3869 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3870 // It can be implemented as SWM16 or LWM16 instruction.
3871 if (inMicroMipsMode() && hasMips32r6())
3872 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3873 else
3874 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3875 }
3876
3877 Inst.setOpcode(NewOpcode);
3878 Out.emitInstruction(Inst, *STI);
3879 return false;
3880}
3881
3882bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3883 MCStreamer &Out,
3884 const MCSubtargetInfo *STI) {
3885 MipsTargetStreamer &TOut = getTargetStreamer();
3886 bool EmittedNoMacroWarning = false;
3887 unsigned PseudoOpcode = Inst.getOpcode();
3888 unsigned SrcReg = Inst.getOperand(0).getReg();
3889 const MCOperand &TrgOp = Inst.getOperand(1);
3890 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3891
3892 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3893 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3894
3895 unsigned TrgReg;
3896 if (TrgOp.isReg())
3897 TrgReg = TrgOp.getReg();
3898 else if (TrgOp.isImm()) {
3899 warnIfNoMacro(IDLoc);
3900 EmittedNoMacroWarning = true;
3901
3902 TrgReg = getATReg(IDLoc);
3903 if (!TrgReg)
3904 return true;
3905
3906 switch(PseudoOpcode) {
3907 default:
3908 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", 3908)
;
3909 case Mips::BLTImmMacro:
3910 PseudoOpcode = Mips::BLT;
3911 break;
3912 case Mips::BLEImmMacro:
3913 PseudoOpcode = Mips::BLE;
3914 break;
3915 case Mips::BGEImmMacro:
3916 PseudoOpcode = Mips::BGE;
3917 break;
3918 case Mips::BGTImmMacro:
3919 PseudoOpcode = Mips::BGT;
3920 break;
3921 case Mips::BLTUImmMacro:
3922 PseudoOpcode = Mips::BLTU;
3923 break;
3924 case Mips::BLEUImmMacro:
3925 PseudoOpcode = Mips::BLEU;
3926 break;
3927 case Mips::BGEUImmMacro:
3928 PseudoOpcode = Mips::BGEU;
3929 break;
3930 case Mips::BGTUImmMacro:
3931 PseudoOpcode = Mips::BGTU;
3932 break;
3933 case Mips::BLTLImmMacro:
3934 PseudoOpcode = Mips::BLTL;
3935 break;
3936 case Mips::BLELImmMacro:
3937 PseudoOpcode = Mips::BLEL;
3938 break;
3939 case Mips::BGELImmMacro:
3940 PseudoOpcode = Mips::BGEL;
3941 break;
3942 case Mips::BGTLImmMacro:
3943 PseudoOpcode = Mips::BGTL;
3944 break;
3945 case Mips::BLTULImmMacro:
3946 PseudoOpcode = Mips::BLTUL;
3947 break;
3948 case Mips::BLEULImmMacro:
3949 PseudoOpcode = Mips::BLEUL;
3950 break;
3951 case Mips::BGEULImmMacro:
3952 PseudoOpcode = Mips::BGEUL;
3953 break;
3954 case Mips::BGTULImmMacro:
3955 PseudoOpcode = Mips::BGTUL;
3956 break;
3957 }
3958
3959 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3960 false, IDLoc, Out, STI))
3961 return true;
3962 }
3963
3964 switch (PseudoOpcode) {
3965 case Mips::BLT:
3966 case Mips::BLTU:
3967 case Mips::BLTL:
3968 case Mips::BLTUL:
3969 AcceptsEquality = false;
3970 ReverseOrderSLT = false;
3971 IsUnsigned =
3972 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3973 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3974 ZeroSrcOpcode = Mips::BGTZ;
3975 ZeroTrgOpcode = Mips::BLTZ;
3976 break;
3977 case Mips::BLE:
3978 case Mips::BLEU:
3979 case Mips::BLEL:
3980 case Mips::BLEUL:
3981 AcceptsEquality = true;
3982 ReverseOrderSLT = true;
3983 IsUnsigned =
3984 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3985 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3986 ZeroSrcOpcode = Mips::BGEZ;
3987 ZeroTrgOpcode = Mips::BLEZ;
3988 break;
3989 case Mips::BGE:
3990 case Mips::BGEU:
3991 case Mips::BGEL:
3992 case Mips::BGEUL:
3993 AcceptsEquality = true;
3994 ReverseOrderSLT = false;
3995 IsUnsigned =
3996 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3997 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3998 ZeroSrcOpcode = Mips::BLEZ;
3999 ZeroTrgOpcode = Mips::BGEZ;
4000 break;
4001 case Mips::BGT:
4002 case Mips::BGTU:
4003 case Mips::BGTL:
4004 case Mips::BGTUL:
4005 AcceptsEquality = false;
4006 ReverseOrderSLT = true;
4007 IsUnsigned =
4008 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4009 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4010 ZeroSrcOpcode = Mips::BLTZ;
4011 ZeroTrgOpcode = Mips::BGTZ;
4012 break;
4013 default:
4014 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", 4014)
;
4015 }
4016
4017 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4018 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4019 if (IsSrcRegZero && IsTrgRegZero) {
4020 // FIXME: All of these Opcode-specific if's are needed for compatibility
4021 // with GAS' behaviour. However, they may not generate the most efficient
4022 // code in some circumstances.
4023 if (PseudoOpcode == Mips::BLT) {
4024 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4025 IDLoc, STI);
4026 return false;
4027 }
4028 if (PseudoOpcode == Mips::BLE) {
4029 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4030 IDLoc, STI);
4031 Warning(IDLoc, "branch is always taken");
4032 return false;
4033 }
4034 if (PseudoOpcode == Mips::BGE) {
4035 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4036 IDLoc, STI);
4037 Warning(IDLoc, "branch is always taken");
4038 return false;
4039 }
4040 if (PseudoOpcode == Mips::BGT) {
4041 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4042 IDLoc, STI);
4043 return false;
4044 }
4045 if (PseudoOpcode == Mips::BGTU) {
4046 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4047 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4048 return false;
4049 }
4050 if (AcceptsEquality) {
4051 // If both registers are $0 and the pseudo-branch accepts equality, it
4052 // will always be taken, so we emit an unconditional branch.
4053 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4054 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4055 Warning(IDLoc, "branch is always taken");
4056 return false;
4057 }
4058 // If both registers are $0 and the pseudo-branch does not accept
4059 // equality, it will never be taken, so we don't have to emit anything.
4060 return false;
4061 }
4062 if (IsSrcRegZero || IsTrgRegZero) {
4063 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4064 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4065 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4066 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4067 // the pseudo-branch will never be taken, so we don't emit anything.
4068 // This only applies to unsigned pseudo-branches.
4069 return false;
4070 }
4071 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4072 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4073 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4074 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4075 // the pseudo-branch will always be taken, so we emit an unconditional
4076 // branch.
4077 // This only applies to unsigned pseudo-branches.
4078 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4079 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4080 Warning(IDLoc, "branch is always taken");
4081 return false;
4082 }
4083 if (IsUnsigned) {
4084 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4085 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4086 // the pseudo-branch will be taken only when the non-zero register is
4087 // different from 0, so we emit a BNEZ.
4088 //
4089 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4090 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4091 // the pseudo-branch will be taken only when the non-zero register is
4092 // equal to 0, so we emit a BEQZ.
4093 //
4094 // Because only BLEU and BGEU branch on equality, we can use the
4095 // AcceptsEquality variable to decide when to emit the BEQZ.
4096 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4097 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4098 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4099 return false;
4100 }
4101 // If we have a signed pseudo-branch and one of the registers is $0,
4102 // we can use an appropriate compare-to-zero branch. We select which one
4103 // to use in the switch statement above.
4104 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4105 IsSrcRegZero ? TrgReg : SrcReg,
4106 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4107 return false;
4108 }
4109
4110 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4111 // expansions. If it is not available, we return.
4112 unsigned ATRegNum = getATReg(IDLoc);
4113 if (!ATRegNum)
4114 return true;
4115
4116 if (!EmittedNoMacroWarning)
4117 warnIfNoMacro(IDLoc);
4118
4119 // SLT fits well with 2 of our 4 pseudo-branches:
4120 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4121 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4122 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4123 // This is accomplished by using a BNEZ with the result of the SLT.
4124 //
4125 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4126 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4127 // Because only BGE and BLE branch on equality, we can use the
4128 // AcceptsEquality variable to decide when to emit the BEQZ.
4129 // Note that the order of the SLT arguments doesn't change between
4130 // opposites.
4131 //
4132 // The same applies to the unsigned variants, except that SLTu is used
4133 // instead of SLT.
4134 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4135 ReverseOrderSLT ? TrgReg : SrcReg,
4136 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4137
4138 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4139 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4140 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4141 STI);
4142 return false;
4143}
4144
4145// Expand a integer division macro.
4146//
4147// Notably we don't have to emit a warning when encountering $rt as the $zero
4148// register, or 0 as an immediate. processInstruction() has already done that.
4149//
4150// The destination register can only be $zero when expanding (S)DivIMacro or
4151// D(S)DivMacro.
4152
4153bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4154 const MCSubtargetInfo *STI,
4155 const bool IsMips64, const bool Signed) {
4156 MipsTargetStreamer &TOut = getTargetStreamer();
4157
4158 warnIfNoMacro(IDLoc);
4159
4160 const MCOperand &RdRegOp = Inst.getOperand(0);
4161 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", 4161, __extension__
__PRETTY_FUNCTION__))
;
4162 unsigned RdReg = RdRegOp.getReg();
4163
4164 const MCOperand &RsRegOp = Inst.getOperand(1);
4165 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", 4165, __extension__
__PRETTY_FUNCTION__))
;
4166 unsigned RsReg = RsRegOp.getReg();
4167
4168 unsigned RtReg;
4169 int64_t ImmValue;
4170
4171 const MCOperand &RtOp = Inst.getOperand(2);
4172 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", 4173, __extension__
__PRETTY_FUNCTION__))
4173 "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", 4173, __extension__
__PRETTY_FUNCTION__))
;
4174 if (RtOp.isReg())
4175 RtReg = RtOp.getReg();
4176 else
4177 ImmValue = RtOp.getImm();
4178
4179 unsigned DivOp;
4180 unsigned ZeroReg;
4181 unsigned SubOp;
4182
4183 if (IsMips64) {
4184 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4185 ZeroReg = Mips::ZERO_64;
4186 SubOp = Mips::DSUB;
4187 } else {
4188 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4189 ZeroReg = Mips::ZERO;
4190 SubOp = Mips::SUB;
4191 }
4192
4193 bool UseTraps = useTraps();
4194
4195 unsigned Opcode = Inst.getOpcode();
4196 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4197 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4198 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4199 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4200
4201 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4202 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4203 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4204 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4205
4206 if (RtOp.isImm()) {
4207 unsigned ATReg = getATReg(IDLoc);
4208 if (!ATReg)
4209 return true;
4210
4211 if (ImmValue == 0) {
4212 if (UseTraps)
4213 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4214 else
4215 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4216 return false;
4217 }
4218
4219 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4220 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4221 return false;
4222 } else if (isDiv && ImmValue == 1) {
4223 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4224 return false;
4225 } else if (isDiv && Signed && ImmValue == -1) {
4226 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4227 return false;
4228 } else {
4229 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4230 false, Inst.getLoc(), Out, STI))
4231 return true;
4232 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4233 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4234 return false;
4235 }
4236 return true;
4237 }
4238
4239 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4240 // break, insert the trap/break and exit. This gives a different result to
4241 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4242 // are handled equivalently. As the observed behaviour is the same, we're ok.
4243 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4244 if (UseTraps) {
4245 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4246 return false;
4247 }
4248 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4249 return false;
4250 }
4251
4252 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4253 // not expand to macro sequence.
4254 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4255 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4256 return false;
4257 }
4258
4259 // Temporary label for first branch traget
4260 MCContext &Context = TOut.getStreamer().getContext();
4261 MCSymbol *BrTarget;
4262 MCOperand LabelOp;
4263
4264 if (UseTraps) {
4265 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4266 } else {
4267 // Branch to the li instruction.
4268 BrTarget = Context.createTempSymbol();
4269 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4270 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4271 }
4272
4273 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4274
4275 if (!UseTraps)
4276 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4277
4278 if (!Signed) {
4279 if (!UseTraps)
4280 TOut.getStreamer().emitLabel(BrTarget);
4281
4282 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4283 return false;
4284 }
4285
4286 unsigned ATReg = getATReg(IDLoc);
4287 if (!ATReg)
4288 return true;
4289
4290 if (!UseTraps)
4291 TOut.getStreamer().emitLabel(BrTarget);
4292
4293 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4294
4295 // Temporary label for the second branch target.
4296 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4297 MCOperand LabelOpEnd =
4298 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4299
4300 // Branch to the mflo instruction.
4301 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4302
4303 if (IsMips64) {
4304 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4305 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4306 } else {
4307 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4308 }
4309
4310 if (UseTraps)
4311 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4312 else {
4313 // Branch to the mflo instruction.
4314 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4315 TOut.emitNop(IDLoc, STI);
4316 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4317 }
4318
4319 TOut.getStreamer().emitLabel(BrTargetEnd);
4320 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4321 return false;
4322}
4323
4324bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4325 SMLoc IDLoc, MCStreamer &Out,
4326 const MCSubtargetInfo *STI) {
4327 MipsTargetStreamer &TOut = getTargetStreamer();
4328
4329 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", 4329, __extension__
__PRETTY_FUNCTION__))
;
4330 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", 4331, __extension__
__PRETTY_FUNCTION__))
4331 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", 4331, __extension__
__PRETTY_FUNCTION__))
;
4332
4333 unsigned FirstReg = Inst.getOperand(0).getReg();
4334 unsigned SecondReg = Inst.getOperand(1).getReg();
4335 unsigned ThirdReg = Inst.getOperand(2).getReg();
4336
4337 if (hasMips1() && !hasMips2()) {
4338 unsigned ATReg = getATReg(IDLoc);
4339 if (!ATReg)
4340 return true;
4341 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4342 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4343 TOut.emitNop(IDLoc, STI);
4344 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4345 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4346 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4347 TOut.emitNop(IDLoc, STI);
4348 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4349 : Mips::CVT_W_S,
4350 FirstReg, SecondReg, IDLoc, STI);
4351 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4352 TOut.emitNop(IDLoc, STI);
4353 return false;
4354 }
4355
4356 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4357 : Mips::TRUNC_W_S,
4358 FirstReg, SecondReg, IDLoc, STI);
4359
4360 return false;
4361}
4362
4363bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4364 MCStreamer &Out, const MCSubtargetInfo *STI) {
4365 if (hasMips32r6() || hasMips64r6()) {
4366 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4367 }
4368
4369 const MCOperand &DstRegOp = Inst.getOperand(0);
4370 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", 4370, __extension__
__PRETTY_FUNCTION__))
;
4371 const MCOperand &SrcRegOp = Inst.getOperand(1);
4372 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", 4372, __extension__
__PRETTY_FUNCTION__))
;
4373 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4374 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", 4374, __extension__
__PRETTY_FUNCTION__))
;
4375
4376 MipsTargetStreamer &TOut = getTargetStreamer();
4377 unsigned DstReg = DstRegOp.getReg();
4378 unsigned SrcReg = SrcRegOp.getReg();
4379 int64_t OffsetValue = OffsetImmOp.getImm();
4380
4381 // NOTE: We always need AT for ULHU, as it is always used as the source
4382 // register for one of the LBu's.
4383 warnIfNoMacro(IDLoc);
4384 unsigned ATReg = getATReg(IDLoc);
4385 if (!ATReg)
4386 return true;
4387
4388 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4389 if (IsLargeOffset) {
4390 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4391 IDLoc, Out, STI))
4392 return true;
4393 }
4394
4395 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4396 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4397 if (isLittle())
4398 std::swap(FirstOffset, SecondOffset);
4399
4400 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4401 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4402
4403 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4404 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4405
4406 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4407 FirstOffset, IDLoc, STI);
4408 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4409 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4410 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4411
4412 return false;
4413}
4414
4415bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4416 const MCSubtargetInfo *STI) {
4417 if (hasMips32r6() || hasMips64r6()) {
4418 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4419 }
4420
4421 const MCOperand &DstRegOp = Inst.getOperand(0);
4422 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", 4422, __extension__
__PRETTY_FUNCTION__))
;
4423 const MCOperand &SrcRegOp = Inst.getOperand(1);
4424 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", 4424, __extension__
__PRETTY_FUNCTION__))
;
4425 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4426 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", 4426, __extension__
__PRETTY_FUNCTION__))
;
4427
4428 MipsTargetStreamer &TOut = getTargetStreamer();
4429 unsigned DstReg = DstRegOp.getReg();
4430 unsigned SrcReg = SrcRegOp.getReg();
4431 int64_t OffsetValue = OffsetImmOp.getImm();
4432
4433 warnIfNoMacro(IDLoc);
4434 unsigned ATReg = getATReg(IDLoc);
4435 if (!ATReg)
4436 return true;
4437
4438 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4439 if (IsLargeOffset) {
4440 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4441 IDLoc, Out, STI))
4442 return true;
4443 }
4444
4445 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4446 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4447 if (isLittle())
4448 std::swap(FirstOffset, SecondOffset);
4449
4450 if (IsLargeOffset) {
4451 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4452 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4453 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4454 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4455 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4456 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4457 } else {
4458 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4459 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4460 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4461 }
4462
4463 return false;
4464}
4465
4466bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4467 const MCSubtargetInfo *STI) {
4468 if (hasMips32r6() || hasMips64r6()) {
4469 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4470 }
4471
4472 const MCOperand &DstRegOp = Inst.getOperand(0);
4473 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", 4473, __extension__
__PRETTY_FUNCTION__))
;
4474 const MCOperand &SrcRegOp = Inst.getOperand(1);
4475 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", 4475, __extension__
__PRETTY_FUNCTION__))
;
4476 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4477 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", 4477, __extension__
__PRETTY_FUNCTION__))
;
4478
4479 MipsTargetStreamer &TOut = getTargetStreamer();
4480 unsigned DstReg = DstRegOp.getReg();
4481 unsigned SrcReg = SrcRegOp.getReg();
4482 int64_t OffsetValue = OffsetImmOp.getImm();
4483
4484 // Compute left/right load/store offsets.
4485 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4486 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4487 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4488 if (isLittle())
4489 std::swap(LxlOffset, LxrOffset);
4490
4491 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4492 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4493 unsigned TmpReg = SrcReg;
4494 if (IsLargeOffset || DoMove) {
4495 warnIfNoMacro(IDLoc);
4496 TmpReg = getATReg(IDLoc);
4497 if (!TmpReg)
4498 return true;
4499 }
4500
4501 if (IsLargeOffset) {
4502 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4503 IDLoc, Out, STI))
4504 return true;
4505 }
4506
4507 if (DoMove)
4508 std::swap(DstReg, TmpReg);
4509
4510 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4511 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4512 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4513 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4514
4515 if (DoMove)
4516 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4517
4518 return false;
4519}
4520
4521bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4522 const MCSubtargetInfo *STI) {
4523 MipsTargetStreamer &TOut = getTargetStreamer();
4524
4525 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", 4525, __extension__
__PRETTY_FUNCTION__))
;
4526 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", 4528, __extension__
__PRETTY_FUNCTION__))
4527 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", 4528, __extension__
__PRETTY_FUNCTION__))
4528 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", 4528, __extension__
__PRETTY_FUNCTION__))
;
4529
4530 unsigned DstReg = Inst.getOperand(0).getReg();
4531 unsigned SrcReg = Inst.getOperand(1).getReg();
4532 unsigned OpReg = Inst.getOperand(2).getReg();
4533 unsigned OpCode;
4534
4535 warnIfNoMacro(IDLoc);
4536
4537 switch (Inst.getOpcode()) {
4538 case Mips::SGE:
4539 OpCode = Mips::SLT;
4540 break;
4541 case Mips::SGEU:
4542 OpCode = Mips::SLTu;
4543 break;
4544 default:
4545 llvm_unreachable("unexpected 'sge' opcode")::llvm::llvm_unreachable_internal("unexpected 'sge' opcode", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4545)
;
4546 }
4547
4548 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4549 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4550 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4551
4552 return false;
4553}
4554
4555bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4556 const MCSubtargetInfo *STI) {
4557 MipsTargetStreamer &TOut = getTargetStreamer();
4558
4559 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", 4559, __extension__
__PRETTY_FUNCTION__))
;
4560 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", 4562, __extension__
__PRETTY_FUNCTION__))
4561 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", 4562, __extension__
__PRETTY_FUNCTION__))
4562 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", 4562, __extension__
__PRETTY_FUNCTION__))
;
4563
4564 unsigned DstReg = Inst.getOperand(0).getReg();
4565 unsigned SrcReg = Inst.getOperand(1).getReg();
4566 int64_t ImmValue = Inst.getOperand(2).getImm();
4567 unsigned OpRegCode, OpImmCode;
4568
4569 warnIfNoMacro(IDLoc);
4570
4571 switch (Inst.getOpcode()) {
4572 case Mips::SGEImm:
4573 case Mips::SGEImm64:
4574 OpRegCode = Mips::SLT;
4575 OpImmCode = Mips::SLTi;
4576 break;
4577 case Mips::SGEUImm:
4578 case Mips::SGEUImm64:
4579 OpRegCode = Mips::SLTu;
4580 OpImmCode = Mips::SLTiu;
4581 break;
4582 default:
4583 llvm_unreachable("unexpected 'sge' opcode with immediate")::llvm::llvm_unreachable_internal("unexpected 'sge' opcode with immediate"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 4583)
;
4584 }
4585
4586 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4587 if (isInt<16>(ImmValue)) {
4588 // Use immediate version of STL.
4589 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4590 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4591 } else {
4592 unsigned ImmReg = DstReg;
4593 if (DstReg == SrcReg) {
4594 unsigned ATReg = getATReg(Inst.getLoc());
4595 if (!ATReg)
4596 return true;
4597 ImmReg = ATReg;
4598 }
4599
4600 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4601 false, IDLoc, Out, STI))
4602 return true;
4603
4604 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4605 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4606 }
4607
4608 return false;
4609}
4610
4611bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4612 const MCSubtargetInfo *STI) {
4613 MipsTargetStreamer &TOut = getTargetStreamer();
4614
4615 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", 4615, __extension__
__PRETTY_FUNCTION__))
;
4616 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", 4618, __extension__
__PRETTY_FUNCTION__))
4617 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", 4618, __extension__
__PRETTY_FUNCTION__))
4618 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", 4618, __extension__
__PRETTY_FUNCTION__))
;
4619
4620 unsigned DstReg = Inst.getOperand(0).getReg();
4621 unsigned SrcReg = Inst.getOperand(1).getReg();
4622 unsigned ImmReg = DstReg;
4623 int64_t ImmValue = Inst.getOperand(2).getImm();
4624 unsigned OpCode;
4625
4626 warnIfNoMacro(IDLoc);
4627
4628 switch (Inst.getOpcode()) {
4629 case Mips::SGTImm:
4630 case Mips::SGTImm64:
4631 OpCode = Mips::SLT;
4632 break;
4633 case Mips::SGTUImm:
4634 case Mips::SGTUImm64:
4635 OpCode = Mips::SLTu;
4636 break;
4637 default:
4638 llvm_unreachable("unexpected 'sgt' opcode with immediate")::llvm::llvm_unreachable_internal("unexpected 'sgt' opcode with immediate"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 4638)
;
4639 }
4640
4641 if (DstReg == SrcReg) {
4642 unsigned ATReg = getATReg(Inst.getLoc());
4643 if (!ATReg)
4644 return true;
4645 ImmReg = ATReg;
4646 }
4647
4648 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4649 false, IDLoc, Out, STI))
4650 return true;
4651
4652 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4653 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4654
4655 return false;
4656}
4657
4658bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4659 const MCSubtargetInfo *STI) {
4660 MipsTargetStreamer &TOut = getTargetStreamer();
4661
4662 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", 4662, __extension__
__PRETTY_FUNCTION__))
;
4663 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", 4665, __extension__
__PRETTY_FUNCTION__))
4664 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", 4665, __extension__
__PRETTY_FUNCTION__))
4665 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", 4665, __extension__
__PRETTY_FUNCTION__))
;
4666
4667 unsigned DstReg = Inst.getOperand(0).getReg();
4668 unsigned SrcReg = Inst.getOperand(1).getReg();
4669 unsigned OpReg = Inst.getOperand(2).getReg();
4670 unsigned OpCode;
4671
4672 warnIfNoMacro(IDLoc);
4673
4674 switch (Inst.getOpcode()) {
4675 case Mips::SLE:
4676 OpCode = Mips::SLT;
4677 break;
4678 case Mips::SLEU:
4679 OpCode = Mips::SLTu;
4680 break;
4681 default:
4682 llvm_unreachable("unexpected 'sge' opcode")::llvm::llvm_unreachable_internal("unexpected 'sge' opcode", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4682)
;
4683 }
4684
4685 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4686 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4687 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4688
4689 return false;
4690}
4691
4692bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4693 const MCSubtargetInfo *STI) {
4694 MipsTargetStreamer &TOut = getTargetStreamer();
4695
4696 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", 4696, __extension__
__PRETTY_FUNCTION__))
;
4697 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", 4699, __extension__
__PRETTY_FUNCTION__))
4698 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", 4699, __extension__
__PRETTY_FUNCTION__))
4699 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", 4699, __extension__
__PRETTY_FUNCTION__))
;
4700
4701 unsigned DstReg = Inst.getOperand(0).getReg();
4702 unsigned SrcReg = Inst.getOperand(1).getReg();
4703 int64_t ImmValue = Inst.getOperand(2).getImm();
4704 unsigned OpRegCode;
4705
4706 warnIfNoMacro(IDLoc);
4707
4708 switch (Inst.getOpcode()) {
4709 case Mips::SLEImm:
4710 case Mips::SLEImm64:
4711 OpRegCode = Mips::SLT;
4712 break;
4713 case Mips::SLEUImm:
4714 case Mips::SLEUImm64:
4715 OpRegCode = Mips::SLTu;
4716 break;
4717 default:
4718 llvm_unreachable("unexpected 'sge' opcode with immediate")::llvm::llvm_unreachable_internal("unexpected 'sge' opcode with immediate"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 4718)
;
4719 }
4720
4721 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4722 unsigned ImmReg = DstReg;
4723 if (DstReg == SrcReg) {
4724 unsigned ATReg = getATReg(Inst.getLoc());
4725 if (!ATReg)
4726 return true;
4727 ImmReg = ATReg;
4728 }
4729
4730 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4731 false, IDLoc, Out, STI))
4732 return true;
4733
4734 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4735 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4736
4737 return false;
4738}
4739
4740bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4741 MCStreamer &Out,
4742 const MCSubtargetInfo *STI) {
4743 MipsTargetStreamer &TOut = getTargetStreamer();
4744
4745 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", 4745, __extension__
__PRETTY_FUNCTION__))
;
4746 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", 4748, __extension__
__PRETTY_FUNCTION__))
4747 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", 4748, __extension__
__PRETTY_FUNCTION__))
4748 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", 4748, __extension__
__PRETTY_FUNCTION__))
;
4749
4750 unsigned ATReg = Mips::NoRegister;
4751 unsigned FinalDstReg = Mips::NoRegister;
4752 unsigned DstReg = Inst.getOperand(0).getReg();
4753 unsigned SrcReg = Inst.getOperand(1).getReg();
4754 int64_t ImmValue = Inst.getOperand(2).getImm();
4755
4756 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4757
4758 unsigned FinalOpcode = Inst.getOpcode();
4759
4760 if (DstReg == SrcReg) {
4761 ATReg = getATReg(Inst.getLoc());
4762 if (!ATReg)
4763 return true;
4764 FinalDstReg = DstReg;
4765 DstReg = ATReg;
4766 }
4767
4768 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4769 Inst.getLoc(), Out, STI)) {
4770 switch (FinalOpcode) {
4771 default:
4772 llvm_unreachable("unimplemented expansion")::llvm::llvm_unreachable_internal("unimplemented expansion", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4772)
;
4773 case Mips::ADDi:
4774 FinalOpcode = Mips::ADD;
4775 break;
4776 case Mips::ADDiu:
4777 FinalOpcode = Mips::ADDu;
4778 break;
4779 case Mips::ANDi:
4780 FinalOpcode = Mips::AND;
4781 break;
4782 case Mips::NORImm:
4783 FinalOpcode = Mips::NOR;
4784 break;
4785 case Mips::ORi:
4786 FinalOpcode = Mips::OR;
4787 break;
4788 case Mips::SLTi:
4789 FinalOpcode = Mips::SLT;
4790 break;
4791 case Mips::SLTiu:
4792 FinalOpcode = Mips::SLTu;
4793 break;
4794 case Mips::XORi:
4795 FinalOpcode = Mips::XOR;
4796 break;
4797 case Mips::ADDi_MM:
4798 FinalOpcode = Mips::ADD_MM;
4799 break;
4800 case Mips::ADDiu_MM:
4801 FinalOpcode = Mips::ADDu_MM;
4802 break;
4803 case Mips::ANDi_MM:
4804 FinalOpcode = Mips::AND_MM;
4805 break;
4806 case Mips::ORi_MM:
4807 FinalOpcode = Mips::OR_MM;
4808 break;
4809 case Mips::SLTi_MM:
4810 FinalOpcode = Mips::SLT_MM;
4811 break;
4812 case Mips::SLTiu_MM:
4813 FinalOpcode = Mips::SLTu_MM;
4814 break;
4815 case Mips::XORi_MM:
4816 FinalOpcode = Mips::XOR_MM;
4817 break;
4818 case Mips::ANDi64:
4819 FinalOpcode = Mips::AND64;
4820 break;
4821 case Mips::NORImm64:
4822 FinalOpcode = Mips::NOR64;
4823 break;
4824 case Mips::ORi64:
4825 FinalOpcode = Mips::OR64;
4826 break;
4827 case Mips::SLTImm64:
4828 FinalOpcode = Mips::SLT64;
4829 break;
4830 case Mips::SLTUImm64:
4831 FinalOpcode = Mips::SLTu64;
4832 break;
4833 case Mips::XORi64:
4834 FinalOpcode = Mips::XOR64;
4835 break;
4836 }
4837
4838 if (FinalDstReg == Mips::NoRegister)
4839 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4840 else
4841 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4842 return false;
4843 }
4844 return true;
4845}
4846
4847bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4848 const MCSubtargetInfo *STI) {
4849 MipsTargetStreamer &TOut = getTargetStreamer();
4850 unsigned ATReg = Mips::NoRegister;
4851 unsigned DReg = Inst.getOperand(0).getReg();
4852 unsigned SReg = Inst.getOperand(1).getReg();
4853 unsigned TReg = Inst.getOperand(2).getReg();
4854 unsigned TmpReg = DReg;
4855
4856 unsigned FirstShift = Mips::NOP;
4857 unsigned SecondShift = Mips::NOP;
4858
4859 if (hasMips32r2()) {
4860 if (DReg == SReg) {
4861 TmpReg = getATReg(Inst.getLoc());
4862 if (!TmpReg)
4863 return true;
4864 }
4865
4866 if (Inst.getOpcode() == Mips::ROL) {
4867 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4868 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4869 return false;
4870 }
4871
4872 if (Inst.getOpcode() == Mips::ROR) {
4873 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4874 return false;
4875 }
4876
4877 return true;
4878 }
4879
4880 if (hasMips32()) {
4881 switch (Inst.getOpcode()) {
4882 default:
4883 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 4883)
;
4884 case Mips::ROL:
4885 FirstShift = Mips::SRLV;
4886 SecondShift = Mips::SLLV;
4887 break;
4888 case Mips::ROR:
4889 FirstShift = Mips::SLLV;
4890 SecondShift = Mips::SRLV;
4891 break;
4892 }
4893
4894 ATReg = getATReg(Inst.getLoc());
4895 if (!ATReg)
4896 return true;
4897
4898 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4899 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4900 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4901 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4902
4903 return false;
4904 }
4905
4906 return true;
4907}
4908
4909bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4910 MCStreamer &Out,
4911 const MCSubtargetInfo *STI) {
4912 MipsTargetStreamer &TOut = getTargetStreamer();
4913 unsigned ATReg = Mips::NoRegister;
4914 unsigned DReg = Inst.getOperand(0).getReg();
4915 unsigned SReg = Inst.getOperand(1).getReg();
4916 int64_t ImmValue = Inst.getOperand(2).getImm();
4917
4918 unsigned FirstShift = Mips::NOP;
4919 unsigned SecondShift = Mips::NOP;
4920
4921 if (hasMips32r2()) {
4922 if (Inst.getOpcode() == Mips::ROLImm) {
4923 uint64_t MaxShift = 32;
4924 uint64_t ShiftValue = ImmValue;
4925 if (ImmValue != 0)
4926 ShiftValue = MaxShift - ImmValue;
4927 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4928 return false;
4929 }
4930
4931 if (Inst.getOpcode() == Mips::RORImm) {
4932 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4933 return false;
4934 }
4935
4936 return true;
4937 }
4938
4939 if (hasMips32()) {
4940 if (ImmValue == 0) {
4941 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4942 return false;
4943 }
4944
4945 switch (Inst.getOpcode()) {
4946 default:
4947 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 4947)
;
4948 case Mips::ROLImm:
4949 FirstShift = Mips::SLL;
4950 SecondShift = Mips::SRL;
4951 break;
4952 case Mips::RORImm:
4953 FirstShift = Mips::SRL;
4954 SecondShift = Mips::SLL;
4955 break;
4956 }
4957
4958 ATReg = getATReg(Inst.getLoc());
4959 if (!ATReg)
4960 return true;
4961
4962 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4963 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4964 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4965
4966 return false;
4967 }
4968
4969 return true;
4970}
4971
4972bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4973 const MCSubtargetInfo *STI) {
4974 MipsTargetStreamer &TOut = getTargetStreamer();
4975 unsigned ATReg = Mips::NoRegister;
4976 unsigned DReg = Inst.getOperand(0).getReg();
4977 unsigned SReg = Inst.getOperand(1).getReg();
4978 unsigned TReg = Inst.getOperand(2).getReg();
4979 unsigned TmpReg = DReg;
4980
4981 unsigned FirstShift = Mips::NOP;
4982 unsigned SecondShift = Mips::NOP;
4983
4984 if (hasMips64r2()) {
4985 if (TmpReg == SReg) {
4986 TmpReg = getATReg(Inst.getLoc());
4987 if (!TmpReg)
4988 return true;
4989 }
4990
4991 if (Inst.getOpcode() == Mips::DROL) {
4992 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4993 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4994 return false;
4995 }
4996
4997 if (Inst.getOpcode() == Mips::DROR) {
4998 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4999 return false;
5000 }
5001
5002 return true;
5003 }
5004
5005 if (hasMips64()) {
5006 switch (Inst.getOpcode()) {
5007 default:
5008 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 5008)
;
5009 case Mips::DROL:
5010 FirstShift = Mips::DSRLV;
5011 SecondShift = Mips::DSLLV;
5012 break;
5013 case Mips::DROR:
5014 FirstShift = Mips::DSLLV;
5015 SecondShift = Mips::DSRLV;
5016 break;
5017 }
5018
5019 ATReg = getATReg(Inst.getLoc());
5020 if (!ATReg)
5021 return true;
5022
5023 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5024 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5025 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5026 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5027
5028 return false;
5029 }
5030
5031 return true;
5032}
5033
5034bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5035 MCStreamer &Out,
5036 const MCSubtargetInfo *STI) {
5037 MipsTargetStreamer &TOut = getTargetStreamer();
5038 unsigned ATReg = Mips::NoRegister;
5039 unsigned DReg = Inst.getOperand(0).getReg();
5040 unsigned SReg = Inst.getOperand(1).getReg();
5041 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5042
5043 unsigned FirstShift = Mips::NOP;
5044 unsigned SecondShift = Mips::NOP;
5045
5046 MCInst TmpInst;
5047
5048 if (hasMips64r2()) {
5049 unsigned FinalOpcode = Mips::NOP;
5050 if (ImmValue == 0)
5051 FinalOpcode = Mips::DROTR;
5052 else if (ImmValue % 32 == 0)
5053 FinalOpcode = Mips::DROTR32;
5054 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5055 if (Inst.getOpcode() == Mips::DROLImm)
5056 FinalOpcode = Mips::DROTR32;
5057 else
5058 FinalOpcode = Mips::DROTR;
5059 } else if (ImmValue >= 33) {
5060 if (Inst.getOpcode() == Mips::DROLImm)
5061 FinalOpcode = Mips::DROTR;
5062 else
5063 FinalOpcode = Mips::DROTR32;
5064 }
5065
5066 uint64_t ShiftValue = ImmValue % 32;
5067 if (Inst.getOpcode() == Mips::DROLImm)
5068 ShiftValue = (32 - ImmValue % 32) % 32;
5069
5070 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5071
5072 return false;
5073 }
5074
5075 if (hasMips64()) {
5076 if (ImmValue == 0) {
5077 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5078 return false;
5079 }
5080
5081 switch (Inst.getOpcode()) {
5082 default:
5083 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 5083)
;
5084 case Mips::DROLImm:
5085 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5086 FirstShift = Mips::DSLL;
5087 SecondShift = Mips::DSRL32;
5088 }
5089 if (ImmValue == 32) {
5090 FirstShift = Mips::DSLL32;
5091 SecondShift = Mips::DSRL32;
5092 }
5093 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5094 FirstShift = Mips::DSLL32;
5095 SecondShift = Mips::DSRL;
5096 }
5097 break;
5098 case Mips::DRORImm:
5099 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5100 FirstShift = Mips::DSRL;
5101 SecondShift = Mips::DSLL32;
5102 }
5103 if (ImmValue == 32) {
5104 FirstShift = Mips::DSRL32;
5105 SecondShift = Mips::DSLL32;
5106 }
5107 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5108 FirstShift = Mips::DSRL32;
5109 SecondShift = Mips::DSLL;
5110 }
5111 break;
5112 }
5113
5114 ATReg = getATReg(Inst.getLoc());
5115 if (!ATReg)
5116 return true;
5117
5118 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5119 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5120 Inst.getLoc(), STI);
5121 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5122
5123 return false;
5124 }
5125
5126 return true;
5127}
5128
5129bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5130 const MCSubtargetInfo *STI) {
5131 MipsTargetStreamer &TOut = getTargetStreamer();
5132 unsigned FirstRegOp = Inst.getOperand(0).getReg();
5133 unsigned SecondRegOp = Inst.getOperand(1).getReg();
5134
5135 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5136 if (FirstRegOp != SecondRegOp)
5137 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5138 else
5139 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5140 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5141
5142 return false;
5143}
5144
5145bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5146 const MCSubtargetInfo *STI) {
5147 MipsTargetStreamer &TOut = getTargetStreamer();
5148 unsigned ATReg = Mips::NoRegister;
5149 unsigned DstReg = Inst.getOperand(0).getReg();
5150 unsigned SrcReg = Inst.getOperand(1).getReg();
5151 int32_t ImmValue = Inst.getOperand(2).getImm();
5152
5153 ATReg = getATReg(IDLoc);
5154 if (!ATReg)
5155 return true;
5156
5157 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
5158 STI);
5159
5160 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5161 SrcReg, ATReg, IDLoc, STI);
5162
5163 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5164
5165 return false;
5166}
5167
5168bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5169 const MCSubtargetInfo *STI) {
5170 MipsTargetStreamer &TOut = getTargetStreamer();
5171 unsigned ATReg = Mips::NoRegister;
5172 unsigned DstReg = Inst.getOperand(0).getReg();
5173 unsigned SrcReg = Inst.getOperand(1).getReg();
5174 unsigned TmpReg = Inst.getOperand(2).getReg();
5175
5176 ATReg = getATReg(Inst.getLoc());
5177 if (!ATReg)
5178 return true;
5179
5180 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5181 SrcReg, TmpReg, IDLoc, STI);
5182
5183 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5184
5185 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5186 DstReg, DstReg, 0x1F, IDLoc, STI);
5187
5188 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5189
5190 if (useTraps()) {
5191 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5192 } else {
5193 MCContext & Context = TOut.getStreamer().getContext();
5194 MCSymbol * BrTarget = Context.createTempSymbol();
5195 MCOperand LabelOp =
5196 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5197
5198 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5199 if (AssemblerOptions.back()->isReorder())
5200 TOut.emitNop(IDLoc, STI);
5201 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5202
5203 TOut.getStreamer().emitLabel(BrTarget);
5204 }
5205 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5206
5207 return false;
5208}
5209
5210bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5211 const MCSubtargetInfo *STI) {
5212 MipsTargetStreamer &TOut = getTargetStreamer();
5213 unsigned ATReg = Mips::NoRegister;
5214 unsigned DstReg = Inst.getOperand(0).getReg();
5215 unsigned SrcReg = Inst.getOperand(1).getReg();
5216 unsigned TmpReg = Inst.getOperand(2).getReg();
5217
5218 ATReg = getATReg(IDLoc);
5219 if (!ATReg)
5220 return true;
5221
5222 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5223 SrcReg, TmpReg, IDLoc, STI);
5224
5225 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5226 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5227 if (useTraps()) {
5228 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5229 } else {
5230 MCContext & Context = TOut.getStreamer().getContext();
5231 MCSymbol * BrTarget = Context.createTempSymbol();
5232 MCOperand LabelOp =
5233 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5234
5235 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5236 if (AssemblerOptions.back()->isReorder())
5237 TOut.emitNop(IDLoc, STI);
5238 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5239
5240 TOut.getStreamer().emitLabel(BrTarget);
5241 }
5242
5243 return false;
5244}
5245
5246bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5247 const MCSubtargetInfo *STI) {
5248 MipsTargetStreamer &TOut = getTargetStreamer();
5249 unsigned DstReg = Inst.getOperand(0).getReg();
5250 unsigned SrcReg = Inst.getOperand(1).getReg();
5251 unsigned TmpReg = Inst.getOperand(2).getReg();
5252
5253 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5254 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5255
5256 return false;
5257}
5258
5259// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5260// lw $<reg+1>>, offset+4($reg2)'
5261// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5262// sw $<reg+1>>, offset+4($reg2)'
5263// for O32.
5264bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5265 MCStreamer &Out,
5266 const MCSubtargetInfo *STI,
5267 bool IsLoad) {
5268 if (!isABI_O32())
5269 return true;
5270
5271 warnIfNoMacro(IDLoc);
5272
5273 MipsTargetStreamer &TOut = getTargetStreamer();
5274 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5275 unsigned FirstReg = Inst.getOperand(0).getReg();
5276 unsigned SecondReg = nextReg(FirstReg);
5277 unsigned BaseReg = Inst.getOperand(1).getReg();
5278 if (!SecondReg)
5279 return true;
5280
5281 warnIfRegIndexIsAT(FirstReg, IDLoc);
5282
5283 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", 5284, __extension__
__PRETTY_FUNCTION__))
5284 "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", 5284, __extension__
__PRETTY_FUNCTION__))
;
5285
5286 MCOperand &FirstOffset = Inst.getOperand(2);
5287 signed NextOffset = FirstOffset.getImm() + 4;
5288 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5289
5290 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5291 return true;
5292
5293 // For loads, clobber the base register with the second load instead of the
5294 // first if the BaseReg == FirstReg.
5295 if (FirstReg != BaseReg || !IsLoad) {
5296 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5297 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5298 } else {
5299 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5300 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5301 }
5302
5303 return false;
5304}
5305
5306
5307// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5308// swc1 $<reg>, offset+4($reg2)'
5309// or if little endian to 'swc1 $<reg>, offset($reg2);
5310// swc1 $<reg+1>, offset+4($reg2)'
5311// for Mips1.
5312bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5313 MCStreamer &Out,
5314 const MCSubtargetInfo *STI) {
5315 if (!isABI_O32())
5316 return true;
5317
5318 warnIfNoMacro(IDLoc);
5319
5320 MipsTargetStreamer &TOut = getTargetStreamer();
5321 unsigned Opcode = Mips::SWC1;
5322 unsigned FirstReg = Inst.getOperand(0).getReg();
5323 unsigned SecondReg = nextReg(FirstReg);
5324 unsigned BaseReg = Inst.getOperand(1).getReg();
5325 if (!SecondReg)
5326 return true;
5327
5328 warnIfRegIndexIsAT(FirstReg, IDLoc);
5329
5330 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", 5331, __extension__
__PRETTY_FUNCTION__))
5331 "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", 5331, __extension__
__PRETTY_FUNCTION__))
;
5332
5333 MCOperand &FirstOffset = Inst.getOperand(2);
5334 signed NextOffset = FirstOffset.getImm() + 4;
5335 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5336
5337 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5338 return true;
5339
5340 if (!IsLittleEndian)
5341 std::swap(FirstReg, SecondReg);
5342
5343 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5344 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5345
5346 return false;
5347}
5348
5349bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5350 const MCSubtargetInfo *STI) {
5351 MipsTargetStreamer &TOut = getTargetStreamer();
5352
5353 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", 5353, __extension__
__PRETTY_FUNCTION__))
;
5354 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", 5356, __extension__
__PRETTY_FUNCTION__))
5355 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", 5356, __extension__
__PRETTY_FUNCTION__))
5356 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", 5356, __extension__
__PRETTY_FUNCTION__))
;
5357
5358 unsigned DstReg = Inst.getOperand(0).getReg();
5359 unsigned SrcReg = Inst.getOperand(1).getReg();
5360 unsigned OpReg = Inst.getOperand(2).getReg();
5361
5362 warnIfNoMacro(IDLoc);
5363
5364 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5365 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5366 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5367 return false;
5368 }
5369
5370 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5371 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5372 return false;
5373}
5374
5375bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5376 const MCSubtargetInfo *STI) {
5377 MipsTargetStreamer &TOut = getTargetStreamer();
5378
5379 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", 5379, __extension__
__PRETTY_FUNCTION__))
;
5380 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", 5382, __extension__
__PRETTY_FUNCTION__))
5381 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", 5382, __extension__
__PRETTY_FUNCTION__))
5382 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", 5382, __extension__
__PRETTY_FUNCTION__))
;
5383
5384 unsigned DstReg = Inst.getOperand(0).getReg();
5385 unsigned SrcReg = Inst.getOperand(1).getReg();
5386 int64_t Imm = Inst.getOperand(2).getImm();
5387
5388 warnIfNoMacro(IDLoc);
5389
5390 if (Imm == 0) {
5391 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5392 return false;
5393 }
5394
5395 if (SrcReg == Mips::ZERO) {
5396 Warning(IDLoc, "comparison is always false");
5397 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5398 DstReg, SrcReg, SrcReg, IDLoc, STI);
5399 return false;
5400 }
5401
5402 unsigned Opc;
5403 if (Imm > -0x8000 && Imm < 0) {
5404 Imm = -Imm;
5405 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5406 } else {
5407 Opc = Mips::XORi;
5408 }
5409
5410 if (!isUInt<16>(Imm)) {
5411 unsigned ATReg = getATReg(IDLoc);
5412 if (!ATReg)
5413 return true;
5414
5415 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5416 Out, STI))
5417 return true;
5418
5419 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5420 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5421 return false;
5422 }
5423
5424 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5425 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5426 return false;
5427}
5428
5429bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5430 const MCSubtargetInfo *STI) {
5431
5432 MipsTargetStreamer &TOut = getTargetStreamer();
5433
5434 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", 5434, __extension__
__PRETTY_FUNCTION__))
;
5435 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", 5437, __extension__
__PRETTY_FUNCTION__))
5436 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", 5437, __extension__
__PRETTY_FUNCTION__))
5437 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", 5437, __extension__
__PRETTY_FUNCTION__))
;
5438
5439 unsigned DstReg = Inst.getOperand(0).getReg();
5440 unsigned SrcReg = Inst.getOperand(1).getReg();
5441 unsigned OpReg = Inst.getOperand(2).getReg();
5442
5443 warnIfNoMacro(IDLoc);
5444
5445 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5446 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5447 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5448 return false;
5449 }
5450
5451 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5452 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5453 return false;
5454}
5455
5456bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5457 const MCSubtargetInfo *STI) {
5458 MipsTargetStreamer &TOut = getTargetStreamer();
5459
5460 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", 5460, __extension__
__PRETTY_FUNCTION__))
;
5461 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", 5463, __extension__
__PRETTY_FUNCTION__))
5462 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", 5463, __extension__
__PRETTY_FUNCTION__))
5463 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", 5463, __extension__
__PRETTY_FUNCTION__))
;
5464
5465 unsigned DstReg = Inst.getOperand(0).getReg();
5466 unsigned SrcReg = Inst.getOperand(1).getReg();
5467 int64_t ImmValue = Inst.getOperand(2).getImm();
5468
5469 warnIfNoMacro(IDLoc);
5470
5471 if (ImmValue == 0) {
5472 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5473 return false;
5474 }
5475
5476 if (SrcReg == Mips::ZERO) {
5477 Warning(IDLoc, "comparison is always true");
5478 if (loadImmediate(1, DstReg, Mips::NoRegister, true, false, IDLoc, Out,
5479 STI))
5480 return true;
5481 return false;
5482 }
5483
5484 unsigned Opc;
5485 if (ImmValue > -0x8000 && ImmValue < 0) {
5486 ImmValue = -ImmValue;
5487 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5488 } else {
5489 Opc = Mips::XORi;
5490 }
5491
5492 if (isUInt<16>(ImmValue)) {
5493 TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5494 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5495 return false;
5496 }
5497
5498 unsigned ATReg = getATReg(IDLoc);
5499 if (!ATReg)
5500 return true;
5501
5502 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
5503 false, IDLoc, Out, STI))
5504 return true;
5505
5506 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5507 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5508 return false;
5509}
5510
5511// Map the DSP accumulator and control register to the corresponding gpr
5512// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5513// do not map the DSP registers contigously to gpr registers.
5514static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5515 switch (Inst.getOpcode()) {
5516 case Mips::MFTLO:
5517 case Mips::MTTLO:
5518 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5519 case Mips::AC0:
5520 return Mips::ZERO;
5521 case Mips::AC1:
5522 return Mips::A0;
5523 case Mips::AC2:
5524 return Mips::T0;
5525 case Mips::AC3:
5526 return Mips::T4;
5527 default:
5528 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 5528)
;
5529 }
5530 case Mips::MFTHI:
5531 case Mips::MTTHI:
5532 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5533 case Mips::AC0:
5534 return Mips::AT;
5535 case Mips::AC1:
5536 return Mips::A1;
5537 case Mips::AC2:
5538 return Mips::T1;
5539 case Mips::AC3:
5540 return Mips::T5;
5541 default:
5542 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 5542)
;
5543 }
5544 case Mips::MFTACX:
5545 case Mips::MTTACX:
5546 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5547 case Mips::AC0:
5548 return Mips::V0;
5549 case Mips::AC1:
5550 return Mips::A2;
5551 case Mips::AC2:
5552 return Mips::T2;
5553 case Mips::AC3:
5554 return Mips::T6;
5555 default:
5556 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 5556)
;
5557 }
5558 case Mips::MFTDSP:
5559 case Mips::MTTDSP:
5560 return Mips::S0;
5561 default:
5562 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", 5562)
;
5563 }
5564}
5565
5566// Map the floating point register operand to the corresponding register
5567// operand.
5568static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5569 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5570 case Mips::F0: return Mips::ZERO;
5571 case Mips::F1: return Mips::AT;
5572 case Mips::F2: return Mips::V0;
5573 case Mips::F3: return Mips::V1;
5574 case Mips::F4: return Mips::A0;
5575 case Mips::F5: return Mips::A1;
5576 case Mips::F6: return Mips::A2;
5577 case Mips::F7: return Mips::A3;
5578 case Mips::F8: return Mips::T0;
5579 case Mips::F9: return Mips::T1;
5580 case Mips::F10: return Mips::T2;
5581 case Mips::F11: return Mips::T3;
5582 case Mips::F12: return Mips::T4;
5583 case Mips::F13: return Mips::T5;
5584 case Mips::F14: return Mips::T6;
5585 case Mips::F15: return Mips::T7;
5586 case Mips::F16: return Mips::S0;
5587 case Mips::F17: return Mips::S1;
5588 case Mips::F18: return Mips::S2;
5589 case Mips::F19: return Mips::S3;
5590 case Mips::F20: return Mips::S4;
5591 case Mips::F21: return Mips::S5;
5592 case Mips::F22: return Mips::S6;
5593 case Mips::F23: return Mips::S7;
5594 case Mips::F24: return Mips::T8;
5595 case Mips::F25: return Mips::T9;
5596 case Mips::F26: return Mips::K0;
5597 case Mips::F27: return Mips::K1;
5598 case Mips::F28: return Mips::GP;
5599 case Mips::F29: return Mips::SP;
5600 case Mips::F30: return Mips::FP;
5601 case Mips::F31: return Mips::RA;
5602 default: llvm_unreachable("Unknown register for mttc1 alias!")::llvm::llvm_unreachable_internal("Unknown register for mttc1 alias!"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 5602)
;
5603 }
5604}
5605
5606// Map the coprocessor operand the corresponding gpr register operand.
5607static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5608 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5609 case Mips::COP00: return Mips::ZERO;
5610 case Mips::COP01: return Mips::AT;
5611 case Mips::COP02: return Mips::V0;
5612 case Mips::COP03: return Mips::V1;
5613 case Mips::COP04: return Mips::A0;
5614 case Mips::COP05: return Mips::A1;
5615 case Mips::COP06: return Mips::A2;
5616 case Mips::COP07: return Mips::A3;
5617 case Mips::COP08: return Mips::T0;
5618 case Mips::COP09: return Mips::T1;
5619 case Mips::COP010: return Mips::T2;
5620 case Mips::COP011: return Mips::T3;
5621 case Mips::COP012: return Mips::T4;
5622 case Mips::COP013: return Mips::T5;
5623 case Mips::COP014: return Mips::T6;
5624 case Mips::COP015: return Mips::T7;
5625 case Mips::COP016: return Mips::S0;
5626 case Mips::COP017: return Mips::S1;
5627 case Mips::COP018: return Mips::S2;
5628 case Mips::COP019: return Mips::S3;
5629 case Mips::COP020: return Mips::S4;
5630 case Mips::COP021: return Mips::S5;
5631 case Mips::COP022: return Mips::S6;
5632 case Mips::COP023: return Mips::S7;
5633 case Mips::COP024: return Mips::T8;
5634 case Mips::COP025: return Mips::T9;
5635 case Mips::COP026: return Mips::K0;
5636 case Mips::COP027: return Mips::K1;
5637 case Mips::COP028: return Mips::GP;
5638 case Mips::COP029: return Mips::SP;
5639 case Mips::COP030: return Mips::FP;
5640 case Mips::COP031: return Mips::RA;
5641 default: llvm_unreachable("Unknown register for mttc0 alias!")::llvm::llvm_unreachable_internal("Unknown register for mttc0 alias!"
, "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp", 5641)
;
5642 }
5643}
5644
5645/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5646/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5647bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5648 const MCSubtargetInfo *STI) {
5649 MipsTargetStreamer &TOut = getTargetStreamer();
5650 unsigned rd = 0;
5651 unsigned u = 1;
5652 unsigned sel = 0;
5653 unsigned h = 0;
5654 bool IsMFTR = false;
5655 switch (Inst.getOpcode()) {
5656 case Mips::MFTC0:
5657 IsMFTR = true;
5658 [[fallthrough]];
5659 case Mips::MTTC0:
5660 u = 0;
5661 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5662 sel = Inst.getOperand(2).getImm();
5663 break;
5664 case Mips::MFTGPR:
5665 IsMFTR = true;
5666 [[fallthrough]];
5667 case Mips::MTTGPR:
5668 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5669 break;
5670 case Mips::MFTLO:
5671 case Mips::MFTHI:
5672 case Mips::MFTACX:
5673 case Mips::MFTDSP:
5674 IsMFTR = true;
5675 [[fallthrough]];
5676 case Mips::MTTLO:
5677 case Mips::MTTHI:
5678 case Mips::MTTACX:
5679 case Mips::MTTDSP:
5680 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5681 sel = 1;
5682 break;
5683 case Mips::MFTHC1:
5684 h = 1;
5685 [[fallthrough]];
5686 case Mips::MFTC1:
5687 IsMFTR = true;
5688 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5689 sel = 2;
5690 break;
5691 case Mips::MTTHC1:
5692 h = 1;
5693 [[fallthrough]];
5694 case Mips::MTTC1:
5695 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5696 sel = 2;
5697 break;
5698 case Mips::CFTC1:
5699 IsMFTR = true;
5700 [[fallthrough]];
5701 case Mips::CTTC1:
5702 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5703 sel = 3;
5704 break;
5705 }
5706 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5707 unsigned Op1 =
5708 IsMFTR ? rd
5709 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5710 : Inst.getOperand(0).getReg());
5711
5712 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5713 STI);
5714 return false;
5715}
5716
5717bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5718 const MCSubtargetInfo *STI) {
5719 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", 5719, __extension__
__PRETTY_FUNCTION__))
;
5720 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", 5720, __extension__
__PRETTY_FUNCTION__))
;
5721 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", 5721, __extension__
__PRETTY_FUNCTION__))
;
5722
5723 warnIfNoMacro(IDLoc);
5724
5725 MipsTargetStreamer &TOut = getTargetStreamer();
5726 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5727 unsigned RtReg = Inst.getOperand(0).getReg();
5728 unsigned BaseReg = Inst.getOperand(1).getReg();
5729 const MCOperand &BaseOp = Inst.getOperand(2);
5730
5731 if (BaseOp.isImm()) {
5732 int64_t ImmValue = BaseOp.getImm();
5733 if (ImmValue == 0) {
5734 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5735 return false;
5736 }
5737 }
5738
5739 unsigned ATReg = getATReg(IDLoc);
5740 if (!ATReg)
5741 return true;
5742
5743 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5744 return true;
5745
5746 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5747 return false;
5748}
5749
5750unsigned
5751MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5752 const OperandVector &Operands) {
5753 switch (Inst.getOpcode()) {
5754 default:
5755 return Match_Success;
5756 case Mips::DATI:
5757 case Mips::DAHI:
5758 if (static_cast<MipsOperand &>(*Operands[1])
5759 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5760 return Match_Success;
5761 return Match_RequiresSameSrcAndDst;
5762 }
5763}
5764
5765unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5766 switch (Inst.getOpcode()) {
5767 // As described by the MIPSR6 spec, daui must not use the zero operand for
5768 // its source operand.
5769 case Mips::DAUI:
5770 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5771 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5772 return Match_RequiresNoZeroRegister;
5773 return Match_Success;
5774 // As described by the Mips32r2 spec, the registers Rd and Rs for
5775 // jalr.hb must be different.
5776 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5777 // and registers Rd and Base for microMIPS lwp instruction
5778 case Mips::JALR_HB:
5779 case Mips::JALR_HB64:
5780 case Mips::JALRC_HB_MMR6:
5781 case Mips::JALRC_MMR6:
5782 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5783 return Match_RequiresDifferentSrcAndDst;
5784 return Match_Success;
5785 case Mips::LWP_MM:
5786 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5787 return Match_RequiresDifferentSrcAndDst;
5788 return Match_Success;
5789 case Mips::SYNC:
5790 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5791 return Match_NonZeroOperandForSync;
5792 return Match_Success;
5793 case Mips::MFC0:
5794 case Mips::MTC0:
5795 case Mips::MTC2:
5796 case Mips::MFC2:
5797 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5798 return Match_NonZeroOperandForMTCX;
5799 return Match_Success;
5800 // As described the MIPSR6 spec, the compact branches that compare registers
5801 // must:
5802 // a) Not use the zero register.
5803 // b) Not use the same register twice.
5804 // c) rs < rt for bnec, beqc.
5805 // NB: For this case, the encoding will swap the operands as their
5806 // ordering doesn't matter. GAS performs this transformation too.
5807 // Hence, that constraint does not have to be enforced.
5808 //
5809 // The compact branches that branch iff the signed addition of two registers
5810 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5811 // operand swapping. They do not have restriction of using the zero register.
5812 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5813 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5814 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5815 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5816 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5817 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5818 case Mips::BLEZC64:
5819 case Mips::BGEZC64:
5820 case Mips::BGTZC64:
5821 case Mips::BLTZC64:
5822 case Mips::BEQZC64:
5823 case Mips::BNEZC64:
5824 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5825 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5826 return Match_RequiresNoZeroRegister;
5827 return Match_Success;
5828 case Mips::BGEC: case Mips::BGEC_MMR6:
5829 case Mips::BLTC: case Mips::BLTC_MMR6:
5830 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5831 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5832 case Mips::BEQC: case Mips::BEQC_MMR6:
5833 case Mips::BNEC: case Mips::BNEC_MMR6:
5834 case Mips::BGEC64:
5835 case Mips::BLTC64:
5836 case Mips::BGEUC64:
5837 case Mips::BLTUC64:
5838 case Mips::BEQC64:
5839 case Mips::BNEC64:
5840 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5841 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5842 return Match_RequiresNoZeroRegister;
5843 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5844 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5845 return Match_RequiresNoZeroRegister;
5846 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5847 return Match_RequiresDifferentOperands;
5848 return Match_Success;
5849 case Mips::DINS: {
5850 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", 5851, __extension__
__PRETTY_FUNCTION__))
5851 "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", 5851, __extension__
__PRETTY_FUNCTION__))
;
5852 const signed Pos = Inst.getOperand(2).getImm();
5853 const signed Size = Inst.getOperand(3).getImm();
5854 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5855 return Match_RequiresPosSizeRange0_32;
5856 return Match_Success;
5857 }
5858 case Mips::DINSM:
5859 case Mips::DINSU: {
5860 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", 5861, __extension__
__PRETTY_FUNCTION__))
5861 "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", 5861, __extension__
__PRETTY_FUNCTION__))
;
5862 const signed Pos = Inst.getOperand(2).getImm();
5863 const signed Size = Inst.getOperand(3).getImm();
5864 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5865 return Match_RequiresPosSizeRange33_64;
5866 return Match_Success;
5867 }
5868 case Mips::DEXT: {
5869 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&(static_cast <bool> (Inst.getOperand(2).isImm() &&
Inst.getOperand(3).isImm() && "Operands must be immediates for 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", 5870, __extension__
__PRETTY_FUNCTION__))
5870 "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", 5870, __extension__
__PRETTY_FUNCTION__))
;
5871 const signed Pos = Inst.getOperand(2).getImm();
5872 const signed Size = Inst.getOperand(3).getImm();
5873 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5874 return Match_RequiresPosSizeUImm6;
5875 return Match_Success;
5876 }
5877 case Mips::DEXTM:
5878 case Mips::DEXTU: {
5879 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", 5880, __extension__
__PRETTY_FUNCTION__))
5880 "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", 5880, __extension__
__PRETTY_FUNCTION__))
;
5881 const signed Pos = Inst.getOperand(2).getImm();
5882 const signed Size = Inst.getOperand(3).getImm();
5883 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5884 return Match_RequiresPosSizeRange33_64;
5885 return Match_Success;
5886 }
5887 case Mips::CRC32B: case Mips::CRC32CB:
5888 case Mips::CRC32H: case Mips::CRC32CH:
5889 case Mips::CRC32W: case Mips::CRC32CW:
5890 case Mips::CRC32D: case Mips::CRC32CD:
5891 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5892 return Match_RequiresSameSrcAndDst;
5893 return Match_Success;
5894 }
5895
5896 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5897 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5898 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5899 return Match_NoFCCRegisterForCurrentISA;
5900
5901 return Match_Success;
5902
5903}
5904
5905static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5906 uint64_t ErrorInfo) {
5907 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5908 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5909 if (ErrorLoc == SMLoc())
5910 return Loc;
5911 return ErrorLoc;
5912 }
5913 return Loc;
5914}
5915
5916bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5917 OperandVector &Operands,
5918 MCStreamer &Out,
5919 uint64_t &ErrorInfo,
5920 bool MatchingInlineAsm) {
5921 MCInst Inst;
5922 unsigned MatchResult =
5923 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5924
5925 switch (MatchResult) {
5926 case Match_Success:
5927 if (processInstruction(Inst, IDLoc, Out, STI))
5928 return true;
5929 return false;
5930 case Match_MissingFeature:
5931 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5932 return true;
5933 case Match_InvalidTiedOperand:
5934 Error(IDLoc, "operand must match destination register");
5935 return true;
5936 case Match_InvalidOperand: {
5937 SMLoc ErrorLoc = IDLoc;
5938 if (ErrorInfo != ~0ULL) {
5939 if (ErrorInfo >= Operands.size())
5940 return Error(IDLoc, "too few operands for instruction");
5941
5942 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5943 if (ErrorLoc == SMLoc())
5944 ErrorLoc = IDLoc;
5945 }
5946
5947 return Error(ErrorLoc, "invalid operand for instruction");
5948 }
5949 case Match_NonZeroOperandForSync:
5950 return Error(IDLoc,
5951 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5952 case Match_NonZeroOperandForMTCX:
5953 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5954 case Match_MnemonicFail:
5955 return Error(IDLoc, "invalid instruction");
5956 case Match_RequiresDifferentSrcAndDst:
5957 return Error(IDLoc, "source and destination must be different");
5958 case Match_RequiresDifferentOperands:
5959 return Error(IDLoc, "registers must be different");
5960 case Match_RequiresNoZeroRegister:
5961 return Error(IDLoc, "invalid operand ($zero) for instruction");
5962 case Match_RequiresSameSrcAndDst:
5963 return Error(IDLoc, "source and destination must match");
5964 case Match_NoFCCRegisterForCurrentISA:
5965 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5966 "non-zero fcc register doesn't exist in current ISA level");
5967 case Match_Immz:
5968 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5969 case Match_UImm1_0:
5970 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5971 "expected 1-bit unsigned immediate");
5972 case Match_UImm2_0:
5973 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5974 "expected 2-bit unsigned immediate");
5975 case Match_UImm2_1:
5976 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5977 "expected immediate in range 1 .. 4");
5978 case Match_UImm3_0:
5979 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5980 "expected 3-bit unsigned immediate");
5981 case Match_UImm4_0:
5982 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5983 "expected 4-bit unsigned immediate");
5984 case Match_SImm4_0:
5985 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5986 "expected 4-bit signed immediate");
5987 case Match_UImm5_0:
5988 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5989 "expected 5-bit unsigned immediate");
5990 case Match_SImm5_0:
5991 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5992 "expected 5-bit signed immediate");
5993 case Match_UImm5_1:
5994 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5995 "expected immediate in range 1 .. 32");
5996 case Match_UImm5_32:
5997 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5998 "expected immediate in range 32 .. 63");
5999 case Match_UImm5_33:
6000 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6001 "expected immediate in range 33 .. 64");
6002 case Match_UImm5_0_Report_UImm6:
6003 // This is used on UImm5 operands that have a corresponding UImm5_32
6004 // operand to avoid confusing the user.
6005 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6006 "expected 6-bit unsigned immediate");
6007 case Match_UImm5_Lsl2:
6008 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6009 "expected both 7-bit unsigned immediate and multiple of 4");
6010 case Match_UImmRange2_64:
6011 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6012 "expected immediate in range 2 .. 64");
6013 case Match_UImm6_0:
6014 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6015 "expected 6-bit unsigned immediate");
6016 case Match_UImm6_Lsl2:
6017 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6018 "expected both 8-bit unsigned immediate and multiple of 4");
6019 case Match_SImm6_0:
6020 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6021 "expected 6-bit signed immediate");
6022 case Match_UImm7_0:
6023 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6024 "expected 7-bit unsigned immediate");
6025 case Match_UImm7_N1:
6026 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6027 "expected immediate in range -1 .. 126");
6028 case Match_SImm7_Lsl2:
6029 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6030 "expected both 9-bit signed immediate and multiple of 4");
6031 case Match_UImm8_0:
6032 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6033 "expected 8-bit unsigned immediate");
6034 case Match_UImm10_0:
6035 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6036 "expected 10-bit unsigned immediate");
6037 case Match_SImm10_0:
6038 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6039 "expected 10-bit signed immediate");
6040 case Match_SImm11_0:
6041 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6042 "expected 11-bit signed immediate");
6043 case Match_UImm16:
6044 case Match_UImm16_Relaxed:
6045 case Match_UImm16_AltRelaxed:
6046 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6047 "expected 16-bit unsigned immediate");
6048 case Match_SImm16:
6049 case Match_SImm16_Relaxed:
6050 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6051 "expected 16-bit signed immediate");
6052 case Match_SImm19_Lsl2:
6053 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6054 "expected both 19-bit signed immediate and multiple of 4");
6055 case Match_UImm20_0:
6056 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6057 "expected 20-bit unsigned immediate");
6058 case Match_UImm26_0:
6059 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6060 "expected 26-bit unsigned immediate");
6061 case Match_SImm32:
6062 case Match_SImm32_Relaxed:
6063 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6064 "expected 32-bit signed immediate");
6065 case Match_UImm32_Coerced:
6066 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6067 "expected 32-bit immediate");
6068 case Match_MemSImm9:
6069 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6070 "expected memory with 9-bit signed offset");
6071 case Match_MemSImm10:
6072 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6073 "expected memory with 10-bit signed offset");
6074 case Match_MemSImm10Lsl1:
6075 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6076 "expected memory with 11-bit signed offset and multiple of 2");
6077 case Match_MemSImm10Lsl2:
6078 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6079 "expected memory with 12-bit signed offset and multiple of 4");
6080 case Match_MemSImm10Lsl3:
6081 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6082 "expected memory with 13-bit signed offset and multiple of 8");
6083 case Match_MemSImm11:
6084 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6085 "expected memory with 11-bit signed offset");
6086 case Match_MemSImm12:
6087 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6088 "expected memory with 12-bit signed offset");
6089 case Match_MemSImm16:
6090 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6091 "expected memory with 16-bit signed offset");
6092 case Match_MemSImmPtr:
6093 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6094 "expected memory with 32-bit signed offset");
6095 case Match_RequiresPosSizeRange0_32: {
6096 SMLoc ErrorStart = Operands[3]->getStartLoc();
6097 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6098 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6099 SMRange(ErrorStart, ErrorEnd));
6100 }
6101 case Match_RequiresPosSizeUImm6: {
6102 SMLoc ErrorStart = Operands[3]->getStartLoc();
6103 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6104 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6105 SMRange(ErrorStart, ErrorEnd));
6106 }
6107 case Match_RequiresPosSizeRange33_64: {
6108 SMLoc ErrorStart = Operands[3]->getStartLoc();
6109 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6110 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6111 SMRange(ErrorStart, ErrorEnd));
6112 }
6113 }
6114
6115 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", 6115)
;
6116}
6117
6118void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
6119 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6120 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
6121 ") without \".set noat\"");
6122}
6123
6124void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6125 if (!AssemblerOptions.back()->isMacro())
6126 Warning(Loc, "macro instruction expanded into multiple instructions");
6127}
6128
6129void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6130 const OperandVector &Operands) {
6131 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", 6133, __extension__
__PRETTY_FUNCTION__))
6132 (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", 6133, __extension__
__PRETTY_FUNCTION__))
6133 "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", 6133, __extension__
__PRETTY_FUNCTION__))
;
6134 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6135 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6136 Inst.addOperand(MCOperand::createReg(NextReg));
6137 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6138}
6139
6140void
6141MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6142 SMRange Range, bool ShowColors) {
6143 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6144 Range, SMFixIt(Range, FixMsg),
6145 ShowColors);
6146}
6147
6148int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6149 int CC;
6150
6151 CC = StringSwitch<unsigned>(Name)
6152 .Case("zero", 0)
6153 .Cases("at", "AT", 1)
6154 .Case("a0", 4)
6155 .Case("a1", 5)
6156 .Case("a2", 6)
6157 .Case("a3", 7)
6158 .Case("v0", 2)
6159 .Case("v1", 3)
6160 .Case("s0", 16)
6161 .Case("s1", 17)
6162 .Case("s2", 18)
6163 .Case("s3", 19)
6164 .Case("s4", 20)
6165 .Case("s5", 21)
6166 .Case("s6", 22)
6167 .Case("s7", 23)
6168 .Case("k0", 26)
6169 .Case("k1", 27)
6170 .Case("gp", 28)
6171 .Case("sp", 29)
6172 .Case("fp", 30)
6173 .Case("s8", 30)
6174 .Case("ra", 31)
6175 .Case("t0", 8)
6176 .Case("t1", 9)
6177 .Case("t2", 10)
6178 .Case("t3", 11)
6179 .Case("t4", 12)
6180 .Case("t5", 13)
6181 .Case("t6", 14)
6182 .Case("t7", 15)
6183 .Case("t8", 24)
6184 .Case("t9", 25)
6185 .Default(-1);
6186
6187 if (!(isABI_N32() || isABI_N64()))
6188 return CC;
6189
6190 if (12 <= CC && CC <= 15) {
6191 // Name is one of t4-t7
6192 AsmToken RegTok = getLexer().peekTok();
6193 SMRange RegRange = RegTok.getLocRange();
6194
6195 StringRef FixedName = StringSwitch<StringRef>(Name)
6196 .Case("t4", "t0")
6197 .Case("t5", "t1")
6198 .Case("t6", "t2")
6199 .Case("t7", "t3")
6200 .Default("");
6201 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", 6201, __extension__
__PRETTY_FUNCTION__))
;
6202
6203 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6204 "Did you mean $" + FixedName + "?", RegRange);
6205 }
6206
6207 // Although SGI documentation just cuts out t0-t3 for n32/n64,
6208 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
6209 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
6210 if (8 <= CC && CC <= 11)
6211 CC += 4;
6212
6213 if (CC == -1)
6214 CC = StringSwitch<unsigned>(Name)
6215 .Case("a4", 8)
6216 .Case("a5", 9)
6217 .Case("a6", 10)
6218 .Case("a7", 11)
6219 .Case("kt0", 26)
6220 .Case("kt1", 27)
6221 .Default(-1);
6222
6223 return CC;
6224}
6225
6226int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6227 int CC;
6228
6229 CC = StringSwitch<unsigned>(Name)
6230 .Case("hwr_cpunum", 0)
6231 .Case("hwr_synci_step", 1)
6232 .Case("hwr_cc", 2)
6233 .Case("hwr_ccres", 3)
6234 .Case("hwr_ulr", 29)
6235 .Default(-1);
6236
6237 return CC;
6238}
6239
6240int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6241 if (Name[0] == 'f') {
6242 StringRef NumString = Name.substr(1);
6243 unsigned IntVal;
6244 if (NumString.getAsInteger(10, IntVal))
6245 return -1; // This is not an integer.
6246 if (IntVal > 31) // Maximum index for fpu register.
6247 return -1;
6248 return IntVal;
6249 }
6250 return -1;
6251}
6252
6253int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6254 if (Name.startswith("fcc")) {
6255 StringRef NumString = Name.substr(3);
6256 unsigned IntVal;
6257 if (NumString.getAsInteger(10, IntVal))
6258 return -1; // This is not an integer.
6259 if (IntVal > 7) // There are only 8 fcc registers.
6260 return -1;
6261 return IntVal;
6262 }
6263 return -1;
6264}
6265
6266int MipsAsmParser::matchACRegisterName(StringRef Name) {
6267 if (Name.startswith("ac")) {
6268 StringRef NumString = Name.substr(2);
6269 unsigned IntVal;
6270 if (NumString.getAsInteger(10, IntVal))
6271 return -1; // This is not an integer.
6272 if (IntVal > 3) // There are only 3 acc registers.
6273 return -1;
6274 return IntVal;
6275 }
6276 return -1;
6277}
6278
6279int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6280 unsigned IntVal;
6281
6282 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6283 return -1;
6284
6285 if (IntVal > 31)
6286 return -1;
6287
6288 return IntVal;
6289}
6290
6291int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6292 int CC;
6293
6294 CC = StringSwitch<unsigned>(Name)
6295 .Case("msair", 0)
6296 .Case("msacsr", 1)
6297 .Case("msaaccess", 2)
6298 .Case("msasave", 3)
6299 .Case("msamodify", 4)
6300 .Case("msarequest", 5)
6301 .Case("msamap", 6)
6302 .Case("msaunmap", 7)
6303 .Default(-1);
6304
6305 return CC;
6306}
6307
6308bool MipsAsmParser::canUseATReg() {
6309 return AssemblerOptions.back()->getATRegIndex() != 0;
6310}
6311
6312unsigned MipsAsmParser::getATReg(SMLoc Loc) {
6313 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6314 if (ATIndex == 0) {
6315 reportParseError(Loc,
6316 "pseudo-instruction requires $at, which is not available");
6317 return 0;
6318 }
6319 unsigned AT = getReg(
6320 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6321 return AT;
6322}
6323
6324unsigned MipsAsmParser::getReg(int RC, int RegNo) {
6325 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6326}
6327
6328bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6329 MCAsmParser &Parser = getParser();
6330 LLVM_DEBUG(dbgs() << "parseOperand\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseOperand\n"; } } while
(false)
;
6331
6332 // Check if the current operand has a custom associated parser, if so, try to
6333 // custom parse the operand, or fallback to the general approach.
6334 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6335 if (ResTy == MatchOperand_Success)
6336 return false;
6337 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6338 // there was a match, but an error occurred, in which case, just return that
6339 // the operand parsing failed.
6340 if (ResTy == MatchOperand_ParseFail)
6341 return true;
6342
6343 LLVM_DEBUG(dbgs() << ".. Generic Parser\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. Generic Parser\n";
} } while (false)
;
6344
6345 switch (getLexer().getKind()) {
6346 case AsmToken::Dollar: {
6347 // Parse the register.
6348 SMLoc S = Parser.getTok().getLoc();
6349
6350 // Almost all registers have been parsed by custom parsers. There is only
6351 // one exception to this. $zero (and it's alias $0) will reach this point
6352 // for div, divu, and similar instructions because it is not an operand
6353 // to the instruction definition but an explicit register. Special case
6354 // this situation for now.
6355 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
6356 return false;
6357
6358 // Maybe it is a symbol reference.
6359 StringRef Identifier;
6360 if (Parser.parseIdentifier(Identifier))
6361 return true;
6362
6363 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6364 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
6365 // Otherwise create a symbol reference.
6366 const MCExpr *Res =
6367 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
6368
6369 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
6370 return false;
6371 }
6372 default: {
6373 LLVM_DEBUG(dbgs() << ".. generic integer expression\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. generic integer expression\n"
; } } while (false)
;
6374
6375 const MCExpr *Expr;
6376 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6377 if (getParser().parseExpression(Expr))
6378 return true;
6379
6380 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6381
6382 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6383 return false;
6384 }
6385 } // switch(getLexer().getKind())
6386 return true;
6387}
6388
6389bool MipsAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
6390 SMLoc &EndLoc) {
6391 return tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success;
6392}
6393
6394OperandMatchResultTy MipsAsmParser::tryParseRegister(MCRegister &RegNo,
6395 SMLoc &StartLoc,
6396 SMLoc &EndLoc) {
6397 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6398 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6399 if (ResTy == MatchOperand_Success) {
6400 assert(Operands.size() == 1)(static_cast <bool> (Operands.size() == 1) ? void (0) :
__assert_fail ("Operands.size() == 1", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 6400, __extension__ __PRETTY_FUNCTION__))
;
6401 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6402 StartLoc = Operand.getStartLoc();
6403 EndLoc = Operand.getEndLoc();
6404
6405 // AFAIK, we only support numeric registers and named GPR's in CFI
6406 // directives.
6407 // Don't worry about eating tokens before failing. Using an unrecognised
6408 // register is a parse error.
6409 if (Operand.isGPRAsmReg()) {
6410 // Resolve to GPR32 or GPR64 appropriately.
6411 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6412 }
6413
6414 return (RegNo == (unsigned)-1) ? MatchOperand_NoMatch
6415 : MatchOperand_Success;
6416 }
6417
6418 assert(Operands.size() == 0)(static_cast <bool> (Operands.size() == 0) ? void (0) :
__assert_fail ("Operands.size() == 0", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 6418, __extension__ __PRETTY_FUNCTION__))
;
6419 return (RegNo == (unsigned)-1) ? MatchOperand_NoMatch : MatchOperand_Success;
6420}
6421
6422bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
6423 SMLoc S;
6424
6425 if (isParenExpr)
6426 return getParser().parseParenExprOfDepth(0, Res, S);
6427 return getParser().parseExpression(Res);
6428}
6429
6430OperandMatchResultTy
6431MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6432 MCAsmParser &Parser = getParser();
6433 LLVM_DEBUG(dbgs() << "parseMemOperand\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseMemOperand\n"; }
} while (false)
;
6434 const MCExpr *IdVal = nullptr;
6435 SMLoc S;
6436 bool isParenExpr = false;
6437 OperandMatchResultTy Res = MatchOperand_NoMatch;
6438 // First operand is the offset.
6439 S = Parser.getTok().getLoc();
6440
6441 if (getLexer().getKind() == AsmToken::LParen) {
6442 Parser.Lex();
6443 isParenExpr = true;
6444 }
6445
6446 if (getLexer().getKind() != AsmToken::Dollar) {
6447 if (parseMemOffset(IdVal, isParenExpr))
6448 return MatchOperand_ParseFail;
6449
6450 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6451 if (Tok.isNot(AsmToken::LParen)) {
6452 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6453 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6454 SMLoc E =
6455 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6456 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6457 return MatchOperand_Success;
6458 }
6459 if (Tok.is(AsmToken::EndOfStatement)) {
6460 SMLoc E =
6461 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6462
6463 // Zero register assumed, add a memory operand with ZERO as its base.
6464 // "Base" will be managed by k_Memory.
6465 auto Base = MipsOperand::createGPRReg(
6466 0, "0", getContext().getRegisterInfo(), S, E, *this);
6467 Operands.push_back(
6468 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6469 return MatchOperand_Success;
6470 }
6471 MCBinaryExpr::Opcode Opcode;
6472 // GAS and LLVM treat comparison operators different. GAS will generate -1
6473 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6474 // highly unlikely to be found in a memory offset expression, we don't
6475 // handle them.
6476 switch (Tok.getKind()) {
6477 case AsmToken::Plus:
6478 Opcode = MCBinaryExpr::Add;
6479 Parser.Lex();
6480 break;
6481 case AsmToken::Minus:
6482 Opcode = MCBinaryExpr::Sub;
6483 Parser.Lex();
6484 break;
6485 case AsmToken::Star:
6486 Opcode = MCBinaryExpr::Mul;
6487 Parser.Lex();
6488 break;
6489 case AsmToken::Pipe:
6490 Opcode = MCBinaryExpr::Or;
6491 Parser.Lex();
6492 break;
6493 case AsmToken::Amp:
6494 Opcode = MCBinaryExpr::And;
6495 Parser.Lex();
6496 break;
6497 case AsmToken::LessLess:
6498 Opcode = MCBinaryExpr::Shl;
6499 Parser.Lex();
6500 break;
6501 case AsmToken::GreaterGreater:
6502 Opcode = MCBinaryExpr::LShr;
6503 Parser.Lex();
6504 break;
6505 case AsmToken::Caret:
6506 Opcode = MCBinaryExpr::Xor;
6507 Parser.Lex();
6508 break;
6509 case AsmToken::Slash:
6510 Opcode = MCBinaryExpr::Div;
6511 Parser.Lex();
6512 break;
6513 case AsmToken::Percent:
6514 Opcode = MCBinaryExpr::Mod;
6515 Parser.Lex();
6516 break;
6517 default:
6518 Error(Parser.getTok().getLoc(), "'(' or expression expected");
6519 return MatchOperand_ParseFail;
6520 }
6521 const MCExpr * NextExpr;
6522 if (getParser().parseExpression(NextExpr))
6523 return MatchOperand_ParseFail;
6524 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6525 }
6526
6527 Parser.Lex(); // Eat the '(' token.
6528 }
6529
6530 Res = parseAnyRegister(Operands);
6531 if (Res != MatchOperand_Success)
6532 return Res;
6533
6534 if (Parser.getTok().isNot(AsmToken::RParen)) {
6535 Error(Parser.getTok().getLoc(), "')' expected");
6536 return MatchOperand_ParseFail;
6537 }
6538
6539 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6540
6541 Parser.Lex(); // Eat the ')' token.
6542
6543 if (!IdVal)
6544 IdVal = MCConstantExpr::create(0, getContext());
6545
6546 // Replace the register operand with the memory operand.
6547 std::unique_ptr<MipsOperand> op(
6548 static_cast<MipsOperand *>(Operands.back().release()));
6549 // Remove the register from the operands.
6550 // "op" will be managed by k_Memory.
6551 Operands.pop_back();
6552 // Add the memory operand.
6553 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6554 int64_t Imm;
6555 if (IdVal->evaluateAsAbsolute(Imm))
6556 IdVal = MCConstantExpr::create(Imm, getContext());
6557 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6558 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6559 getContext());
6560 }
6561
6562 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6563 return MatchOperand_Success;
6564}
6565
6566bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6567 MCAsmParser &Parser = getParser();
6568 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6569 if (!Sym)
6570 return false;
6571
6572 SMLoc S = Parser.getTok().getLoc();
6573 if (Sym->isVariable()) {
6574 const MCExpr *Expr = Sym->getVariableValue();
6575 if (Expr->getKind() == MCExpr::SymbolRef) {
6576 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6577 StringRef DefSymbol = Ref->getSymbol().getName();
6578 if (DefSymbol.startswith("$")) {
6579 OperandMatchResultTy ResTy =
6580 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6581 if (ResTy == MatchOperand_Success) {
6582 Parser.Lex();
6583 return true;
6584 }
6585 if (ResTy == MatchOperand_ParseFail)
6586 llvm_unreachable("Should never ParseFail")::llvm::llvm_unreachable_internal("Should never ParseFail", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 6586)
;
6587 }
6588 }
6589 } else if (Sym->isUnset()) {
6590 // If symbol is unset, it might be created in the `parseSetAssignment`
6591 // routine as an alias for a numeric register name.
6592 // Lookup in the aliases list.
6593 auto Entry = RegisterSets.find(Sym->getName());
6594 if (Entry != RegisterSets.end()) {
6595 OperandMatchResultTy ResTy =
6596 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6597 if (ResTy == MatchOperand_Success) {
6598 Parser.Lex();
6599 return true;
6600 }
6601 }
6602 }
6603
6604 return false;
6605}
6606
6607OperandMatchResultTy
6608MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6609 StringRef Identifier,
6610 SMLoc S) {
6611 int Index = matchCPURegisterName(Identifier);
6612 if (Index != -1) {
6613 Operands.push_back(MipsOperand::createGPRReg(
6614 Index, Identifier, getContext().getRegisterInfo(), S,
6615 getLexer().getLoc(), *this));
6616 return MatchOperand_Success;
6617 }
6618
6619 Index = matchHWRegsRegisterName(Identifier);
6620 if (Index != -1) {
6621 Operands.push_back(MipsOperand::createHWRegsReg(
6622 Index, Identifier, getContext().getRegisterInfo(), S,
6623 getLexer().getLoc(), *this));
6624 return MatchOperand_Success;
6625 }
6626
6627 Index = matchFPURegisterName(Identifier);
6628 if (Index != -1) {
6629 Operands.push_back(MipsOperand::createFGRReg(
6630 Index, Identifier, getContext().getRegisterInfo(), S,
6631 getLexer().getLoc(), *this));
6632 return MatchOperand_Success;
6633 }
6634
6635 Index = matchFCCRegisterName(Identifier);
6636 if (Index != -1) {
6637 Operands.push_back(MipsOperand::createFCCReg(
6638 Index, Identifier, getContext().getRegisterInfo(), S,
6639 getLexer().getLoc(), *this));
6640 return MatchOperand_Success;
6641 }
6642
6643 Index = matchACRegisterName(Identifier);
6644 if (Index != -1) {
6645 Operands.push_back(MipsOperand::createACCReg(
6646 Index, Identifier, getContext().getRegisterInfo(), S,
6647 getLexer().getLoc(), *this));
6648 return MatchOperand_Success;
6649 }
6650
6651 Index = matchMSA128RegisterName(Identifier);
6652 if (Index != -1) {
6653 Operands.push_back(MipsOperand::createMSA128Reg(
6654 Index, Identifier, getContext().getRegisterInfo(), S,
6655 getLexer().getLoc(), *this));
6656 return MatchOperand_Success;
6657 }
6658
6659 Index = matchMSA128CtrlRegisterName(Identifier);
6660 if (Index != -1) {
6661 Operands.push_back(MipsOperand::createMSACtrlReg(
6662 Index, Identifier, getContext().getRegisterInfo(), S,
6663 getLexer().getLoc(), *this));
6664 return MatchOperand_Success;
6665 }
6666
6667 return MatchOperand_NoMatch;
6668}
6669
6670OperandMatchResultTy
6671MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6672 const AsmToken &Token, SMLoc S) {
6673 if (Token.is(AsmToken::Identifier)) {
6674 LLVM_DEBUG(dbgs() << ".. identifier\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. identifier\n"; } }
while (false)
;
6675 StringRef Identifier = Token.getIdentifier();
6676 OperandMatchResultTy ResTy =
6677 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6678 return ResTy;
6679 } else if (Token.is(AsmToken::Integer)) {
6680 LLVM_DEBUG(dbgs() << ".. integer\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. integer\n"; } } while
(false)
;
6681 int64_t RegNum = Token.getIntVal();
6682 if (RegNum < 0 || RegNum > 31) {
6683 // Show the error, but treat invalid register
6684 // number as a normal one to continue parsing
6685 // and catch other possible errors.
6686 Error(getLexer().getLoc(), "invalid register number");
6687 }
6688 Operands.push_back(MipsOperand::createNumericReg(
6689 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6690 Token.getLoc(), *this));
6691 return MatchOperand_Success;
6692 }
6693
6694 LLVM_DEBUG(dbgs() << Token.getKind() << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << Token.getKind() <<
"\n"; } } while (false)
;
6695
6696 return MatchOperand_NoMatch;
6697}
6698
6699OperandMatchResultTy
6700MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6701 auto Token = getLexer().peekTok(false);
6702 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6703}
6704
6705OperandMatchResultTy
6706MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6707 MCAsmParser &Parser = getParser();
6708 LLVM_DEBUG(dbgs() << "parseAnyRegister\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseAnyRegister\n"; }
} while (false)
;
6709
6710 auto Token = Parser.getTok();
6711
6712 SMLoc S = Token.getLoc();
6713
6714 if (Token.isNot(AsmToken::Dollar)) {
6715 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. !$ -> try sym aliasing\n"
; } } while (false)
;
6716 if (Token.is(AsmToken::Identifier)) {
6717 if (searchSymbolAlias(Operands))
6718 return MatchOperand_Success;
6719 }
6720 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. !symalias -> NoMatch\n"
; } } while (false)
;
6721 return MatchOperand_NoMatch;
6722 }
6723 LLVM_DEBUG(dbgs() << ".. $\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. $\n"; } } while (false
)
;
6724
6725 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6726 if (ResTy == MatchOperand_Success) {
6727 Parser.Lex(); // $
6728 Parser.Lex(); // identifier
6729 }
6730 return ResTy;
6731}
6732
6733OperandMatchResultTy
6734MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6735 MCAsmParser &Parser = getParser();
6736 LLVM_DEBUG(dbgs() << "parseJumpTarget\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseJumpTarget\n"; }
} while (false)
;
6737
6738 SMLoc S = getLexer().getLoc();
6739
6740 // Registers are a valid target and have priority over symbols.
6741 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6742 if (ResTy != MatchOperand_NoMatch)
6743 return ResTy;
6744
6745 // Integers and expressions are acceptable
6746 const MCExpr *Expr = nullptr;
6747 if (Parser.parseExpression(Expr)) {
6748 // We have no way of knowing if a symbol was consumed so we must ParseFail
6749 return MatchOperand_ParseFail;
6750 }
6751 Operands.push_back(
6752 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6753 return MatchOperand_Success;
6754}
6755
6756OperandMatchResultTy
6757MipsAsmParser::parseInvNum(OperandVector &Operands) {
6758 MCAsmParser &Parser = getParser();
6759 const MCExpr *IdVal;
6760 // If the first token is '$' we may have register operand. We have to reject
6761 // cases where it is not a register. Complicating the matter is that
6762 // register names are not reserved across all ABIs.
6763 // Peek past the dollar to see if it's a register name for this ABI.
6764 SMLoc S = Parser.getTok().getLoc();
6765 if (Parser.getTok().is(AsmToken::Dollar)) {
6766 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6767 ? MatchOperand_ParseFail
6768 : MatchOperand_NoMatch;
6769 }
6770 if (getParser().parseExpression(IdVal))
6771 return MatchOperand_ParseFail;
6772 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6773 if (!MCE)
6774 return MatchOperand_NoMatch;
6775 int64_t Val = MCE->getValue();
6776 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6777 Operands.push_back(MipsOperand::CreateImm(
6778 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6779 return MatchOperand_Success;
6780}
6781
6782OperandMatchResultTy
6783MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6784 MCAsmParser &Parser = getParser();
6785 SmallVector<unsigned, 10> Regs;
6786 unsigned RegNo;
6787 unsigned PrevReg = Mips::NoRegister;
6788 bool RegRange = false;
6789 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6790
6791 if (Parser.getTok().isNot(AsmToken::Dollar))
6792 return MatchOperand_ParseFail;
6793
6794 SMLoc S = Parser.getTok().getLoc();
6795 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6796 SMLoc E = getLexer().getLoc();
6797 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6798 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6799 if (RegRange) {
6800 // Remove last register operand because registers from register range
6801 // should be inserted first.
6802 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6803 (!isGP64bit() && RegNo == Mips::RA)) {
6804 Regs.push_back(RegNo);
6805 } else {
6806 unsigned TmpReg = PrevReg + 1;
6807 while (TmpReg <= RegNo) {
6808 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6809 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6810 isGP64bit())) {
6811 Error(E, "invalid register operand");
6812 return MatchOperand_ParseFail;
6813 }
6814
6815 PrevReg = TmpReg;
6816 Regs.push_back(TmpReg++);
6817 }
6818 }
6819
6820 RegRange = false;
6821 } else {
6822 if ((PrevReg == Mips::NoRegister) &&
6823 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6824 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6825 Error(E, "$16 or $31 expected");
6826 return MatchOperand_ParseFail;
6827 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6828 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6829 !isGP64bit()) ||
6830 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6831 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6832 isGP64bit()))) {
6833 Error(E, "invalid register operand");
6834 return MatchOperand_ParseFail;
6835 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6836 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6837 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6838 isGP64bit()))) {
6839 Error(E, "consecutive register numbers expected");
6840 return MatchOperand_ParseFail;
6841 }
6842
6843 Regs.push_back(RegNo);
6844 }
6845
6846 if (Parser.getTok().is(AsmToken::Minus))
6847 RegRange = true;
6848
6849 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6850 !Parser.getTok().isNot(AsmToken::Comma)) {
6851 Error(E, "',' or '-' expected");
6852 return MatchOperand_ParseFail;
6853 }
6854
6855 Lex(); // Consume comma or minus
6856 if (Parser.getTok().isNot(AsmToken::Dollar))
6857 break;
6858
6859 PrevReg = RegNo;
6860 }
6861
6862 SMLoc E = Parser.getTok().getLoc();
6863 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6864 parseMemOperand(Operands);
6865 return MatchOperand_Success;
6866}
6867
6868/// Sometimes (i.e. load/stores) the operand may be followed immediately by
6869/// either this.
6870/// ::= '(', register, ')'
6871/// handle it before we iterate so we don't get tripped up by the lack of
6872/// a comma.
6873bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6874 MCAsmParser &Parser = getParser();
6875 if (getLexer().is(AsmToken::LParen)) {
6876 Operands.push_back(
6877 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6878 Parser.Lex();
6879 if (parseOperand(Operands, Name)) {
6880 SMLoc Loc = getLexer().getLoc();
6881 return Error(Loc, "unexpected token in argument list");
6882 }
6883 if (Parser.getTok().isNot(AsmToken::RParen)) {
6884 SMLoc Loc = getLexer().getLoc();
6885 return Error(Loc, "unexpected token, expected ')'");
6886 }
6887 Operands.push_back(
6888 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6889 Parser.Lex();
6890 }
6891 return false;
6892}
6893
6894/// Sometimes (i.e. in MSA) the operand may be followed immediately by
6895/// either one of these.
6896/// ::= '[', register, ']'
6897/// ::= '[', integer, ']'
6898/// handle it before we iterate so we don't get tripped up by the lack of
6899/// a comma.
6900bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6901 OperandVector &Operands) {
6902 MCAsmParser &Parser = getParser();
6903 if (getLexer().is(AsmToken::LBrac)) {
6904 Operands.push_back(
6905 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6906 Parser.Lex();
6907 if (parseOperand(Operands, Name)) {
6908 SMLoc Loc = getLexer().getLoc();
6909 return Error(Loc, "unexpected token in argument list");
6910 }
6911 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6912 SMLoc Loc = getLexer().getLoc();
6913 return Error(Loc, "unexpected token, expected ']'");
6914 }
6915 Operands.push_back(
6916 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6917 Parser.Lex();
6918 }
6919 return false;
6920}
6921
6922static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6923 unsigned VariantID = 0);
6924
6925bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6926 const MCParsedAsmOperand &Op2) const {
6927 // This target-overriden function exists to maintain current behaviour for
6928 // e.g.
6929 // dahi $3, $3, 0x5678
6930 // as tested in test/MC/Mips/mips64r6/valid.s.
6931 // FIXME: Should this test actually fail with an error? If so, then remove
6932 // this overloaded method.
6933 if (!Op1.isReg() || !Op2.isReg())
6934 return true;
6935 return Op1.getReg() == Op2.getReg();
6936}
6937
6938bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6939 SMLoc NameLoc, OperandVector &Operands) {
6940 MCAsmParser &Parser = getParser();
6941 LLVM_DEBUG(dbgs() << "ParseInstruction\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "ParseInstruction\n"; }
} while (false)
;
6942
6943 // We have reached first instruction, module directive are now forbidden.
6944 getTargetStreamer().forbidModuleDirective();
6945
6946 // Check if we have valid mnemonic
6947 if (!mnemonicIsValid(Name, 0)) {
6948 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6949 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6950 return Error(NameLoc, "unknown instruction" + Suggestion);
6951 }
6952 // First operand in MCInst is instruction mnemonic.
6953 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6954
6955 // Read the remaining operands.
6956 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6957 // Read the first operand.
6958 if (parseOperand(Operands, Name)) {
6959 SMLoc Loc = getLexer().getLoc();
6960 return Error(Loc, "unexpected token in argument list");
6961 }
6962 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6963 return true;
6964 // AFAIK, parenthesis suffixes are never on the first operand
6965
6966 while (getLexer().is(AsmToken::Comma)) {
6967 Parser.Lex(); // Eat the comma.
6968 // Parse and remember the operand.
6969 if (parseOperand(Operands, Name)) {
6970 SMLoc Loc = getLexer().getLoc();
6971 return Error(Loc, "unexpected token in argument list");
6972 }
6973 // Parse bracket and parenthesis suffixes before we iterate
6974 if (getLexer().is(AsmToken::LBrac)) {
6975 if (parseBracketSuffix(Name, Operands))
6976 return true;
6977 } else if (getLexer().is(AsmToken::LParen) &&
6978 parseParenSuffix(Name, Operands))
6979 return true;
6980 }
6981 }
6982 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6983 SMLoc Loc = getLexer().getLoc();
6984 return Error(Loc, "unexpected token in argument list");
6985 }
6986 Parser.Lex(); // Consume the EndOfStatement.
6987 return false;
6988}
6989
6990// FIXME: Given that these have the same name, these should both be
6991// consistent on affecting the Parser.
6992bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
6993 SMLoc Loc = getLexer().getLoc();
6994 return Error(Loc, ErrorMsg);
6995}
6996
6997bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
6998 return Error(Loc, ErrorMsg);
6999}
7000
7001bool MipsAsmParser::parseSetNoAtDirective() {
7002 MCAsmParser &Parser = getParser();
7003 // Line should look like: ".set noat".
7004
7005 // Set the $at register to $0.
7006 AssemblerOptions.back()->setATRegIndex(0);
7007
7008 Parser.Lex(); // Eat "noat".
7009
7010 // If this is not the end of the statement, report an error.
7011 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7012 reportParseError("unexpected token, expected end of statement");
7013 return false;
7014 }
7015
7016 getTargetStreamer().emitDirectiveSetNoAt();
7017 Parser.Lex(); // Consume the EndOfStatement.
7018 return false;
7019}
7020
7021bool MipsAsmParser::parseSetAtDirective() {
7022 // Line can be: ".set at", which sets $at to $1
7023 // or ".set at=$reg", which sets $at to $reg.
7024 MCAsmParser &Parser = getParser();
7025 Parser.Lex(); // Eat "at".
7026
7027 if (getLexer().is(AsmToken::EndOfStatement)) {
7028 // No register was specified, so we set $at to $1.
7029 AssemblerOptions.back()->setATRegIndex(1);
7030
7031 getTargetStreamer().emitDirectiveSetAt();
7032 Parser.Lex(); // Consume the EndOfStatement.
7033 return false;
7034 }
7035
7036 if (getLexer().isNot(AsmToken::Equal)) {
7037 reportParseError("unexpected token, expected equals sign");
7038 return false;
7039 }
7040 Parser.Lex(); // Eat "=".
7041
7042 if (getLexer().isNot(AsmToken::Dollar)) {
7043 if (getLexer().is(AsmToken::EndOfStatement)) {
7044 reportParseError("no register specified");
7045 return false;
7046 } else {
7047 reportParseError("unexpected token, expected dollar sign '$'");
7048 return false;
7049 }
7050 }
7051 Parser.Lex(); // Eat "$".
7052
7053 // Find out what "reg" is.
7054 unsigned AtRegNo;
7055 const AsmToken &Reg = Parser.getTok();
7056 if (Reg.is(AsmToken::Identifier)) {
7057 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7058 } else if (Reg.is(AsmToken::Integer)) {
7059 AtRegNo = Reg.getIntVal();
7060 } else {
7061 reportParseError("unexpected token, expected identifier or integer");
7062 return false;
7063 }
7064
7065 // Check if $reg is a valid register. If it is, set $at to $reg.
7066 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7067 reportParseError("invalid register");
7068 return false;
7069 }
7070 Parser.Lex(); // Eat "reg".
7071
7072 // If this is not the end of the statement, report an error.
7073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7074 reportParseError("unexpected token, expected end of statement");
7075 return false;
7076 }
7077
7078 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7079
7080 Parser.Lex(); // Consume the EndOfStatement.
7081 return false;
7082}
7083
7084bool MipsAsmParser::parseSetReorderDirective() {
7085 MCAsmParser &Parser = getParser();
7086 Parser.Lex();
7087 // If this is not the end of the statement, report an error.
7088 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7089 reportParseError("unexpected token, expected end of statement");
7090 return false;
7091 }
7092 AssemblerOptions.back()->setReorder();
7093 getTargetStreamer().emitDirectiveSetReorder();
7094 Parser.Lex(); // Consume the EndOfStatement.
7095 return false;
7096}
7097
7098bool MipsAsmParser::parseSetNoReorderDirective() {
7099 MCAsmParser &Parser = getParser();
7100 Parser.Lex();
7101 // If this is not the end of the statement, report an error.
7102 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7103 reportParseError("unexpected token, expected end of statement");
7104 return false;
7105 }
7106 AssemblerOptions.back()->setNoReorder();
7107 getTargetStreamer().emitDirectiveSetNoReorder();
7108 Parser.Lex(); // Consume the EndOfStatement.
7109 return false;
7110}
7111
7112bool MipsAsmParser::parseSetMacroDirective() {
7113 MCAsmParser &Parser = getParser();
7114 Parser.Lex();
7115 // If this is not the end of the statement, report an error.
7116 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7117 reportParseError("unexpected token, expected end of statement");
7118 return false;
7119 }
7120 AssemblerOptions.back()->setMacro();
7121 getTargetStreamer().emitDirectiveSetMacro();
7122 Parser.Lex(); // Consume the EndOfStatement.
7123 return false;
7124}
7125
7126bool MipsAsmParser::parseSetNoMacroDirective() {
7127 MCAsmParser &Parser = getParser();
7128 Parser.Lex();
7129 // If this is not the end of the statement, report an error.
7130 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7131 reportParseError("unexpected token, expected end of statement");
7132 return false;
7133 }
7134 if (AssemblerOptions.back()->isReorder()) {
7135 reportParseError("`noreorder' must be set before `nomacro'");
7136 return false;
7137 }
7138 AssemblerOptions.back()->setNoMacro();
7139 getTargetStreamer().emitDirectiveSetNoMacro();
7140 Parser.Lex(); // Consume the EndOfStatement.
7141 return false;
7142}
7143
7144bool MipsAsmParser::parseSetMsaDirective() {
7145 MCAsmParser &Parser = getParser();
7146 Parser.Lex();
7147
7148 // If this is not the end of the statement, report an error.
7149 if (getLexer().isNot(AsmToken::EndOfStatement))
7150 return reportParseError("unexpected token, expected end of statement");
7151
7152 setFeatureBits(Mips::FeatureMSA, "msa");
7153 getTargetStreamer().emitDirectiveSetMsa();
7154 return false;
7155}
7156
7157bool MipsAsmParser::parseSetNoMsaDirective() {
7158 MCAsmParser &Parser = getParser();
7159 Parser.Lex();
7160
7161 // If this is not the end of the statement, report an error.
7162 if (getLexer().isNot(AsmToken::EndOfStatement))
7163 return reportParseError("unexpected token, expected end of statement");
7164
7165 clearFeatureBits(Mips::FeatureMSA, "msa");
7166 getTargetStreamer().emitDirectiveSetNoMsa();
7167 return false;
7168}
7169
7170bool MipsAsmParser::parseSetNoDspDirective() {
7171 MCAsmParser &Parser = getParser();
7172 Parser.Lex(); // Eat "nodsp".
7173
7174 // If this is not the end of the statement, report an error.
7175 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7176 reportParseError("unexpected token, expected end of statement");
7177 return false;
7178 }
7179
7180 clearFeatureBits(Mips::FeatureDSP, "dsp");
7181 getTargetStreamer().emitDirectiveSetNoDsp();
7182 return false;
7183}
7184
7185bool MipsAsmParser::parseSetNoMips3DDirective() {
7186 MCAsmParser &Parser = getParser();
7187 Parser.Lex(); // Eat "nomips3d".
7188
7189 // If this is not the end of the statement, report an error.
7190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7191 reportParseError("unexpected token, expected end of statement");
7192 return false;
7193 }
7194
7195 clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7196 getTargetStreamer().emitDirectiveSetNoMips3D();
7197 return false;
7198}
7199
7200bool MipsAsmParser::parseSetMips16Directive() {
7201 MCAsmParser &Parser = getParser();
7202 Parser.Lex(); // Eat "mips16".
7203
7204 // If this is not the end of the statement, report an error.
7205 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7206 reportParseError("unexpected token, expected end of statement");
7207 return false;
7208 }
7209
7210 setFeatureBits(Mips::FeatureMips16, "mips16");
7211 getTargetStreamer().emitDirectiveSetMips16();
7212 Parser.Lex(); // Consume the EndOfStatement.
7213 return false;
7214}
7215
7216bool MipsAsmParser::parseSetNoMips16Directive() {
7217 MCAsmParser &Parser = getParser();
7218 Parser.Lex(); // Eat "nomips16".
7219
7220 // If this is not the end of the statement, report an error.
7221 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7222 reportParseError("unexpected token, expected end of statement");
7223 return false;
7224 }
7225
7226 clearFeatureBits(Mips::FeatureMips16, "mips16");
7227 getTargetStreamer().emitDirectiveSetNoMips16();
7228 Parser.Lex(); // Consume the EndOfStatement.
7229 return false;
7230}
7231
7232bool MipsAsmParser::parseSetFpDirective() {
7233 MCAsmParser &Parser = getParser();
7234 MipsABIFlagsSection::FpABIKind FpAbiVal;
7235 // Line can be: .set fp=32
7236 // .set fp=xx
7237 // .set fp=64
7238 Parser.Lex(); // Eat fp token
7239 AsmToken Tok = Parser.getTok();
7240 if (Tok.isNot(AsmToken::Equal)) {
7241 reportParseError("unexpected token, expected equals sign '='");
7242 return false;
7243 }
7244 Parser.Lex(); // Eat '=' token.
7245 Tok = Parser.getTok();
7246
7247 if (!parseFpABIValue(FpAbiVal, ".set"))
7248 return false;
7249
7250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7251 reportParseError("unexpected token, expected end of statement");
7252 return false;
7253 }
7254 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7255 Parser.Lex(); // Consume the EndOfStatement.
7256 return false;
7257}
7258
7259bool MipsAsmParser::parseSetOddSPRegDirective() {
7260 MCAsmParser &Parser = getParser();
7261
7262 Parser.Lex(); // Eat "oddspreg".
7263 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7264 reportParseError("unexpected token, expected end of statement");
7265 return false;
7266 }
7267
7268 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7269 getTargetStreamer().emitDirectiveSetOddSPReg();
7270 return false;
7271}
7272
7273bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7274 MCAsmParser &Parser = getParser();
7275
7276 Parser.Lex(); // Eat "nooddspreg".
7277 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7278 reportParseError("unexpected token, expected end of statement");
7279 return false;
7280 }
7281
7282 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7283 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7284 return false;
7285}
7286
7287bool MipsAsmParser::parseSetMtDirective() {
7288 MCAsmParser &Parser = getParser();
7289 Parser.Lex(); // Eat "mt".
7290
7291 // If this is not the end of the statement, report an error.
7292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7293 reportParseError("unexpected token, expected end of statement");
7294 return false;
7295 }
7296
7297 setFeatureBits(Mips::FeatureMT, "mt");
7298 getTargetStreamer().emitDirectiveSetMt();
7299 Parser.Lex(); // Consume the EndOfStatement.
7300 return false;
7301}
7302
7303bool MipsAsmParser::parseSetNoMtDirective() {
7304 MCAsmParser &Parser = getParser();
7305 Parser.Lex(); // Eat "nomt".
7306
7307 // If this is not the end of the statement, report an error.
7308 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7309 reportParseError("unexpected token, expected end of statement");
7310 return false;
7311 }
7312
7313 clearFeatureBits(Mips::FeatureMT, "mt");
7314
7315 getTargetStreamer().emitDirectiveSetNoMt();
7316 Parser.Lex(); // Consume the EndOfStatement.
7317 return false;
7318}
7319
7320bool MipsAsmParser::parseSetNoCRCDirective() {
7321 MCAsmParser &Parser = getParser();
7322 Parser.Lex(); // Eat "nocrc".
7323
7324 // If this is not the end of the statement, report an error.
7325 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7326 reportParseError("unexpected token, expected end of statement");
7327 return false;
7328 }
7329
7330 clearFeatureBits(Mips::FeatureCRC, "crc");
7331
7332 getTargetStreamer().emitDirectiveSetNoCRC();
7333 Parser.Lex(); // Consume the EndOfStatement.
7334 return false;
7335}
7336
7337bool MipsAsmParser::parseSetNoVirtDirective() {
7338 MCAsmParser &Parser = getParser();
7339 Parser.Lex(); // Eat "novirt".
7340
7341 // If this is not the end of the statement, report an error.
7342 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7343 reportParseError("unexpected token, expected end of statement");
7344 return false;
7345 }
7346
7347 clearFeatureBits(Mips::FeatureVirt, "virt");
7348
7349 getTargetStreamer().emitDirectiveSetNoVirt();
7350 Parser.Lex(); // Consume the EndOfStatement.
7351 return false;
7352}
7353
7354bool MipsAsmParser::parseSetNoGINVDirective() {
7355 MCAsmParser &Parser = getParser();
7356 Parser.Lex(); // Eat "noginv".
7357
7358 // If this is not the end of the statement, report an error.
7359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7360 reportParseError("unexpected token, expected end of statement");
7361 return false;
7362 }
7363
7364 clearFeatureBits(Mips::FeatureGINV, "ginv");
7365
7366 getTargetStreamer().emitDirectiveSetNoGINV();
7367 Parser.Lex(); // Consume the EndOfStatement.
7368 return false;
7369}
7370
7371bool MipsAsmParser::parseSetPopDirective() {
7372 MCAsmParser &Parser = getParser();
7373 SMLoc Loc = getLexer().getLoc();
7374
7375 Parser.Lex();
7376 if (getLexer().isNot(AsmToken::EndOfStatement))
7377 return reportParseError("unexpected token, expected end of statement");
7378
7379 // Always keep an element on the options "stack" to prevent the user
7380 // from changing the initial options. This is how we remember them.
7381 if (AssemblerOptions.size() == 2)
7382 return reportParseError(Loc, ".set pop with no .set push");
7383
7384 MCSubtargetInfo &STI = copySTI();
7385 AssemblerOptions.pop_back();
7386 setAvailableFeatures(
7387 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7388 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7389
7390 getTargetStreamer().emitDirectiveSetPop();
7391 return false;
7392}
7393
7394bool MipsAsmParser::parseSetPushDirective() {
7395 MCAsmParser &Parser = getParser();
7396 Parser.Lex();
7397 if (getLexer().isNot(AsmToken::EndOfStatement))
7398 return reportParseError("unexpected token, expected end of statement");
7399
7400 // Create a copy of the current assembler options environment and push it.
7401 AssemblerOptions.push_back(
7402 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7403
7404 getTargetStreamer().emitDirectiveSetPush();
7405 return false;
7406}
7407
7408bool MipsAsmParser::parseSetSoftFloatDirective() {
7409 MCAsmParser &Parser = getParser();
7410 Parser.Lex();
7411 if (getLexer().isNot(AsmToken::EndOfStatement))
7412 return reportParseError("unexpected token, expected end of statement");
7413
7414 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7415 getTargetStreamer().emitDirectiveSetSoftFloat();
7416 return false;
7417}
7418
7419bool MipsAsmParser::parseSetHardFloatDirective() {
7420 MCAsmParser &Parser = getParser();
7421 Parser.Lex();
7422 if (getLexer().isNot(AsmToken::EndOfStatement))
7423 return reportParseError("unexpected token, expected end of statement");
7424
7425 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7426 getTargetStreamer().emitDirectiveSetHardFloat();
7427 return false;
7428}
7429
7430bool MipsAsmParser::parseSetAssignment() {
7431 StringRef Name;
7432 MCAsmParser &Parser = getParser();
7433
7434 if (Parser.parseIdentifier(Name))
7435 return reportParseError("expected identifier after .set");
7436
7437 if (getLexer().isNot(AsmToken::Comma))
7438 return reportParseError("unexpected token, expected comma");
7439 Lex(); // Eat comma
7440
7441 if (getLexer().is(AsmToken::Dollar) &&
7442 getLexer().peekTok().is(AsmToken::Integer)) {
7443 // Parse assignment of a numeric register:
7444 // .set r1,$1
7445 Parser.Lex(); // Eat $.
7446 RegisterSets[Name] = Parser.getTok();
7447 Parser.Lex(); // Eat identifier.
7448 getContext().getOrCreateSymbol(Name);
7449 return false;
7450 }
7451
7452 MCSymbol *Sym;
7453 const MCExpr *Value;
7454 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7455 Parser, Sym, Value))
7456 return true;
7457 Sym->setVariableValue(Value);
7458
7459 return false;
7460}
7461
7462bool MipsAsmParser::parseSetMips0Directive() {
7463 MCAsmParser &Parser = getParser();
7464 Parser.Lex();
7465 if (getLexer().isNot(AsmToken::EndOfStatement))
7466 return reportParseError("unexpected token, expected end of statement");
7467
7468 // Reset assembler options to their initial values.
7469 MCSubtargetInfo &STI = copySTI();
7470 setAvailableFeatures(
7471 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7472 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7473 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7474
7475 getTargetStreamer().emitDirectiveSetMips0();
7476 return false;
7477}
7478
7479bool MipsAsmParser::parseSetArchDirective() {
7480 MCAsmParser &Parser = getParser();
7481 Parser.Lex();
7482 if (getLexer().isNot(AsmToken::Equal))
7483 return reportParseError("unexpected token, expected equals sign");
7484
7485 Parser.Lex();
7486 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7487 if (Arch.empty())
7488 return reportParseError("expected arch identifier");
7489
7490 StringRef ArchFeatureName =
7491 StringSwitch<StringRef>(Arch)
7492 .Case("mips1", "mips1")
7493 .Case("mips2", "mips2")
7494 .Case("mips3", "mips3")
7495 .Case("mips4", "mips4")
7496 .Case("mips5", "mips5")
7497 .Case("mips32", "mips32")
7498 .Case("mips32r2", "mips32r2")
7499 .Case("mips32r3", "mips32r3")
7500 .Case("mips32r5", "mips32r5")
7501 .Case("mips32r6", "mips32r6")
7502 .Case("mips64", "mips64")
7503 .Case("mips64r2", "mips64r2")
7504 .Case("mips64r3", "mips64r3")
7505 .Case("mips64r5", "mips64r5")
7506 .Case("mips64r6", "mips64r6")
7507 .Case("octeon", "cnmips")
7508 .Case("octeon+", "cnmipsp")
7509 .Case("r4000", "mips3") // This is an implementation of Mips3.
7510 .Default("");
7511
7512 if (ArchFeatureName.empty())
7513 return reportParseError("unsupported architecture");
7514
7515 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7516 return reportParseError("mips64r6 does not support microMIPS");
7517
7518 selectArch(ArchFeatureName);
7519 getTargetStreamer().emitDirectiveSetArch(Arch);
7520 return false;
7521}
7522
7523bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7524 MCAsmParser &Parser = getParser();
7525 Parser.Lex();
7526 if (getLexer().isNot(AsmToken::EndOfStatement))
7527 return reportParseError("unexpected token, expected end of statement");
7528
7529 switch (Feature) {
7530 default:
7531 llvm_unreachable("Unimplemented feature")::llvm::llvm_unreachable_internal("Unimplemented feature", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 7531)
;
7532 case Mips::FeatureMips3D:
7533 setFeatureBits(Mips::FeatureMips3D, "mips3d");
7534 getTargetStreamer().emitDirectiveSetMips3D();
7535 break;
7536 case Mips::FeatureDSP:
7537 setFeatureBits(Mips::FeatureDSP, "dsp");
7538 getTargetStreamer().emitDirectiveSetDsp();
7539 break;
7540 case Mips::FeatureDSPR2:
7541 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7542 getTargetStreamer().emitDirectiveSetDspr2();
7543 break;
7544 case Mips::FeatureMicroMips:
7545 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7546 getTargetStreamer().emitDirectiveSetMicroMips();
7547 break;
7548 case Mips::FeatureMips1:
7549 selectArch("mips1");
7550 getTargetStreamer().emitDirectiveSetMips1();
7551 break;
7552 case Mips::FeatureMips2:
7553 selectArch("mips2");
7554 getTargetStreamer().emitDirectiveSetMips2();
7555 break;
7556 case Mips::FeatureMips3:
7557 selectArch("mips3");
7558 getTargetStreamer().emitDirectiveSetMips3();
7559 break;
7560 case Mips::FeatureMips4:
7561 selectArch("mips4");
7562 getTargetStreamer().emitDirectiveSetMips4();
7563 break;
7564 case Mips::FeatureMips5:
7565 selectArch("mips5");
7566 getTargetStreamer().emitDirectiveSetMips5();
7567 break;
7568 case Mips::FeatureMips32:
7569 selectArch("mips32");
7570 getTargetStreamer().emitDirectiveSetMips32();
7571 break;
7572 case Mips::FeatureMips32r2:
7573 selectArch("mips32r2");
7574 getTargetStreamer().emitDirectiveSetMips32R2();
7575 break;
7576 case Mips::FeatureMips32r3:
7577 selectArch("mips32r3");
7578 getTargetStreamer().emitDirectiveSetMips32R3();
7579 break;
7580 case Mips::FeatureMips32r5:
7581 selectArch("mips32r5");
7582 getTargetStreamer().emitDirectiveSetMips32R5();
7583 break;
7584 case Mips::FeatureMips32r6:
7585 selectArch("mips32r6");
7586 getTargetStreamer().emitDirectiveSetMips32R6();
7587 break;
7588 case Mips::FeatureMips64:
7589 selectArch("mips64");
7590 getTargetStreamer().emitDirectiveSetMips64();
7591 break;
7592 case Mips::FeatureMips64r2:
7593 selectArch("mips64r2");
7594 getTargetStreamer().emitDirectiveSetMips64R2();
7595 break;
7596 case Mips::FeatureMips64r3:
7597 selectArch("mips64r3");
7598 getTargetStreamer().emitDirectiveSetMips64R3();
7599 break;
7600 case Mips::FeatureMips64r5:
7601 selectArch("mips64r5");
7602 getTargetStreamer().emitDirectiveSetMips64R5();
7603 break;
7604 case Mips::FeatureMips64r6:
7605 selectArch("mips64r6");
7606 getTargetStreamer().emitDirectiveSetMips64R6();
7607 break;
7608 case Mips::FeatureCRC:
7609 setFeatureBits(Mips::FeatureCRC, "crc");
7610 getTargetStreamer().emitDirectiveSetCRC();
7611 break;
7612 case Mips::FeatureVirt:
7613 setFeatureBits(Mips::FeatureVirt, "virt");
7614 getTargetStreamer().emitDirectiveSetVirt();
7615 break;
7616 case Mips::FeatureGINV:
7617 setFeatureBits(Mips::FeatureGINV, "ginv");
7618 getTargetStreamer().emitDirectiveSetGINV();
7619 break;
7620 }
7621 return false;
7622}
7623
7624bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7625 MCAsmParser &Parser = getParser();
7626 if (getLexer().isNot(AsmToken::Comma)) {
7627 SMLoc Loc = getLexer().getLoc();
7628 return Error(Loc, ErrorStr);
7629 }
7630
7631 Parser.Lex(); // Eat the comma.
7632 return true;
7633}
7634
7635// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7636// In this class, it is only used for .cprestore.
7637// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7638// MipsTargetELFStreamer and MipsAsmParser.
7639bool MipsAsmParser::isPicAndNotNxxAbi() {
7640 return inPicMode() && !(isABI_N32() || isABI_N64());
7641}
7642
7643bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7644 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7645 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7646 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7647 reportParseError("expected register");
7648 return false;
7649 }
7650
7651 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7652 if (!RegOpnd.isGPRAsmReg()) {
7653 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7654 return false;
7655 }
7656
7657 // If this is not the end of the statement, report an error.
7658 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7659 reportParseError("unexpected token, expected end of statement");
7660 return false;
7661 }
7662 getParser().Lex(); // Consume the EndOfStatement.
7663
7664 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7665 return false;
7666}
7667
7668bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7669 if (AssemblerOptions.back()->isReorder())
7670 Warning(Loc, ".cpload should be inside a noreorder section");
7671
7672 if (inMips16Mode()) {
7673 reportParseError(".cpload is not supported in Mips16 mode");
7674 return false;
7675 }
7676
7677 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7678 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7679 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7680 reportParseError("expected register containing function address");
7681 return false;
7682 }
7683
7684 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7685 if (!RegOpnd.isGPRAsmReg()) {
7686 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7687 return false;
7688 }
7689
7690 // If this is not the end of the statement, report an error.
7691 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7692 reportParseError("unexpected token, expected end of statement");
7693 return false;
7694 }
7695
7696 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7697 return false;
7698}
7699
7700bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7701 if (!isABI_N32() && !isABI_N64()) {
7702 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7703 return false;
7704 }
7705
7706 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7707 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7708 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7709 reportParseError("expected register containing global pointer");
7710 return false;
7711 }
7712
7713 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7714 if (!RegOpnd.isGPRAsmReg()) {
7715 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7716 return false;
7717 }
7718
7719 // If this is not the end of the statement, report an error.
7720 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7721 reportParseError("unexpected token, expected end of statement");
7722 return false;
7723 }
7724 getParser().Lex(); // Consume the EndOfStatement.
7725
7726 unsigned NewReg = RegOpnd.getGPR32Reg();
7727 if (IsPicEnabled)
7728 GPReg = NewReg;
7729
7730 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7731 return false;
7732}
7733
7734bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7735 MCAsmParser &Parser = getParser();
7736
7737 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7738 // is used in non-PIC mode.
7739
7740 if (inMips16Mode()) {
7741 reportParseError(".cprestore is not supported in Mips16 mode");
7742 return false;
7743 }
7744
7745 // Get the stack offset value.
7746 const MCExpr *StackOffset;
7747 int64_t StackOffsetVal;
7748 if (Parser.parseExpression(StackOffset)) {
7749 reportParseError("expected stack offset value");
7750 return false;
7751 }
7752
7753 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7754 reportParseError("stack offset is not an absolute expression");
7755 return false;
7756 }
7757
7758 if (StackOffsetVal < 0) {
7759 Warning(Loc, ".cprestore with negative stack offset has no effect");
7760 IsCpRestoreSet = false;
7761 } else {
7762 IsCpRestoreSet = true;
7763 CpRestoreOffset = StackOffsetVal;
7764 }
7765
7766 // If this is not the end of the statement, report an error.
7767 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7768 reportParseError("unexpected token, expected end of statement");
7769 return false;
7770 }
7771
7772 if (!getTargetStreamer().emitDirectiveCpRestore(
7773 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7774 return true;
7775 Parser.Lex(); // Consume the EndOfStatement.
7776 return false;
7777}
7778
7779bool MipsAsmParser::parseDirectiveCPSetup() {
7780 MCAsmParser &Parser = getParser();
7781 unsigned FuncReg;
7782 unsigned Save;
7783 bool SaveIsReg = true;
7784
7785 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7786 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7787 if (ResTy == MatchOperand_NoMatch) {
7788 reportParseError("expected register containing function address");
7789 return false;
7790 }
7791
7792 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7793 if (!FuncRegOpnd.isGPRAsmReg()) {
7794 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7795 return false;
7796 }
7797
7798 FuncReg = FuncRegOpnd.getGPR32Reg();
7799 TmpReg.clear();
7800
7801 if (!eatComma("unexpected token, expected comma"))
7802 return true;
7803
7804 ResTy = parseAnyRegister(TmpReg);
7805 if (ResTy == MatchOperand_NoMatch) {
7806 const MCExpr *OffsetExpr;
7807 int64_t OffsetVal;
7808 SMLoc ExprLoc = getLexer().getLoc();
7809
7810 if (Parser.parseExpression(OffsetExpr) ||
7811 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7812 reportParseError(ExprLoc, "expected save register or stack offset");
7813 return false;
7814 }
7815
7816 Save = OffsetVal;
7817 SaveIsReg = false;
7818 } else {
7819 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7820 if (!SaveOpnd.isGPRAsmReg()) {
7821 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7822 return false;
7823 }
7824 Save = SaveOpnd.getGPR32Reg();
7825 }
7826
7827 if (!eatComma("unexpected token, expected comma"))
7828 return true;
7829
7830 const MCExpr *Expr;
7831 if (Parser.parseExpression(Expr)) {
7832 reportParseError("expected expression");
7833 return false;
7834 }
7835
7836 if (Expr->getKind() != MCExpr::SymbolRef) {
7837 reportParseError("expected symbol");
7838 return false;
7839 }
7840 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7841
7842 CpSaveLocation = Save;
7843 CpSaveLocationIsRegister = SaveIsReg;
7844
7845 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7846 SaveIsReg);
7847 return false;
7848}
7849
7850bool MipsAsmParser::parseDirectiveCPReturn() {
7851 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7852 CpSaveLocationIsRegister);
7853 return false;
7854}
7855
7856bool MipsAsmParser::parseDirectiveNaN() {
7857 MCAsmParser &Parser = getParser();
7858 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7859 const AsmToken &Tok = Parser.getTok();
7860
7861 if (Tok.getString() == "2008") {
7862 Parser.Lex();
7863 getTargetStreamer().emitDirectiveNaN2008();
7864 return false;
7865 } else if (Tok.getString() == "legacy") {
7866 Parser.Lex();
7867 getTargetStreamer().emitDirectiveNaNLegacy();
7868 return false;
7869 }
7870 }
7871 // If we don't recognize the option passed to the .nan
7872 // directive (e.g. no option or unknown option), emit an error.
7873 reportParseError("invalid option in .nan directive");
7874 return false;
7875}
7876
7877bool MipsAsmParser::parseDirectiveSet() {
7878 const AsmToken &Tok = getParser().getTok();
7879 StringRef IdVal = Tok.getString();
7880 SMLoc Loc = Tok.getLoc();
7881
7882 if (IdVal == "noat")
7883 return parseSetNoAtDirective();
7884 if (IdVal == "at")
7885 return parseSetAtDirective();
7886 if (IdVal == "arch")
7887 return parseSetArchDirective();
7888 if (IdVal == "bopt") {
7889 Warning(Loc, "'bopt' feature is unsupported");
7890 getParser().Lex();
7891 return false;
7892 }
7893 if (IdVal == "nobopt") {
7894 // We're already running in nobopt mode, so nothing to do.
7895 getParser().Lex();
7896 return false;
7897 }
7898 if (IdVal == "fp")
7899 return parseSetFpDirective();
7900 if (IdVal == "oddspreg")
7901 return parseSetOddSPRegDirective();
7902 if (IdVal == "nooddspreg")
7903 return parseSetNoOddSPRegDirective();
7904 if (IdVal == "pop")
7905 return parseSetPopDirective();
7906 if (IdVal == "push")
7907 return parseSetPushDirective();
7908 if (IdVal == "reorder")
7909 return parseSetReorderDirective();
7910 if (IdVal == "noreorder")
7911 return parseSetNoReorderDirective();
7912 if (IdVal == "macro")
7913 return parseSetMacroDirective();
7914 if (IdVal == "nomacro")
7915 return parseSetNoMacroDirective();
7916 if (IdVal == "mips16")
7917 return parseSetMips16Directive();
7918 if (IdVal == "nomips16")
7919 return parseSetNoMips16Directive();
7920 if (IdVal == "nomicromips") {
7921 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7922 getTargetStreamer().emitDirectiveSetNoMicroMips();
7923 getParser().eatToEndOfStatement();
7924 return false;
7925 }
7926 if (IdVal == "micromips") {
7927 if (hasMips64r6()) {
7928 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7929 return false;
7930 }
7931 return parseSetFeature(Mips::FeatureMicroMips);
7932 }
7933 if (IdVal == "mips0")
7934 return parseSetMips0Directive();
7935 if (IdVal == "mips1")
7936 return parseSetFeature(Mips::FeatureMips1);
7937 if (IdVal == "mips2")
7938 return parseSetFeature(Mips::FeatureMips2);
7939 if (IdVal == "mips3")
7940 return parseSetFeature(Mips::FeatureMips3);
7941 if (IdVal == "mips4")
7942 return parseSetFeature(Mips::FeatureMips4);
7943 if (IdVal == "mips5")
7944 return parseSetFeature(Mips::FeatureMips5);
7945 if (IdVal == "mips32")
7946 return parseSetFeature(Mips::FeatureMips32);
7947 if (IdVal == "mips32r2")
7948 return parseSetFeature(Mips::FeatureMips32r2);
7949 if (IdVal == "mips32r3")
7950 return parseSetFeature(Mips::FeatureMips32r3);
7951 if (IdVal == "mips32r5")
7952 return parseSetFeature(Mips::FeatureMips32r5);
7953 if (IdVal == "mips32r6")
7954 return parseSetFeature(Mips::FeatureMips32r6);
7955 if (IdVal == "mips64")
7956 return parseSetFeature(Mips::FeatureMips64);
7957 if (IdVal == "mips64r2")
7958 return parseSetFeature(Mips::FeatureMips64r2);
7959 if (IdVal == "mips64r3")
7960 return parseSetFeature(Mips::FeatureMips64r3);
7961 if (IdVal == "mips64r5")
7962 return parseSetFeature(Mips::FeatureMips64r5);
7963 if (IdVal == "mips64r6") {
7964 if (inMicroMipsMode()) {
7965 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7966 return false;
7967 }
7968 return parseSetFeature(Mips::FeatureMips64r6);
7969 }
7970 if (IdVal == "dsp")
7971 return parseSetFeature(Mips::FeatureDSP);
7972 if (IdVal == "dspr2")
7973 return parseSetFeature(Mips::FeatureDSPR2);
7974 if (IdVal == "nodsp")
7975 return parseSetNoDspDirective();
7976 if (IdVal == "mips3d")
7977 return parseSetFeature(Mips::FeatureMips3D);
7978 if (IdVal == "nomips3d")
7979 return parseSetNoMips3DDirective();
7980 if (IdVal == "msa")
7981 return parseSetMsaDirective();
7982 if (IdVal == "nomsa")
7983 return parseSetNoMsaDirective();
7984 if (IdVal == "mt")
7985 return parseSetMtDirective();
7986 if (IdVal == "nomt")
7987 return parseSetNoMtDirective();
7988 if (IdVal == "softfloat")
7989 return parseSetSoftFloatDirective();
7990 if (IdVal == "hardfloat")
7991 return parseSetHardFloatDirective();
7992 if (IdVal == "crc")
7993 return parseSetFeature(Mips::FeatureCRC);
7994 if (IdVal == "nocrc")
7995 return parseSetNoCRCDirective();
7996 if (IdVal == "virt")
7997 return parseSetFeature(Mips::FeatureVirt);
7998 if (IdVal == "novirt")
7999 return parseSetNoVirtDirective();
8000 if (IdVal == "ginv")
8001 return parseSetFeature(Mips::FeatureGINV);
8002 if (IdVal == "noginv")
8003 return parseSetNoGINVDirective();
8004
8005 // It is just an identifier, look for an assignment.
8006 return parseSetAssignment();
8007}
8008
8009/// parseDirectiveGpWord
8010/// ::= .gpword local_sym
8011bool MipsAsmParser::parseDirectiveGpWord() {
8012 MCAsmParser &Parser = getParser();
8013 const MCExpr *Value;
8014 // EmitGPRel32Value requires an expression, so we are using base class
8015 // method to evaluate the expression.
8016 if (getParser().parseExpression(Value))
8017 return true;
8018 getParser().getStreamer().emitGPRel32Value(Value);
8019
8020 if (getLexer().isNot(AsmToken::EndOfStatement))
8021 return Error(getLexer().getLoc(),
8022 "unexpected token, expected end of statement");
8023 Parser.Lex(); // Eat EndOfStatement token.
8024 return false;
8025}
8026
8027/// parseDirectiveGpDWord
8028/// ::= .gpdword local_sym
8029bool MipsAsmParser::parseDirectiveGpDWord() {
8030 MCAsmParser &Parser = getParser();
8031 const MCExpr *Value;
8032 // EmitGPRel64Value requires an expression, so we are using base class
8033 // method to evaluate the expression.
8034 if (getParser().parseExpression(Value))
8035 return true;
8036 getParser().getStreamer().emitGPRel64Value(Value);
8037
8038 if (getLexer().isNot(AsmToken::EndOfStatement))
8039 return Error(getLexer().getLoc(),
8040 "unexpected token, expected end of statement");
8041 Parser.Lex(); // Eat EndOfStatement token.
8042 return false;
8043}
8044
8045/// parseDirectiveDtpRelWord
8046/// ::= .dtprelword tls_sym
8047bool MipsAsmParser::parseDirectiveDtpRelWord() {
8048 MCAsmParser &Parser = getParser();
8049 const MCExpr *Value;
8050 // EmitDTPRel32Value requires an expression, so we are using base class
8051 // method to evaluate the expression.
8052 if (getParser().parseExpression(Value))
8053 return true;
8054 getParser().getStreamer().emitDTPRel32Value(Value);
8055
8056 if (getLexer().isNot(AsmToken::EndOfStatement))
8057 return Error(getLexer().getLoc(),
8058 "unexpected token, expected end of statement");
8059 Parser.Lex(); // Eat EndOfStatement token.
8060 return false;
8061}
8062
8063/// parseDirectiveDtpRelDWord
8064/// ::= .dtpreldword tls_sym
8065bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8066 MCAsmParser &Parser = getParser();
8067 const MCExpr *Value;
8068 // EmitDTPRel64Value requires an expression, so we are using base class
8069 // method to evaluate the expression.
8070 if (getParser().parseExpression(Value))
8071 return true;
8072 getParser().getStreamer().emitDTPRel64Value(Value);
8073
8074 if (getLexer().isNot(AsmToken::EndOfStatement))
8075 return Error(getLexer().getLoc(),
8076 "unexpected token, expected end of statement");
8077 Parser.Lex(); // Eat EndOfStatement token.
8078 return false;
8079}
8080
8081/// parseDirectiveTpRelWord
8082/// ::= .tprelword tls_sym
8083bool MipsAsmParser::parseDirectiveTpRelWord() {
8084 MCAsmParser &Parser = getParser();
8085 const MCExpr *Value;
8086 // EmitTPRel32Value requires an expression, so we are using base class
8087 // method to evaluate the expression.
8088 if (getParser().parseExpression(Value))
8089 return true;
8090 getParser().getStreamer().emitTPRel32Value(Value);
8091
8092 if (getLexer().isNot(AsmToken::EndOfStatement))
8093 return Error(getLexer().getLoc(),
8094 "unexpected token, expected end of statement");
8095 Parser.Lex(); // Eat EndOfStatement token.
8096 return false;
8097}
8098
8099/// parseDirectiveTpRelDWord
8100/// ::= .tpreldword tls_sym
8101bool MipsAsmParser::parseDirectiveTpRelDWord() {
8102 MCAsmParser &Parser = getParser();
8103 const MCExpr *Value;
8104 // EmitTPRel64Value requires an expression, so we are using base class
8105 // method to evaluate the expression.
8106 if (getParser().parseExpression(Value))
8107 return true;
8108 getParser().getStreamer().emitTPRel64Value(Value);
8109
8110 if (getLexer().isNot(AsmToken::EndOfStatement))
8111 return Error(getLexer().getLoc(),
8112 "unexpected token, expected end of statement");
8113 Parser.Lex(); // Eat EndOfStatement token.
8114 return false;
8115}
8116
8117bool MipsAsmParser::parseDirectiveOption() {
8118 MCAsmParser &Parser = getParser();
8119 // Get the option token.
8120 AsmToken Tok = Parser.getTok();
8121 // At the moment only identifiers are supported.
8122 if (Tok.isNot(AsmToken::Identifier)) {
8123 return Error(Parser.getTok().getLoc(),
8124 "unexpected token, expected identifier");
8125 }
8126
8127 StringRef Option = Tok.getIdentifier();
8128
8129 if (Option == "pic0") {
8130 // MipsAsmParser needs to know if the current PIC mode changes.
8131 IsPicEnabled = false;
8132
8133 getTargetStreamer().emitDirectiveOptionPic0();
8134 Parser.Lex();
8135 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8136 return Error(Parser.getTok().getLoc(),
8137 "unexpected token, expected end of statement");
8138 }
8139 return false;
8140 }
8141
8142 if (Option == "pic2") {
8143 // MipsAsmParser needs to know if the current PIC mode changes.
8144 IsPicEnabled = true;
8145
8146 getTargetStreamer().emitDirectiveOptionPic2();
8147 Parser.Lex();
8148 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8149 return Error(Parser.getTok().getLoc(),
8150 "unexpected token, expected end of statement");
8151 }
8152 return false;
8153 }
8154
8155 // Unknown option.
8156 Warning(Parser.getTok().getLoc(),
8157 "unknown option, expected 'pic0' or 'pic2'");
8158 Parser.eatToEndOfStatement();
8159 return false;
8160}
8161
8162/// parseInsnDirective
8163/// ::= .insn
8164bool MipsAsmParser::parseInsnDirective() {
8165 // If this is not the end of the statement, report an error.
8166 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8167 reportParseError("unexpected token, expected end of statement");
8168 return false;
8169 }
8170
8171 // The actual label marking happens in
8172 // MipsELFStreamer::createPendingLabelRelocs().
8173 getTargetStreamer().emitDirectiveInsn();
8174
8175 getParser().Lex(); // Eat EndOfStatement token.
8176 return false;
8177}
8178
8179/// parseRSectionDirective
8180/// ::= .rdata
8181bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8182 // If this is not the end of the statement, report an error.
8183 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8184 reportParseError("unexpected token, expected end of statement");
8185 return false;
8186 }
8187
8188 MCSection *ELFSection = getContext().getELFSection(
8189 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
8190 getParser().getStreamer().switchSection(ELFSection);
8191
8192 getParser().Lex(); // Eat EndOfStatement token.
8193 return false;
8194}
8195
8196/// parseSSectionDirective
8197/// ::= .sbss
8198/// ::= .sdata
8199bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8200 // If this is not the end of the statement, report an error.
8201 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8202 reportParseError("unexpected token, expected end of statement");
8203 return false;
8204 }
8205
8206 MCSection *ELFSection = getContext().getELFSection(
8207 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
8208 getParser().getStreamer().switchSection(ELFSection);
8209
8210 getParser().Lex(); // Eat EndOfStatement token.
8211 return false;
8212}
8213
8214/// parseDirectiveModule
8215/// ::= .module oddspreg
8216/// ::= .module nooddspreg
8217/// ::= .module fp=value
8218/// ::= .module softfloat
8219/// ::= .module hardfloat
8220/// ::= .module mt
8221/// ::= .module crc
8222/// ::= .module nocrc
8223/// ::= .module virt
8224/// ::= .module novirt
8225/// ::= .module ginv
8226/// ::= .module noginv
8227bool MipsAsmParser::parseDirectiveModule() {
8228 MCAsmParser &Parser = getParser();
8229 MCAsmLexer &Lexer = getLexer();
8230 SMLoc L = Lexer.getLoc();
8231
8232 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8233 // TODO : get a better message.
8234 reportParseError(".module directive must appear before any code");
8235 return false;
8236 }
8237
8238 StringRef Option;
8239 if (Parser.parseIdentifier(Option)) {
8240 reportParseError("expected .module option identifier");
8241 return false;
8242 }
8243
8244 if (Option == "oddspreg") {
8245 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8246
8247 // Synchronize the abiflags information with the FeatureBits information we
8248 // changed above.
8249 getTargetStreamer().updateABIInfo(*this);
8250
8251 // If printing assembly, use the recently updated abiflags information.
8252 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8253 // emitted at the end).
8254 getTargetStreamer().emitDirectiveModuleOddSPReg();
8255
8256 // If this is not the end of the statement, report an error.
8257 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8258 reportParseError("unexpected token, expected end of statement");
8259 return false;
8260 }
8261
8262 return false; // parseDirectiveModule has finished successfully.
8263 } else if (Option == "nooddspreg") {
8264 if (!isABI_O32()) {
8265 return Error(L, "'.module nooddspreg' requires the O32 ABI");
8266 }
8267
8268 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8269
8270 // Synchronize the abiflags information with the FeatureBits information we
8271 // changed above.
8272 getTargetStreamer().updateABIInfo(*this);
8273
8274 // If printing assembly, use the recently updated abiflags information.
8275 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8276 // emitted at the end).
8277 getTargetStreamer().emitDirectiveModuleOddSPReg();
8278
8279 // If this is not the end of the statement, report an error.
8280 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8281 reportParseError("unexpected token, expected end of statement");
8282 return false;
8283 }
8284
8285 return false; // parseDirectiveModule has finished successfully.
8286 } else if (Option == "fp") {
8287 return parseDirectiveModuleFP();
8288 } else if (Option == "softfloat") {
8289 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8290
8291 // Synchronize the ABI Flags information with the FeatureBits information we
8292 // updated above.
8293 getTargetStreamer().updateABIInfo(*this);
8294
8295 // If printing assembly, use the recently updated ABI Flags information.
8296 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8297 // emitted later).
8298 getTargetStreamer().emitDirectiveModuleSoftFloat();
8299
8300 // If this is not the end of the statement, report an error.
8301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8302 reportParseError("unexpected token, expected end of statement");
8303 return false;
8304 }
8305
8306 return false; // parseDirectiveModule has finished successfully.
8307 } else if (Option == "hardfloat") {
8308 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8309
8310 // Synchronize the ABI Flags information with the FeatureBits information we
8311 // updated above.
8312 getTargetStreamer().updateABIInfo(*this);
8313
8314 // If printing assembly, use the recently updated ABI Flags information.
8315 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8316 // emitted later).
8317 getTargetStreamer().emitDirectiveModuleHardFloat();
8318
8319 // If this is not the end of the statement, report an error.
8320 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8321 reportParseError("unexpected token, expected end of statement");
8322 return false;
8323 }
8324
8325 return false; // parseDirectiveModule has finished successfully.
8326 } else if (Option == "mt") {
8327 setModuleFeatureBits(Mips::FeatureMT, "mt");
8328
8329 // Synchronize the ABI Flags information with the FeatureBits information we
8330 // updated above.
8331 getTargetStreamer().updateABIInfo(*this);
8332
8333 // If printing assembly, use the recently updated ABI Flags information.
8334 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8335 // emitted later).
8336 getTargetStreamer().emitDirectiveModuleMT();
8337
8338 // If this is not the end of the statement, report an error.
8339 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8340 reportParseError("unexpected token, expected end of statement");
8341 return false;
8342 }
8343
8344 return false; // parseDirectiveModule has finished successfully.
8345 } else if (Option == "crc") {
8346 setModuleFeatureBits(Mips::FeatureCRC, "crc");
8347
8348 // Synchronize the ABI Flags information with the FeatureBits information we
8349 // updated above.
8350 getTargetStreamer().updateABIInfo(*this);
8351
8352 // If printing assembly, use the recently updated ABI Flags information.
8353 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8354 // emitted later).
8355 getTargetStreamer().emitDirectiveModuleCRC();
8356
8357 // If this is not the end of the statement, report an error.
8358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8359 reportParseError("unexpected token, expected end of statement");
8360 return false;
8361 }
8362
8363 return false; // parseDirectiveModule has finished successfully.
8364 } else if (Option == "nocrc") {
8365 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8366
8367 // Synchronize the ABI Flags information with the FeatureBits information we
8368 // updated above.
8369 getTargetStreamer().updateABIInfo(*this);
8370
8371 // If printing assembly, use the recently updated ABI Flags information.
8372 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8373 // emitted later).
8374 getTargetStreamer().emitDirectiveModuleNoCRC();
8375
8376 // If this is not the end of the statement, report an error.
8377 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8378 reportParseError("unexpected token, expected end of statement");
8379 return false;
8380 }
8381
8382 return false; // parseDirectiveModule has finished successfully.
8383 } else if (Option == "virt") {
8384 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8385
8386 // Synchronize the ABI Flags information with the FeatureBits information we
8387 // updated above.
8388 getTargetStreamer().updateABIInfo(*this);
8389
8390 // If printing assembly, use the recently updated ABI Flags information.
8391 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8392 // emitted later).
8393 getTargetStreamer().emitDirectiveModuleVirt();
8394
8395 // If this is not the end of the statement, report an error.
8396 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8397 reportParseError("unexpected token, expected end of statement");
8398 return false;
8399 }
8400
8401 return false; // parseDirectiveModule has finished successfully.
8402 } else if (Option == "novirt") {
8403 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8404
8405 // Synchronize the ABI Flags information with the FeatureBits information we
8406 // updated above.
8407 getTargetStreamer().updateABIInfo(*this);
8408
8409 // If printing assembly, use the recently updated ABI Flags information.
8410 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8411 // emitted later).
8412 getTargetStreamer().emitDirectiveModuleNoVirt();
8413
8414 // If this is not the end of the statement, report an error.
8415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8416 reportParseError("unexpected token, expected end of statement");
8417 return false;
8418 }
8419
8420 return false; // parseDirectiveModule has finished successfully.
8421 } else if (Option == "ginv") {
8422 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8423
8424 // Synchronize the ABI Flags information with the FeatureBits information we
8425 // updated above.
8426 getTargetStreamer().updateABIInfo(*this);
8427
8428 // If printing assembly, use the recently updated ABI Flags information.
8429 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8430 // emitted later).
8431 getTargetStreamer().emitDirectiveModuleGINV();
8432
8433 // If this is not the end of the statement, report an error.
8434 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8435 reportParseError("unexpected token, expected end of statement");
8436 return false;
8437 }
8438
8439 return false; // parseDirectiveModule has finished successfully.
8440 } else if (Option == "noginv") {
8441 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8442
8443 // Synchronize the ABI Flags information with the FeatureBits information we
8444 // updated above.
8445 getTargetStreamer().updateABIInfo(*this);
8446
8447 // If printing assembly, use the recently updated ABI Flags information.
8448 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8449 // emitted later).
8450 getTargetStreamer().emitDirectiveModuleNoGINV();
8451
8452 // If this is not the end of the statement, report an error.
8453 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8454 reportParseError("unexpected token, expected end of statement");
8455 return false;
8456 }
8457
8458 return false; // parseDirectiveModule has finished successfully.
8459 } else {
8460 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8461 }
8462}
8463
8464/// parseDirectiveModuleFP
8465/// ::= =32
8466/// ::= =xx
8467/// ::= =64
8468bool MipsAsmParser::parseDirectiveModuleFP() {
8469 MCAsmParser &Parser = getParser();
8470 MCAsmLexer &Lexer = getLexer();
8471
8472 if (Lexer.isNot(AsmToken::Equal)) {
8473 reportParseError("unexpected token, expected equals sign '='");
8474 return false;
8475 }
8476 Parser.Lex(); // Eat '=' token.
8477
8478 MipsABIFlagsSection::FpABIKind FpABI;
8479 if (!parseFpABIValue(FpABI, ".module"))
8480 return false;
8481
8482 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8483 reportParseError("unexpected token, expected end of statement");
8484 return false;
8485 }
8486
8487 // Synchronize the abiflags information with the FeatureBits information we
8488 // changed above.
8489 getTargetStreamer().updateABIInfo(*this);
8490
8491 // If printing assembly, use the recently updated abiflags information.
8492 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8493 // emitted at the end).
8494 getTargetStreamer().emitDirectiveModuleFP();
8495
8496 Parser.Lex(); // Consume the EndOfStatement.
8497 return false;
8498}
8499
8500bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8501 StringRef Directive) {
8502 MCAsmParser &Parser = getParser();
8503 MCAsmLexer &Lexer = getLexer();
8504 bool ModuleLevelOptions = Directive == ".module";
8505
8506 if (Lexer.is(AsmToken::Identifier)) {
8507 StringRef Value = Parser.getTok().getString();
8508 Parser.Lex();
8509
8510 if (Value != "xx") {
8511 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8512 return false;
8513 }
8514
8515 if (!isABI_O32()) {
8516 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8517 return false;
8518 }
8519
8520 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8521 if (ModuleLevelOptions) {
8522 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8523 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8524 } else {
8525 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8526 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8527 }
8528 return true;
8529 }
8530
8531 if (Lexer.is(AsmToken::Integer)) {
8532 unsigned Value = Parser.getTok().getIntVal();
8533 Parser.Lex();
8534
8535 if (Value != 32 && Value != 64) {
8536 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8537 return false;
8538 }
8539
8540 if (Value == 32) {
8541 if (!isABI_O32()) {
8542 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8543 return false;
8544 }
8545
8546 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8547 if (ModuleLevelOptions) {
8548 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8549 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8550 } else {
8551 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8552 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8553 }
8554 } else {
8555 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8556 if (ModuleLevelOptions) {
8557 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8558 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8559 } else {
8560 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8561 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8562 }
8563 }
8564
8565 return true;
8566 }
8567
8568 return false;
8569}
8570
8571bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8572 // This returns false if this function recognizes the directive
8573 // regardless of whether it is successfully handles or reports an
8574 // error. Otherwise it returns true to give the generic parser a
8575 // chance at recognizing it.
8576
8577 MCAsmParser &Parser = getParser();
8578 StringRef IDVal = DirectiveID.getString();
8579
8580 if (IDVal == ".cpadd") {
8581 parseDirectiveCpAdd(DirectiveID.getLoc());
8582 return false;
8583 }
8584 if (IDVal == ".cpload") {
8585 parseDirectiveCpLoad(DirectiveID.getLoc());
8586 return false;
8587 }
8588 if (IDVal == ".cprestore") {
8589 parseDirectiveCpRestore(DirectiveID.getLoc());
8590 return false;
8591 }
8592 if (IDVal == ".cplocal") {
8593 parseDirectiveCpLocal(DirectiveID.getLoc());
8594 return false;
8595 }
8596 if (IDVal == ".ent") {
8597 StringRef SymbolName;
8598
8599 if (Parser.parseIdentifier(SymbolName)) {
8600 reportParseError("expected identifier after .ent");
8601 return false;
8602 }
8603
8604 // There's an undocumented extension that allows an integer to
8605 // follow the name of the procedure which AFAICS is ignored by GAS.
8606 // Example: .ent foo,2
8607 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8608 if (getLexer().isNot(AsmToken::Comma)) {
8609 // Even though we accept this undocumented extension for compatibility
8610 // reasons, the additional integer argument does not actually change
8611 // the behaviour of the '.ent' directive, so we would like to discourage
8612 // its use. We do this by not referring to the extended version in
8613 // error messages which are not directly related to its use.
8614 reportParseError("unexpected token, expected end of statement");
8615 return false;
8616 }
8617 Parser.Lex(); // Eat the comma.
8618 const MCExpr *DummyNumber;
8619 int64_t DummyNumberVal;
8620 // If the user was explicitly trying to use the extended version,
8621 // we still give helpful extension-related error messages.
8622 if (Parser.parseExpression(DummyNumber)) {
8623 reportParseError("expected number after comma");
8624 return false;
8625 }
8626 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8627 reportParseError("expected an absolute expression after comma");
8628 return false;
8629 }
8630 }
8631
8632 // If this is not the end of the statement, report an error.
8633 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8634 reportParseError("unexpected token, expected end of statement");
8635 return false;
8636 }
8637
8638 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8639
8640 getTargetStreamer().emitDirectiveEnt(*Sym);
8641 CurrentFn = Sym;
8642 IsCpRestoreSet = false;
8643 return false;
8644 }
8645
8646 if (IDVal == ".end") {
8647 StringRef SymbolName;
8648
8649 if (Parser.parseIdentifier(SymbolName)) {
8650 reportParseError("expected identifier after .end");
8651 return false;
8652 }
8653
8654 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8655 reportParseError("unexpected token, expected end of statement");
8656 return false;
8657 }
8658
8659 if (CurrentFn == nullptr) {
8660 reportParseError(".end used without .ent");
8661 return false;
8662 }
8663
8664 if ((SymbolName != CurrentFn->getName())) {
8665 reportParseError(".end symbol does not match .ent symbol");
8666 return false;
8667 }
8668
8669 getTargetStreamer().emitDirectiveEnd(SymbolName);
8670 CurrentFn = nullptr;
8671 IsCpRestoreSet = false;
8672 return false;
8673 }
8674
8675 if (IDVal == ".frame") {
8676 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8677 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8678 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
8679 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8680 reportParseError("expected stack register");
8681 return false;
8682 }
8683
8684 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8685 if (!StackRegOpnd.isGPRAsmReg()) {
8686 reportParseError(StackRegOpnd.getStartLoc(),
8687 "expected general purpose register");
8688 return false;
8689 }
8690 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8691
8692 if (Parser.getTok().is(AsmToken::Comma))
8693 Parser.Lex();
8694 else {
8695 reportParseError("unexpected token, expected comma");
8696 return false;
8697 }
8698
8699 // Parse the frame size.
8700 const MCExpr *FrameSize;
8701 int64_t FrameSizeVal;
8702
8703 if (Parser.parseExpression(FrameSize)) {
8704 reportParseError("expected frame size value");
8705 return false;
8706 }
8707
8708 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8709 reportParseError("frame size not an absolute expression");
8710 return false;
8711 }
8712
8713 if (Parser.getTok().is(AsmToken::Comma))
8714 Parser.Lex();
8715 else {
8716 reportParseError("unexpected token, expected comma");
8717 return false;
8718 }
8719
8720 // Parse the return register.
8721 TmpReg.clear();
8722 ResTy = parseAnyRegister(TmpReg);
8723 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8724 reportParseError("expected return register");
8725 return false;
8726 }
8727
8728 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8729 if (!ReturnRegOpnd.isGPRAsmReg()) {
8730 reportParseError(ReturnRegOpnd.getStartLoc(),
8731 "expected general purpose register");
8732 return false;
8733 }
8734
8735 // If this is not the end of the statement, report an error.
8736 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8737 reportParseError("unexpected token, expected end of statement");
8738 return false;
8739 }
8740
8741 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8742 ReturnRegOpnd.getGPR32Reg());
8743 IsCpRestoreSet = false;
8744 return false;
8745 }
8746
8747 if (IDVal == ".set") {
8748 parseDirectiveSet();
8749 return false;
8750 }
8751
8752 if (IDVal == ".mask" || IDVal == ".fmask") {
8753 // .mask bitmask, frame_offset
8754 // bitmask: One bit for each register used.
8755 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8756 // first register is expected to be saved.
8757 // Examples:
8758 // .mask 0x80000000, -4
8759 // .fmask 0x80000000, -4
8760 //
8761
8762 // Parse the bitmask
8763 const MCExpr *BitMask;
8764 int64_t BitMaskVal;
8765
8766 if (Parser.parseExpression(BitMask)) {
8767 reportParseError("expected bitmask value");
8768 return false;
8769 }
8770
8771 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8772 reportParseError("bitmask not an absolute expression");
8773 return false;
8774 }
8775
8776 if (Parser.getTok().is(AsmToken::Comma))
8777 Parser.Lex();
8778 else {
8779 reportParseError("unexpected token, expected comma");
8780 return false;
8781 }
8782
8783 // Parse the frame_offset
8784 const MCExpr *FrameOffset;
8785 int64_t FrameOffsetVal;
8786
8787 if (Parser.parseExpression(FrameOffset)) {
8788 reportParseError("expected frame offset value");
8789 return false;
8790 }
8791
8792 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8793 reportParseError("frame offset not an absolute expression");
8794 return false;
8795 }
8796
8797 // If this is not the end of the statement, report an error.
8798 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8799 reportParseError("unexpected token, expected end of statement");
8800 return false;
8801 }
8802
8803 if (IDVal == ".mask")
8804 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8805 else
8806 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8807 return false;
8808 }
8809
8810 if (IDVal == ".nan")
8811 return parseDirectiveNaN();
8812
8813 if (IDVal == ".gpword") {
8814 parseDirectiveGpWord();
8815 return false;
8816 }
8817
8818 if (IDVal == ".gpdword") {
8819 parseDirectiveGpDWord();
8820 return false;
8821 }
8822
8823 if (IDVal == ".dtprelword") {
8824 parseDirectiveDtpRelWord();
8825 return false;
8826 }
8827
8828 if (IDVal == ".dtpreldword") {
8829 parseDirectiveDtpRelDWord();
8830 return false;
8831 }
8832
8833 if (IDVal == ".tprelword") {
8834 parseDirectiveTpRelWord();
8835 return false;
8836 }
8837
8838 if (IDVal == ".tpreldword") {
8839 parseDirectiveTpRelDWord();
8840 return false;
8841 }
8842
8843 if (IDVal == ".option") {
8844 parseDirectiveOption();
8845 return false;
8846 }
8847
8848 if (IDVal == ".abicalls") {
8849 getTargetStreamer().emitDirectiveAbiCalls();
8850 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8851 Error(Parser.getTok().getLoc(),
8852 "unexpected token, expected end of statement");
8853 }
8854 return false;
8855 }
8856
8857 if (IDVal == ".cpsetup") {
8858 parseDirectiveCPSetup();
8859 return false;
8860 }
8861 if (IDVal == ".cpreturn") {
8862 parseDirectiveCPReturn();
8863 return false;
8864 }
8865 if (IDVal == ".module") {
8866 parseDirectiveModule();
8867 return false;
8868 }
8869 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8870 parseInternalDirectiveReallowModule();
8871 return false;
8872 }
8873 if (IDVal == ".insn") {
8874 parseInsnDirective();
8875 return false;
8876 }
8877 if (IDVal == ".rdata") {
8878 parseRSectionDirective(".rodata");
8879 return false;
8880 }
8881 if (IDVal == ".sbss") {
8882 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8883 return false;
8884 }
8885 if (IDVal == ".sdata") {
8886 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8887 return false;
8888 }
8889
8890 return true;
8891}
8892
8893bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8894 // If this is not the end of the statement, report an error.
8895 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8896 reportParseError("unexpected token, expected end of statement");
8897 return false;
8898 }
8899
8900 getTargetStreamer().reallowModuleDirective();
8901
8902 getParser().Lex(); // Eat EndOfStatement token.
8903 return false;
8904}
8905
8906extern "C" LLVM_EXTERNAL_VISIBILITY__attribute__((visibility("default"))) void LLVMInitializeMipsAsmParser() {
8907 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8908 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8909 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8910 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8911}
8912
8913#define GET_REGISTER_MATCHER
8914#define GET_MATCHER_IMPLEMENTATION
8915#define GET_MNEMONIC_SPELL_CHECKER
8916#include "MipsGenAsmMatcher.inc"
8917
8918bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8919 // Find the appropriate table for this asm variant.
8920 const MatchEntry *Start, *End;
8921 switch (VariantID) {
8922 default: llvm_unreachable("invalid variant!")::llvm::llvm_unreachable_internal("invalid variant!", "llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 8922)
;
8923 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8924 }
8925 // Search the table.
8926 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8927 return MnemonicRange.first != MnemonicRange.second;
8928}

/build/source/llvm/include/llvm/Support/MathExtras.h

1//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
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// This file contains some functions that are useful for math stuff.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_SUPPORT_MATHEXTRAS_H
14#define LLVM_SUPPORT_MATHEXTRAS_H
15
16#include "llvm/ADT/bit.h"
17#include "llvm/Support/Compiler.h"
18#include <cassert>
19#include <climits>
20#include <cstdint>
21#include <cstring>
22#include <limits>
23#include <type_traits>
24
25namespace llvm {
26
27/// The behavior an operation has on an input of 0.
28enum ZeroBehavior {
29 /// The returned value is undefined.
30 ZB_Undefined,
31 /// The returned value is numeric_limits<T>::max()
32 ZB_Max
33};
34
35/// Mathematical constants.
36namespace numbers {
37// TODO: Track C++20 std::numbers.
38// TODO: Favor using the hexadecimal FP constants (requires C++17).
39constexpr double e = 2.7182818284590452354, // (0x1.5bf0a8b145749P+1) https://oeis.org/A001113
40 egamma = .57721566490153286061, // (0x1.2788cfc6fb619P-1) https://oeis.org/A001620
41 ln2 = .69314718055994530942, // (0x1.62e42fefa39efP-1) https://oeis.org/A002162
42 ln10 = 2.3025850929940456840, // (0x1.24bb1bbb55516P+1) https://oeis.org/A002392
43 log2e = 1.4426950408889634074, // (0x1.71547652b82feP+0)
44 log10e = .43429448190325182765, // (0x1.bcb7b1526e50eP-2)
45 pi = 3.1415926535897932385, // (0x1.921fb54442d18P+1) https://oeis.org/A000796
46 inv_pi = .31830988618379067154, // (0x1.45f306bc9c883P-2) https://oeis.org/A049541
47 sqrtpi = 1.7724538509055160273, // (0x1.c5bf891b4ef6bP+0) https://oeis.org/A002161
48 inv_sqrtpi = .56418958354775628695, // (0x1.20dd750429b6dP-1) https://oeis.org/A087197
49 sqrt2 = 1.4142135623730950488, // (0x1.6a09e667f3bcdP+0) https://oeis.org/A00219
50 inv_sqrt2 = .70710678118654752440, // (0x1.6a09e667f3bcdP-1)
51 sqrt3 = 1.7320508075688772935, // (0x1.bb67ae8584caaP+0) https://oeis.org/A002194
52 inv_sqrt3 = .57735026918962576451, // (0x1.279a74590331cP-1)
53 phi = 1.6180339887498948482; // (0x1.9e3779b97f4a8P+0) https://oeis.org/A001622
54constexpr float ef = 2.71828183F, // (0x1.5bf0a8P+1) https://oeis.org/A001113
55 egammaf = .577215665F, // (0x1.2788d0P-1) https://oeis.org/A001620
56 ln2f = .693147181F, // (0x1.62e430P-1) https://oeis.org/A002162
57 ln10f = 2.30258509F, // (0x1.26bb1cP+1) https://oeis.org/A002392
58 log2ef = 1.44269504F, // (0x1.715476P+0)
59 log10ef = .434294482F, // (0x1.bcb7b2P-2)
60 pif = 3.14159265F, // (0x1.921fb6P+1) https://oeis.org/A000796
61 inv_pif = .318309886F, // (0x1.45f306P-2) https://oeis.org/A049541
62 sqrtpif = 1.77245385F, // (0x1.c5bf8aP+0) https://oeis.org/A002161
63 inv_sqrtpif = .564189584F, // (0x1.20dd76P-1) https://oeis.org/A087197
64 sqrt2f = 1.41421356F, // (0x1.6a09e6P+0) https://oeis.org/A002193
65 inv_sqrt2f = .707106781F, // (0x1.6a09e6P-1)
66 sqrt3f = 1.73205081F, // (0x1.bb67aeP+0) https://oeis.org/A002194
67 inv_sqrt3f = .577350269F, // (0x1.279a74P-1)
68 phif = 1.61803399F; // (0x1.9e377aP+0) https://oeis.org/A001622
69} // namespace numbers
70
71/// Count number of 0's from the least significant bit to the most
72/// stopping at the first 1.
73///
74/// Only unsigned integral types are allowed.
75///
76/// Returns std::numeric_limits<T>::digits on an input of 0.
77template <typename T> unsigned countTrailingZeros(T Val) {
78 static_assert(std::is_unsigned_v<T>,
79 "Only unsigned integral types are allowed.");
80 return llvm::countr_zero(Val);
81}
82
83/// Count number of 0's from the most significant bit to the least
84/// stopping at the first 1.
85///
86/// Only unsigned integral types are allowed.
87///
88/// Returns std::numeric_limits<T>::digits on an input of 0.
89template <typename T> unsigned countLeadingZeros(T Val) {
90 static_assert(std::is_unsigned_v<T>,
91 "Only unsigned integral types are allowed.");
92 return llvm::countl_zero(Val);
93}
94
95/// Get the index of the first set bit starting from the least
96/// significant bit.
97///
98/// Only unsigned integral types are allowed.
99///
100/// \param ZB the behavior on an input of 0.
101template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
102 if (ZB
1.1
'ZB' is equal to ZB_Max
1.1
'ZB' is equal to ZB_Max
1.1
'ZB' is equal to ZB_Max
== ZB_Max && Val == 0)
2
Assuming 'Val' is equal to 0
3
Taking true branch
103 return std::numeric_limits<T>::max();
4
Calling 'numeric_limits::max'
6
Returning from 'numeric_limits::max'
7
Returning the value 18446744073709551615
104
105 return llvm::countr_zero(Val);
106}
107
108/// Create a bitmask with the N right-most bits set to 1, and all other
109/// bits set to 0. Only unsigned types are allowed.
110template <typename T> T maskTrailingOnes(unsigned N) {
111 static_assert(std::is_unsigned<T>::value, "Invalid type!");
112 const unsigned Bits = CHAR_BIT8 * sizeof(T);
113 assert(N <= Bits && "Invalid bit index")(static_cast <bool> (N <= Bits && "Invalid bit index"
) ? void (0) : __assert_fail ("N <= Bits && \"Invalid bit index\""
, "llvm/include/llvm/Support/MathExtras.h", 113, __extension__
__PRETTY_FUNCTION__))
;
114 return N == 0 ? 0 : (T(-1) >> (Bits - N));
115}
116
117/// Create a bitmask with the N left-most bits set to 1, and all other
118/// bits set to 0. Only unsigned types are allowed.
119template <typename T> T maskLeadingOnes(unsigned N) {
120 return ~maskTrailingOnes<T>(CHAR_BIT8 * sizeof(T) - N);
121}
122
123/// Create a bitmask with the N right-most bits set to 0, and all other
124/// bits set to 1. Only unsigned types are allowed.
125template <typename T> T maskTrailingZeros(unsigned N) {
126 return maskLeadingOnes<T>(CHAR_BIT8 * sizeof(T) - N);
127}
128
129/// Create a bitmask with the N left-most bits set to 0, and all other
130/// bits set to 1. Only unsigned types are allowed.
131template <typename T> T maskLeadingZeros(unsigned N) {
132 return maskTrailingOnes<T>(CHAR_BIT8 * sizeof(T) - N);
133}
134
135/// Get the index of the last set bit starting from the least
136/// significant bit.
137///
138/// Only unsigned integral types are allowed.
139///
140/// \param ZB the behavior on an input of 0.
141template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
142 if (ZB == ZB_Max && Val == 0)
143 return std::numeric_limits<T>::max();
144
145 // Use ^ instead of - because both gcc and llvm can remove the associated ^
146 // in the __builtin_clz intrinsic on x86.
147 return llvm::countl_zero(Val) ^ (std::numeric_limits<T>::digits - 1);
148}
149
150/// Macro compressed bit reversal table for 256 bits.
151///
152/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
153static const unsigned char BitReverseTable256[256] = {
154#define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64
155#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
156#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
157 R6(0), R6(2), R6(1), R6(3)
158#undef R2
159#undef R4
160#undef R6
161};
162
163/// Reverse the bits in \p Val.
164template <typename T> T reverseBits(T Val) {
165#if __has_builtin(__builtin_bitreverse8)1
166 if constexpr (std::is_same_v<T, uint8_t>)
167 return __builtin_bitreverse8(Val);
168#endif
169#if __has_builtin(__builtin_bitreverse16)1
170 if constexpr (std::is_same_v<T, uint16_t>)
171 return __builtin_bitreverse16(Val);
172#endif
173#if __has_builtin(__builtin_bitreverse32)1
174 if constexpr (std::is_same_v<T, uint32_t>)
175 return __builtin_bitreverse32(Val);
176#endif
177#if __has_builtin(__builtin_bitreverse64)1
178 if constexpr (std::is_same_v<T, uint64_t>)
179 return __builtin_bitreverse64(Val);
180#endif
181
182 unsigned char in[sizeof(Val)];
183 unsigned char out[sizeof(Val)];
184 std::memcpy(in, &Val, sizeof(Val));
185 for (unsigned i = 0; i < sizeof(Val); ++i)
186 out[(sizeof(Val) - i) - 1] = BitReverseTable256[in[i]];
187 std::memcpy(&Val, out, sizeof(Val));
188 return Val;
189}
190
191// NOTE: The following support functions use the _32/_64 extensions instead of
192// type overloading so that signed and unsigned integers can be used without
193// ambiguity.
194
195/// Return the high 32 bits of a 64 bit value.
196constexpr inline uint32_t Hi_32(uint64_t Value) {
197 return static_cast<uint32_t>(Value >> 32);
198}
199
200/// Return the low 32 bits of a 64 bit value.
201constexpr inline uint32_t Lo_32(uint64_t Value) {
202 return static_cast<uint32_t>(Value);
203}
204
205/// Make a 64-bit integer from a high / low pair of 32-bit integers.
206constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) {
207 return ((uint64_t)High << 32) | (uint64_t)Low;
208}
209
210/// Checks if an integer fits into the given bit width.
211template <unsigned N> constexpr inline bool isInt(int64_t x) {
212 if constexpr (N == 8)
213 return static_cast<int8_t>(x) == x;
214 if constexpr (N == 16)
215 return static_cast<int16_t>(x) == x;
216 if constexpr (N == 32)
217 return static_cast<int32_t>(x) == x;
218 if constexpr (N < 64)
219 return -(INT64_C(1)1L << (N - 1)) <= x && x < (INT64_C(1)1L << (N - 1));
220 (void)x; // MSVC v19.25 warns that x is unused.
221 return true;
222}
223
224/// Checks if a signed integer is an N bit number shifted left by S.
225template <unsigned N, unsigned S>
226constexpr inline bool isShiftedInt(int64_t x) {
227 static_assert(
228 N > 0, "isShiftedInt<0> doesn't make sense (refers to a 0-bit number.");
229 static_assert(N + S <= 64, "isShiftedInt<N, S> with N + S > 64 is too wide.");
230 return isInt<N + S>(x) && (x % (UINT64_C(1)1UL << S) == 0);
231}
232
233/// Checks if an unsigned integer fits into the given bit width.
234template <unsigned N> constexpr inline bool isUInt(uint64_t x) {
235 static_assert(N > 0, "isUInt<0> doesn't make sense");
236 if constexpr (N == 8)
237 return static_cast<uint8_t>(x) == x;
238 if constexpr (N == 16)
239 return static_cast<uint16_t>(x) == x;
240 if constexpr (N == 32)
241 return static_cast<uint32_t>(x) == x;
242 if constexpr (N < 64)
243 return x < (UINT64_C(1)1UL << (N));
244 (void)x; // MSVC v19.25 warns that x is unused.
245 return true;
246}
247
248/// Checks if a unsigned integer is an N bit number shifted left by S.
249template <unsigned N, unsigned S>
250constexpr inline bool isShiftedUInt(uint64_t x) {
251 static_assert(
252 N > 0, "isShiftedUInt<0> doesn't make sense (refers to a 0-bit number)");
253 static_assert(N + S <= 64,
254 "isShiftedUInt<N, S> with N + S > 64 is too wide.");
255 // Per the two static_asserts above, S must be strictly less than 64. So
256 // 1 << S is not undefined behavior.
257 return isUInt<N + S>(x) && (x % (UINT64_C(1)1UL << S) == 0);
258}
259
260/// Gets the maximum value for a N-bit unsigned integer.
261inline uint64_t maxUIntN(uint64_t N) {
262 assert(N > 0 && N <= 64 && "integer width out of range")(static_cast <bool> (N > 0 && N <= 64 &&
"integer width out of range") ? void (0) : __assert_fail ("N > 0 && N <= 64 && \"integer width out of range\""
, "llvm/include/llvm/Support/MathExtras.h", 262, __extension__
__PRETTY_FUNCTION__))
;
263
264 // uint64_t(1) << 64 is undefined behavior, so we can't do
265 // (uint64_t(1) << N) - 1
266 // without checking first that N != 64. But this works and doesn't have a
267 // branch.
268 return UINT64_MAX(18446744073709551615UL) >> (64 - N);
269}
270
271/// Gets the minimum value for a N-bit signed integer.
272inline int64_t minIntN(int64_t N) {
273 assert(N > 0 && N <= 64 && "integer width out of range")(static_cast <bool> (N > 0 && N <= 64 &&
"integer width out of range") ? void (0) : __assert_fail ("N > 0 && N <= 64 && \"integer width out of range\""
, "llvm/include/llvm/Support/MathExtras.h", 273, __extension__
__PRETTY_FUNCTION__))
;
274
275 return UINT64_C(1)1UL + ~(UINT64_C(1)1UL << (N - 1));
276}
277
278/// Gets the maximum value for a N-bit signed integer.
279inline int64_t maxIntN(int64_t N) {
280 assert(N > 0 && N <= 64 && "integer width out of range")(static_cast <bool> (N > 0 && N <= 64 &&
"integer width out of range") ? void (0) : __assert_fail ("N > 0 && N <= 64 && \"integer width out of range\""
, "llvm/include/llvm/Support/MathExtras.h", 280, __extension__
__PRETTY_FUNCTION__))
;
281
282 // This relies on two's complement wraparound when N == 64, so we convert to
283 // int64_t only at the very end to avoid UB.
284 return (UINT64_C(1)1UL << (N - 1)) - 1;
285}
286
287/// Checks if an unsigned integer fits into the given (dynamic) bit width.
288inline bool isUIntN(unsigned N, uint64_t x) {
289 return N >= 64 || x <= maxUIntN(N);
290}
291
292/// Checks if an signed integer fits into the given (dynamic) bit width.
293inline bool isIntN(unsigned N, int64_t x) {
294 return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N));
295}
296
297/// Return true if the argument is a non-empty sequence of ones starting at the
298/// least significant bit with the remainder zero (32 bit version).
299/// Ex. isMask_32(0x0000FFFFU) == true.
300constexpr inline bool isMask_32(uint32_t Value) {
301 return Value && ((Value + 1) & Value) == 0;
302}
303
304/// Return true if the argument is a non-empty sequence of ones starting at the
305/// least significant bit with the remainder zero (64 bit version).
306constexpr inline bool isMask_64(uint64_t Value) {
307 return Value && ((Value + 1) & Value) == 0;
308}
309
310/// Return true if the argument contains a non-empty sequence of ones with the
311/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true.
312constexpr inline bool isShiftedMask_32(uint32_t Value) {
313 return Value && isMask_32((Value - 1) | Value);
314}
315
316/// Return true if the argument contains a non-empty sequence of ones with the
317/// remainder zero (64 bit version.)
318constexpr inline bool isShiftedMask_64(uint64_t Value) {
319 return Value && isMask_64((Value - 1) | Value);
320}
321
322/// Return true if the argument is a power of two > 0.
323/// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
324constexpr inline bool isPowerOf2_32(uint32_t Value) {
325 return llvm::has_single_bit(Value);
326}
327
328/// Return true if the argument is a power of two > 0 (64 bit edition.)
329constexpr inline bool isPowerOf2_64(uint64_t Value) {
330 return llvm::has_single_bit(Value);
331}
332
333/// Count the number of ones from the most significant bit to the first
334/// zero bit.
335///
336/// Ex. countLeadingOnes(0xFF0FFF00) == 8.
337/// Only unsigned integral types are allowed.
338///
339/// Returns std::numeric_limits<T>::digits on an input of all ones.
340template <typename T> unsigned countLeadingOnes(T Value) {
341 static_assert(std::is_unsigned_v<T>,
342 "Only unsigned integral types are allowed.");
343 return llvm::countl_one<T>(Value);
344}
345
346/// Count the number of ones from the least significant bit to the first
347/// zero bit.
348///
349/// Ex. countTrailingOnes(0x00FF00FF) == 8.
350/// Only unsigned integral types are allowed.
351///
352/// Returns std::numeric_limits<T>::digits on an input of all ones.
353template <typename T> unsigned countTrailingOnes(T Value) {
354 static_assert(std::is_unsigned_v<T>,
355 "Only unsigned integral types are allowed.");
356 return llvm::countr_one<T>(Value);
357}
358
359/// Count the number of set bits in a value.
360/// Ex. countPopulation(0xF000F000) = 8
361/// Returns 0 if the word is zero.
362template <typename T>
363inline unsigned countPopulation(T Value) {
364 static_assert(std::is_unsigned_v<T>,
365 "Only unsigned integral types are allowed.");
366 return (unsigned)llvm::popcount(Value);
367}
368
369/// Return true if the argument contains a non-empty sequence of ones with the
370/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true.
371/// If true, \p MaskIdx will specify the index of the lowest set bit and \p
372/// MaskLen is updated to specify the length of the mask, else neither are
373/// updated.
374inline bool isShiftedMask_32(uint32_t Value, unsigned &MaskIdx,
375 unsigned &MaskLen) {
376 if (!isShiftedMask_32(Value))
377 return false;
378 MaskIdx = llvm::countr_zero(Value);
379 MaskLen = llvm::popcount(Value);
380 return true;
381}
382
383/// Return true if the argument contains a non-empty sequence of ones with the
384/// remainder zero (64 bit version.) If true, \p MaskIdx will specify the index
385/// of the lowest set bit and \p MaskLen is updated to specify the length of the
386/// mask, else neither are updated.
387inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx,
388 unsigned &MaskLen) {
389 if (!isShiftedMask_64(Value))
390 return false;
391 MaskIdx = llvm::countr_zero(Value);
392 MaskLen = llvm::popcount(Value);
393 return true;
394}
395
396/// Compile time Log2.
397/// Valid only for positive powers of two.
398template <size_t kValue> constexpr inline size_t CTLog2() {
399 static_assert(kValue > 0 && llvm::isPowerOf2_64(kValue),
400 "Value is not a valid power of 2");
401 return 1 + CTLog2<kValue / 2>();
402}
403
404template <> constexpr inline size_t CTLog2<1>() { return 0; }
405
406/// Return the floor log base 2 of the specified value, -1 if the value is zero.
407/// (32 bit edition.)
408/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
409inline unsigned Log2_32(uint32_t Value) {
410 return 31 - llvm::countl_zero(Value);
411}
412
413/// Return the floor log base 2 of the specified value, -1 if the value is zero.
414/// (64 bit edition.)
415inline unsigned Log2_64(uint64_t Value) {
416 return 63 - llvm::countl_zero(Value);
417}
418
419/// Return the ceil log base 2 of the specified value, 32 if the value is zero.
420/// (32 bit edition).
421/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
422inline unsigned Log2_32_Ceil(uint32_t Value) {
423 return 32 - llvm::countl_zero(Value - 1);
424}
425
426/// Return the ceil log base 2 of the specified value, 64 if the value is zero.
427/// (64 bit edition.)
428inline unsigned Log2_64_Ceil(uint64_t Value) {
429 return 64 - llvm::countl_zero(Value - 1);
430}
431
432/// This function takes a 64-bit integer and returns the bit equivalent double.
433inline double BitsToDouble(uint64_t Bits) {
434 static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
435 return llvm::bit_cast<double>(Bits);
436}
437
438/// This function takes a 32-bit integer and returns the bit equivalent float.
439inline float BitsToFloat(uint32_t Bits) {
440 static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes");
441 return llvm::bit_cast<float>(Bits);
442}
443
444/// This function takes a double and returns the bit equivalent 64-bit integer.
445/// Note that copying doubles around changes the bits of NaNs on some hosts,
446/// notably x86, so this routine cannot be used if these bits are needed.
447inline uint64_t DoubleToBits(double Double) {
448 static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
449 return llvm::bit_cast<uint64_t>(Double);
450}
451
452/// This function takes a float and returns the bit equivalent 32-bit integer.
453/// Note that copying floats around changes the bits of NaNs on some hosts,
454/// notably x86, so this routine cannot be used if these bits are needed.
455inline uint32_t FloatToBits(float Float) {
456 static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes");
457 return llvm::bit_cast<uint32_t>(Float);
458}
459
460/// A and B are either alignments or offsets. Return the minimum alignment that
461/// may be assumed after adding the two together.
462constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) {
463 // The largest power of 2 that divides both A and B.
464 //
465 // Replace "-Value" by "1+~Value" in the following commented code to avoid
466 // MSVC warning C4146
467 // return (A | B) & -(A | B);
468 return (A | B) & (1 + ~(A | B));
469}
470
471/// Returns the next power of two (in 64-bits) that is strictly greater than A.
472/// Returns zero on overflow.
473constexpr inline uint64_t NextPowerOf2(uint64_t A) {
474 A |= (A >> 1);
475 A |= (A >> 2);
476 A |= (A >> 4);
477 A |= (A >> 8);
478 A |= (A >> 16);
479 A |= (A >> 32);
480 return A + 1;
481}
482
483/// Returns the power of two which is less than or equal to the given value.
484/// Essentially, it is a floor operation across the domain of powers of two.
485inline uint64_t PowerOf2Floor(uint64_t A) {
486 return llvm::bit_floor(A);
487}
488
489/// Returns the power of two which is greater than or equal to the given value.
490/// Essentially, it is a ceil operation across the domain of powers of two.
491inline uint64_t PowerOf2Ceil(uint64_t A) {
492 if (!A)
493 return 0;
494 return NextPowerOf2(A - 1);
495}
496
497/// Returns the next integer (mod 2**64) that is greater than or equal to
498/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
499///
500/// Examples:
501/// \code
502/// alignTo(5, 8) = 8
503/// alignTo(17, 8) = 24
504/// alignTo(~0LL, 8) = 0
505/// alignTo(321, 255) = 510
506/// \endcode
507inline uint64_t alignTo(uint64_t Value, uint64_t Align) {
508 assert(Align != 0u && "Align can't be 0.")(static_cast <bool> (Align != 0u && "Align can't be 0."
) ? void (0) : __assert_fail ("Align != 0u && \"Align can't be 0.\""
, "llvm/include/llvm/Support/MathExtras.h", 508, __extension__
__PRETTY_FUNCTION__))
;
509 return (Value + Align - 1) / Align * Align;
510}
511
512inline uint64_t alignToPowerOf2(uint64_t Value, uint64_t Align) {
513 assert(Align != 0 && (Align & (Align - 1)) == 0 &&(static_cast <bool> (Align != 0 && (Align &
(Align - 1)) == 0 && "Align must be a power of 2") ?
void (0) : __assert_fail ("Align != 0 && (Align & (Align - 1)) == 0 && \"Align must be a power of 2\""
, "llvm/include/llvm/Support/MathExtras.h", 514, __extension__
__PRETTY_FUNCTION__))
514 "Align must be a power of 2")(static_cast <bool> (Align != 0 && (Align &
(Align - 1)) == 0 && "Align must be a power of 2") ?
void (0) : __assert_fail ("Align != 0 && (Align & (Align - 1)) == 0 && \"Align must be a power of 2\""
, "llvm/include/llvm/Support/MathExtras.h", 514, __extension__
__PRETTY_FUNCTION__))
;
515 return (Value + Align - 1) & -Align;
516}
517
518/// If non-zero \p Skew is specified, the return value will be a minimal integer
519/// that is greater than or equal to \p Size and equal to \p A * N + \p Skew for
520/// some integer N. If \p Skew is larger than \p A, its value is adjusted to '\p
521/// Skew mod \p A'. \p Align must be non-zero.
522///
523/// Examples:
524/// \code
525/// alignTo(5, 8, 7) = 7
526/// alignTo(17, 8, 1) = 17
527/// alignTo(~0LL, 8, 3) = 3
528/// alignTo(321, 255, 42) = 552
529/// \endcode
530inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew) {
531 assert(Align != 0u && "Align can't be 0.")(static_cast <bool> (Align != 0u && "Align can't be 0."
) ? void (0) : __assert_fail ("Align != 0u && \"Align can't be 0.\""
, "llvm/include/llvm/Support/MathExtras.h", 531, __extension__
__PRETTY_FUNCTION__))
;
532 Skew %= Align;
533 return alignTo(Value - Skew, Align) + Skew;
534}
535
536/// Returns the next integer (mod 2**64) that is greater than or equal to
537/// \p Value and is a multiple of \c Align. \c Align must be non-zero.
538template <uint64_t Align> constexpr inline uint64_t alignTo(uint64_t Value) {
539 static_assert(Align != 0u, "Align must be non-zero");
540 return (Value + Align - 1) / Align * Align;
541}
542
543/// Returns the integer ceil(Numerator / Denominator).
544inline uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) {
545 return alignTo(Numerator, Denominator) / Denominator;
546}
547
548/// Returns the integer nearest(Numerator / Denominator).
549inline uint64_t divideNearest(uint64_t Numerator, uint64_t Denominator) {
550 return (Numerator + (Denominator / 2)) / Denominator;
551}
552
553/// Returns the largest uint64_t less than or equal to \p Value and is
554/// \p Skew mod \p Align. \p Align must be non-zero
555inline uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew = 0) {
556 assert(Align != 0u && "Align can't be 0.")(static_cast <bool> (Align != 0u && "Align can't be 0."
) ? void (0) : __assert_fail ("Align != 0u && \"Align can't be 0.\""
, "llvm/include/llvm/Support/MathExtras.h", 556, __extension__
__PRETTY_FUNCTION__))
;
557 Skew %= Align;
558 return (Value - Skew) / Align * Align + Skew;
559}
560
561/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
562/// Requires 0 < B <= 32.
563template <unsigned B> constexpr inline int32_t SignExtend32(uint32_t X) {
564 static_assert(B > 0, "Bit width can't be 0.");
565 static_assert(B <= 32, "Bit width out of range.");
566 return int32_t(X << (32 - B)) >> (32 - B);
567}
568
569/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
570/// Requires 0 < B <= 32.
571inline int32_t SignExtend32(uint32_t X, unsigned B) {
572 assert(B > 0 && "Bit width can't be 0.")(static_cast <bool> (B > 0 && "Bit width can't be 0."
) ? void (0) : __assert_fail ("B > 0 && \"Bit width can't be 0.\""
, "llvm/include/llvm/Support/MathExtras.h", 572, __extension__
__PRETTY_FUNCTION__))
;
573 assert(B <= 32 && "Bit width out of range.")(static_cast <bool> (B <= 32 && "Bit width out of range."
) ? void (0) : __assert_fail ("B <= 32 && \"Bit width out of range.\""
, "llvm/include/llvm/Support/MathExtras.h", 573, __extension__
__PRETTY_FUNCTION__))
;
574 return int32_t(X << (32 - B)) >> (32 - B);
575}
576
577/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
578/// Requires 0 < B <= 64.
579template <unsigned B> constexpr inline int64_t SignExtend64(uint64_t x) {
580 static_assert(B > 0, "Bit width can't be 0.");
581 static_assert(B <= 64, "Bit width out of range.");
582 return int64_t(x << (64 - B)) >> (64 - B);
583}
584
585/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
586/// Requires 0 < B <= 64.
587inline int64_t SignExtend64(uint64_t X, unsigned B) {
588 assert(B > 0 && "Bit width can't be 0.")(static_cast <bool> (B > 0 && "Bit width can't be 0."
) ? void (0) : __assert_fail ("B > 0 && \"Bit width can't be 0.\""
, "llvm/include/llvm/Support/MathExtras.h", 588, __extension__
__PRETTY_FUNCTION__))
;
589 assert(B <= 64 && "Bit width out of range.")(static_cast <bool> (B <= 64 && "Bit width out of range."
) ? void (0) : __assert_fail ("B <= 64 && \"Bit width out of range.\""
, "llvm/include/llvm/Support/MathExtras.h", 589, __extension__
__PRETTY_FUNCTION__))
;
590 return int64_t(X << (64 - B)) >> (64 - B);
591}
592
593/// Subtract two unsigned integers, X and Y, of type T and return the absolute
594/// value of the result.
595template <typename T>
596std::enable_if_t<std::is_unsigned<T>::value, T> AbsoluteDifference(T X, T Y) {
597 return X > Y ? (X - Y) : (Y - X);
598}
599
600/// Add two unsigned integers, X and Y, of type T. Clamp the result to the
601/// maximum representable value of T on overflow. ResultOverflowed indicates if
602/// the result is larger than the maximum representable value of type T.
603template <typename T>
604std::enable_if_t<std::is_unsigned<T>::value, T>
605SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
606 bool Dummy;
607 bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
608 // Hacker's Delight, p. 29
609 T Z = X + Y;
610 Overflowed = (Z < X || Z < Y);
611 if (Overflowed)
612 return std::numeric_limits<T>::max();
613 else
614 return Z;
615}
616
617/// Add multiple unsigned integers of type T. Clamp the result to the
618/// maximum representable value of T on overflow.
619template <class T, class... Ts>
620std::enable_if_t<std::is_unsigned_v<T>, T> SaturatingAdd(T X, T Y, T Z,
621 Ts... Args) {
622 bool Overflowed = false;
623 T XY = SaturatingAdd(X, Y, &Overflowed);
624 if (Overflowed)
625 return SaturatingAdd(std::numeric_limits<T>::max(), T(1), Args...);
626 return SaturatingAdd(XY, Z, Args...);
627}
628
629/// Multiply two unsigned integers, X and Y, of type T. Clamp the result to the
630/// maximum representable value of T on overflow. ResultOverflowed indicates if
631/// the result is larger than the maximum representable value of type T.
632template <typename T>
633std::enable_if_t<std::is_unsigned<T>::value, T>
634SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
635 bool Dummy;
636 bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
637
638 // Hacker's Delight, p. 30 has a different algorithm, but we don't use that
639 // because it fails for uint16_t (where multiplication can have undefined
640 // behavior due to promotion to int), and requires a division in addition
641 // to the multiplication.
642
643 Overflowed = false;
644
645 // Log2(Z) would be either Log2Z or Log2Z + 1.
646 // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z
647 // will necessarily be less than Log2Max as desired.
648 int Log2Z = Log2_64(X) + Log2_64(Y);
649 const T Max = std::numeric_limits<T>::max();
650 int Log2Max = Log2_64(Max);
651 if (Log2Z < Log2Max) {
652 return X * Y;
653 }
654 if (Log2Z > Log2Max) {
655 Overflowed = true;
656 return Max;
657 }
658
659 // We're going to use the top bit, and maybe overflow one
660 // bit past it. Multiply all but the bottom bit then add
661 // that on at the end.
662 T Z = (X >> 1) * Y;
663 if (Z & ~(Max >> 1)) {
664 Overflowed = true;
665 return Max;
666 }
667 Z <<= 1;
668 if (X & 1)
669 return SaturatingAdd(Z, Y, ResultOverflowed);
670
671 return Z;
672}
673
674/// Multiply two unsigned integers, X and Y, and add the unsigned integer, A to
675/// the product. Clamp the result to the maximum representable value of T on
676/// overflow. ResultOverflowed indicates if the result is larger than the
677/// maximum representable value of type T.
678template <typename T>
679std::enable_if_t<std::is_unsigned<T>::value, T>
680SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
681 bool Dummy;
682 bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
683
684 T Product = SaturatingMultiply(X, Y, &Overflowed);
685 if (Overflowed)
686 return Product;
687
688 return SaturatingAdd(A, Product, &Overflowed);
689}
690
691/// Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
692extern const float huge_valf;
693
694
695/// Add two signed integers, computing the two's complement truncated result,
696/// returning true if overflow occurred.
697template <typename T>
698std::enable_if_t<std::is_signed<T>::value, T> AddOverflow(T X, T Y, T &Result) {
699#if __has_builtin(__builtin_add_overflow)1
700 return __builtin_add_overflow(X, Y, &Result);
701#else
702 // Perform the unsigned addition.
703 using U = std::make_unsigned_t<T>;
704 const U UX = static_cast<U>(X);
705 const U UY = static_cast<U>(Y);
706 const U UResult = UX + UY;
707
708 // Convert to signed.
709 Result = static_cast<T>(UResult);
710
711 // Adding two positive numbers should result in a positive number.
712 if (X > 0 && Y > 0)
713 return Result <= 0;
714 // Adding two negatives should result in a negative number.
715 if (X < 0 && Y < 0)
716 return Result >= 0;
717 return false;
718#endif
719}
720
721/// Subtract two signed integers, computing the two's complement truncated
722/// result, returning true if an overflow ocurred.
723template <typename T>
724std::enable_if_t<std::is_signed<T>::value, T> SubOverflow(T X, T Y, T &Result) {
725#if __has_builtin(__builtin_sub_overflow)1
726 return __builtin_sub_overflow(X, Y, &Result);
727#else
728 // Perform the unsigned addition.
729 using U = std::make_unsigned_t<T>;
730 const U UX = static_cast<U>(X);
731 const U UY = static_cast<U>(Y);
732 const U UResult = UX - UY;
733
734 // Convert to signed.
735 Result = static_cast<T>(UResult);
736
737 // Subtracting a positive number from a negative results in a negative number.
738 if (X <= 0 && Y > 0)
739 return Result >= 0;
740 // Subtracting a negative number from a positive results in a positive number.
741 if (X >= 0 && Y < 0)
742 return Result <= 0;
743 return false;
744#endif
745}
746
747/// Multiply two signed integers, computing the two's complement truncated
748/// result, returning true if an overflow ocurred.
749template <typename T>
750std::enable_if_t<std::is_signed<T>::value, T> MulOverflow(T X, T Y, T &Result) {
751 // Perform the unsigned multiplication on absolute values.
752 using U = std::make_unsigned_t<T>;
753 const U UX = X < 0 ? (0 - static_cast<U>(X)) : static_cast<U>(X);
754 const U UY = Y < 0 ? (0 - static_cast<U>(Y)) : static_cast<U>(Y);
755 const U UResult = UX * UY;
756
757 // Convert to signed.
758 const bool IsNegative = (X < 0) ^ (Y < 0);
759 Result = IsNegative ? (0 - UResult) : UResult;
760
761 // If any of the args was 0, result is 0 and no overflow occurs.
762 if (UX == 0 || UY == 0)
763 return false;
764
765 // UX and UY are in [1, 2^n], where n is the number of digits.
766 // Check how the max allowed absolute value (2^n for negative, 2^(n-1) for
767 // positive) divided by an argument compares to the other.
768 if (IsNegative)
769 return UX > (static_cast<U>(std::numeric_limits<T>::max()) + U(1)) / UY;
770 else
771 return UX > (static_cast<U>(std::numeric_limits<T>::max())) / UY;
772}
773
774} // End llvm namespace
775
776#endif

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/limits

1// The template and inlines for the numeric_limits classes. -*- C++ -*-
2
3// Copyright (C) 1999-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/limits
26 * This is a Standard C++ Library header.
27 */
28
29// Note: this is not a conforming implementation.
30// Written by Gabriel Dos Reis <gdr@codesourcery.com>
31
32//
33// ISO 14882:1998
34// 18.2.1
35//
36
37#ifndef _GLIBCXX_NUMERIC_LIMITS1
38#define _GLIBCXX_NUMERIC_LIMITS1 1
39
40#pragma GCC system_header
41
42#include <bits/c++config.h>
43
44//
45// The numeric_limits<> traits document implementation-defined aspects
46// of fundamental arithmetic data types (integers and floating points).
47// From Standard C++ point of view, there are 14 such types:
48// * integers
49// bool (1)
50// char, signed char, unsigned char, wchar_t (4)
51// short, unsigned short (2)
52// int, unsigned (2)
53// long, unsigned long (2)
54//
55// * floating points
56// float (1)
57// double (1)
58// long double (1)
59//
60// GNU C++ understands (where supported by the host C-library)
61// * integer
62// long long, unsigned long long (2)
63//
64// which brings us to 16 fundamental arithmetic data types in GNU C++.
65//
66//
67// Since a numeric_limits<> is a bit tricky to get right, we rely on
68// an interface composed of macros which should be defined in config/os
69// or config/cpu when they differ from the generic (read arbitrary)
70// definitions given here.
71//
72
73// These values can be overridden in the target configuration file.
74// The default values are appropriate for many 32-bit targets.
75
76// GCC only intrinsically supports modulo integral types. The only remaining
77// integral exceptional values is division by zero. Only targets that do not
78// signal division by zero in some "hard to ignore" way should use false.
79#ifndef __glibcxx_integral_trapstrue
80# define __glibcxx_integral_trapstrue true
81#endif
82
83// float
84//
85
86// Default values. Should be overridden in configuration files if necessary.
87
88#ifndef __glibcxx_float_has_denorm_loss
89# define __glibcxx_float_has_denorm_loss false
90#endif
91#ifndef __glibcxx_float_traps
92# define __glibcxx_float_traps false
93#endif
94#ifndef __glibcxx_float_tinyness_before
95# define __glibcxx_float_tinyness_before false
96#endif
97
98// double
99
100// Default values. Should be overridden in configuration files if necessary.
101
102#ifndef __glibcxx_double_has_denorm_loss
103# define __glibcxx_double_has_denorm_loss false
104#endif
105#ifndef __glibcxx_double_traps
106# define __glibcxx_double_traps false
107#endif
108#ifndef __glibcxx_double_tinyness_before
109# define __glibcxx_double_tinyness_before false
110#endif
111
112// long double
113
114// Default values. Should be overridden in configuration files if necessary.
115
116#ifndef __glibcxx_long_double_has_denorm_loss
117# define __glibcxx_long_double_has_denorm_loss false
118#endif
119#ifndef __glibcxx_long_double_traps
120# define __glibcxx_long_double_traps false
121#endif
122#ifndef __glibcxx_long_double_tinyness_before
123# define __glibcxx_long_double_tinyness_before false
124#endif
125
126// You should not need to define any macros below this point.
127
128#define __glibcxx_signed_b(T,B)((T)(-1) < 0) ((T)(-1) < 0)
129
130#define __glibcxx_min_b(T,B)(((T)(-1) < 0) ? -(((T)(-1) < 0) ? (((((T)1 << ((
B - ((T)(-1) < 0)) - 1)) - 1) << 1) + 1) : ~(T)0) - 1
: (T)0)
\
131 (__glibcxx_signed_b (T,B)((T)(-1) < 0) ? -__glibcxx_max_b (T,B)(((T)(-1) < 0) ? (((((T)1 << ((B - ((T)(-1) < 0))
- 1)) - 1) << 1) + 1) : ~(T)0)
- 1 : (T)0)
132
133#define __glibcxx_max_b(T,B)(((T)(-1) < 0) ? (((((T)1 << ((B - ((T)(-1) < 0))
- 1)) - 1) << 1) + 1) : ~(T)0)
\
134 (__glibcxx_signed_b (T,B)((T)(-1) < 0) ? \
135 (((((T)1 << (__glibcxx_digits_b (T,B)(B - ((T)(-1) < 0)) - 1)) - 1) << 1) + 1) : ~(T)0)
136
137#define __glibcxx_digits_b(T,B)(B - ((T)(-1) < 0)) \
138 (B - __glibcxx_signed_b (T,B)((T)(-1) < 0))
139
140// The fraction 643/2136 approximates log10(2) to 7 significant digits.
141#define __glibcxx_digits10_b(T,B)((B - ((T)(-1) < 0)) * 643L / 2136) \
142 (__glibcxx_digits_b (T,B)(B - ((T)(-1) < 0)) * 643L / 2136)
143
144#define __glibcxx_signed(T) \
145 __glibcxx_signed_b (T, sizeof(T) * __CHAR_BIT__)((T)(-1) < 0)
146#define __glibcxx_min(T) \
147 __glibcxx_min_b (T, sizeof(T) * __CHAR_BIT__)(((T)(-1) < 0) ? -(((T)(-1) < 0) ? (((((T)1 << ((
sizeof(T) * 8 - ((T)(-1) < 0)) - 1)) - 1) << 1) + 1)
: ~(T)0) - 1 : (T)0)
148#define __glibcxx_max(T) \
149 __glibcxx_max_b (T, sizeof(T) * __CHAR_BIT__)(((T)(-1) < 0) ? (((((T)1 << ((sizeof(T) * 8 - ((T)(
-1) < 0)) - 1)) - 1) << 1) + 1) : ~(T)0)
150#define __glibcxx_digits(T) \
151 __glibcxx_digits_b (T, sizeof(T) * __CHAR_BIT__)(sizeof(T) * 8 - ((T)(-1) < 0))
152#define __glibcxx_digits10(T) \
153 __glibcxx_digits10_b (T, sizeof(T) * __CHAR_BIT__)((sizeof(T) * 8 - ((T)(-1) < 0)) * 643L / 2136)
154
155#define __glibcxx_max_digits10(T) \
156 (2 + (T) * 643L / 2136)
157
158namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
159{
160_GLIBCXX_BEGIN_NAMESPACE_VERSION
161
162 /**
163 * @brief Describes the rounding style for floating-point types.
164 *
165 * This is used in the std::numeric_limits class.
166 */
167 enum float_round_style
168 {
169 round_indeterminate = -1, /// Intermediate.
170 round_toward_zero = 0, /// To zero.
171 round_to_nearest = 1, /// To the nearest representable value.
172 round_toward_infinity = 2, /// To infinity.
173 round_toward_neg_infinity = 3 /// To negative infinity.
174 };
175
176 /**
177 * @brief Describes the denormalization for floating-point types.
178 *
179 * These values represent the presence or absence of a variable number
180 * of exponent bits. This type is used in the std::numeric_limits class.
181 */
182 enum float_denorm_style
183 {
184 /// Indeterminate at compile time whether denormalized values are allowed.
185 denorm_indeterminate = -1,
186 /// The type does not allow denormalized values.
187 denorm_absent = 0,
188 /// The type allows denormalized values.
189 denorm_present = 1
190 };
191
192 /**
193 * @brief Part of std::numeric_limits.
194 *
195 * The @c static @c const members are usable as integral constant
196 * expressions.
197 *
198 * @note This is a separate class for purposes of efficiency; you
199 * should only access these members as part of an instantiation
200 * of the std::numeric_limits class.
201 */
202 struct __numeric_limits_base
203 {
204 /** This will be true for all fundamental types (which have
205 specializations), and false for everything else. */
206 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = false;
207
208 /** The number of @c radix digits that be represented without change: for
209 integer types, the number of non-sign bits in the mantissa; for
210 floating types, the number of @c radix digits in the mantissa. */
211 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = 0;
212
213 /** The number of base 10 digits that can be represented without change. */
214 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = 0;
215
216#if __cplusplus201703L >= 201103L
217 /** The number of base 10 digits required to ensure that values which
218 differ are always differentiated. */
219 static constexpr int max_digits10 = 0;
220#endif
221
222 /** True if the type is signed. */
223 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false;
224
225 /** True if the type is integer. */
226 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = false;
227
228 /** True if the type uses an exact representation. All integer types are
229 exact, but not all exact types are integer. For example, rational and
230 fixed-exponent representations are exact but not integer. */
231 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = false;
232
233 /** For integer types, specifies the base of the representation. For
234 floating types, specifies the base of the exponent representation. */
235 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 0;
236
237 /** The minimum negative integer such that @c radix raised to the power of
238 (one less than that integer) is a normalized floating point number. */
239 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
240
241 /** The minimum negative integer such that 10 raised to that power is in
242 the range of normalized floating point numbers. */
243 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
244
245 /** The maximum positive integer such that @c radix raised to the power of
246 (one less than that integer) is a representable finite floating point
247 number. */
248 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
249
250 /** The maximum positive integer such that 10 raised to that power is in
251 the range of representable finite floating point numbers. */
252 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
253
254 /** True if the type has a representation for positive infinity. */
255 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
256
257 /** True if the type has a representation for a quiet (non-signaling)
258 Not a Number. */
259 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
260
261 /** True if the type has a representation for a signaling
262 Not a Number. */
263 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
264
265 /** See std::float_denorm_style for more information. */
266 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm = denorm_absent;
267
268 /** True if loss of accuracy is detected as a denormalization loss,
269 rather than as an inexact result. */
270 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
271
272 /** True if-and-only-if the type adheres to the IEC 559 standard, also
273 known as IEEE 754. (Only makes sense for floating point types.) */
274 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
275
276 /** True if the set of values representable by the type is
277 finite. All built-in types are bounded, this member would be
278 false for arbitrary precision types. */
279 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = false;
280
281 /** True if the type is @e modulo. A type is modulo if, for any
282 operation involving +, -, or * on values of that type whose
283 result would fall outside the range [min(),max()], the value
284 returned differs from the true value by an integer multiple of
285 max() - min() + 1. On most machines, this is false for floating
286 types, true for unsigned integers, and true for signed integers.
287 See PR22200 about signed integers. */
288 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
289
290 /** True if trapping is implemented for this type. */
291 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = false;
292
293 /** True if tininess is detected before rounding. (see IEC 559) */
294 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
295
296 /** See std::float_round_style for more information. This is only
297 meaningful for floating types; integer types will all be
298 round_toward_zero. */
299 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style =
300 round_toward_zero;
301 };
302
303 /**
304 * @brief Properties of fundamental types.
305 *
306 * This class allows a program to obtain information about the
307 * representation of a fundamental type on a given platform. For
308 * non-fundamental types, the functions will return 0 and the data
309 * members will all be @c false.
310 */
311 template<typename _Tp>
312 struct numeric_limits : public __numeric_limits_base
313 {
314 /** The minimum finite value, or for floating types with
315 denormalization, the minimum positive normalized value. */
316 static _GLIBCXX_CONSTEXPRconstexpr _Tp
317 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
318
319 /** The maximum finite value. */
320 static _GLIBCXX_CONSTEXPRconstexpr _Tp
321 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
322
323#if __cplusplus201703L >= 201103L
324 /** A finite value x such that there is no other finite value y
325 * where y < x. */
326 static constexpr _Tp
327 lowest() noexcept { return _Tp(); }
328#endif
329
330 /** The @e machine @e epsilon: the difference between 1 and the least
331 value greater than 1 that is representable. */
332 static _GLIBCXX_CONSTEXPRconstexpr _Tp
333 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
334
335 /** The maximum rounding error measurement (see LIA-1). */
336 static _GLIBCXX_CONSTEXPRconstexpr _Tp
337 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
338
339 /** The representation of positive infinity, if @c has_infinity. */
340 static _GLIBCXX_CONSTEXPRconstexpr _Tp
341 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
342
343 /** The representation of a quiet Not a Number,
344 if @c has_quiet_NaN. */
345 static _GLIBCXX_CONSTEXPRconstexpr _Tp
346 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
347
348 /** The representation of a signaling Not a Number, if
349 @c has_signaling_NaN. */
350 static _GLIBCXX_CONSTEXPRconstexpr _Tp
351 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
352
353 /** The minimum positive denormalized value. For types where
354 @c has_denorm is false, this is the minimum positive normalized
355 value. */
356 static _GLIBCXX_CONSTEXPRconstexpr _Tp
357 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return _Tp(); }
358 };
359
360 // _GLIBCXX_RESOLVE_LIB_DEFECTS
361 // 559. numeric_limits<const T>
362
363 template<typename _Tp>
364 struct numeric_limits<const _Tp>
365 : public numeric_limits<_Tp> { };
366
367 template<typename _Tp>
368 struct numeric_limits<volatile _Tp>
369 : public numeric_limits<_Tp> { };
370
371 template<typename _Tp>
372 struct numeric_limits<const volatile _Tp>
373 : public numeric_limits<_Tp> { };
374
375 // Now there follow 16 explicit specializations. Yes, 16. Make sure
376 // you get the count right. (18 in C++11 mode, with char16_t and char32_t.)
377 // (+1 if char8_t is enabled.)
378
379 // _GLIBCXX_RESOLVE_LIB_DEFECTS
380 // 184. numeric_limits<bool> wording problems
381
382 /// numeric_limits<bool> specialization.
383 template<>
384 struct numeric_limits<bool>
385 {
386 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
387
388 static _GLIBCXX_CONSTEXPRconstexpr bool
389 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return false; }
390
391 static _GLIBCXX_CONSTEXPRconstexpr bool
392 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return true; }
393
394#if __cplusplus201703L >= 201103L
395 static constexpr bool
396 lowest() noexcept { return min(); }
397#endif
398 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = 1;
399 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = 0;
400#if __cplusplus201703L >= 201103L
401 static constexpr int max_digits10 = 0;
402#endif
403 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false;
404 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
405 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
406 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
407
408 static _GLIBCXX_CONSTEXPRconstexpr bool
409 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return false; }
410
411 static _GLIBCXX_CONSTEXPRconstexpr bool
412 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return false; }
413
414 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
415 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
416 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
417 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
418
419 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
420 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
421 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
422 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
423 = denorm_absent;
424 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
425
426 static _GLIBCXX_CONSTEXPRconstexpr bool
427 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return false; }
428
429 static _GLIBCXX_CONSTEXPRconstexpr bool
430 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return false; }
431
432 static _GLIBCXX_CONSTEXPRconstexpr bool
433 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return false; }
434
435 static _GLIBCXX_CONSTEXPRconstexpr bool
436 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return false; }
437
438 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
439 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
440 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
441
442 // It is not clear what it means for a boolean type to trap.
443 // This is a DR on the LWG issue list. Here, I use integer
444 // promotion semantics.
445 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
446 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
447 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
448 = round_toward_zero;
449 };
450
451 /// numeric_limits<char> specialization.
452 template<>
453 struct numeric_limits<char>
454 {
455 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
456
457 static _GLIBCXX_CONSTEXPRconstexpr char
458 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_min(char); }
459
460 static _GLIBCXX_CONSTEXPRconstexpr char
461 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_max(char); }
462
463#if __cplusplus201703L >= 201103L
464 static constexpr char
465 lowest() noexcept { return min(); }
466#endif
467
468 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __glibcxx_digits (char);
469 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __glibcxx_digits10 (char);
470#if __cplusplus201703L >= 201103L
471 static constexpr int max_digits10 = 0;
472#endif
473 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = __glibcxx_signed (char);
474 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
475 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
476 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
477
478 static _GLIBCXX_CONSTEXPRconstexpr char
479 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
480
481 static _GLIBCXX_CONSTEXPRconstexpr char
482 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
483
484 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
485 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
486 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
487 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
488
489 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
490 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
491 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
492 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
493 = denorm_absent;
494 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
495
496 static _GLIBCXX_CONSTEXPRconstexpr
497 char infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return char(); }
498
499 static _GLIBCXX_CONSTEXPRconstexpr char
500 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return char(); }
501
502 static _GLIBCXX_CONSTEXPRconstexpr char
503 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return char(); }
504
505 static _GLIBCXX_CONSTEXPRconstexpr char
506 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<char>(0); }
507
508 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
509 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
510 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = !is_signed;
511
512 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
513 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
514 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
515 = round_toward_zero;
516 };
517
518 /// numeric_limits<signed char> specialization.
519 template<>
520 struct numeric_limits<signed char>
521 {
522 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
523
524 static _GLIBCXX_CONSTEXPRconstexpr signed char
525 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return -__SCHAR_MAX__127 - 1; }
526
527 static _GLIBCXX_CONSTEXPRconstexpr signed char
528 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __SCHAR_MAX__127; }
529
530#if __cplusplus201703L >= 201103L
531 static constexpr signed char
532 lowest() noexcept { return min(); }
533#endif
534
535 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __glibcxx_digits (signed char);
536 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
537 = __glibcxx_digits10 (signed char);
538#if __cplusplus201703L >= 201103L
539 static constexpr int max_digits10 = 0;
540#endif
541 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
542 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
543 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
544 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
545
546 static _GLIBCXX_CONSTEXPRconstexpr signed char
547 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
548
549 static _GLIBCXX_CONSTEXPRconstexpr signed char
550 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
551
552 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
553 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
554 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
555 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
556
557 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
558 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
559 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
560 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
561 = denorm_absent;
562 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
563
564 static _GLIBCXX_CONSTEXPRconstexpr signed char
565 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<signed char>(0); }
566
567 static _GLIBCXX_CONSTEXPRconstexpr signed char
568 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<signed char>(0); }
569
570 static _GLIBCXX_CONSTEXPRconstexpr signed char
571 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
572 { return static_cast<signed char>(0); }
573
574 static _GLIBCXX_CONSTEXPRconstexpr signed char
575 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept
576 { return static_cast<signed char>(0); }
577
578 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
579 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
580 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
581
582 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
583 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
584 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
585 = round_toward_zero;
586 };
587
588 /// numeric_limits<unsigned char> specialization.
589 template<>
590 struct numeric_limits<unsigned char>
591 {
592 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
593
594 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
595 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
596
597 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
598 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __SCHAR_MAX__127 * 2U + 1; }
599
600#if __cplusplus201703L >= 201103L
601 static constexpr unsigned char
602 lowest() noexcept { return min(); }
603#endif
604
605 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits
606 = __glibcxx_digits (unsigned char);
607 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
608 = __glibcxx_digits10 (unsigned char);
609#if __cplusplus201703L >= 201103L
610 static constexpr int max_digits10 = 0;
611#endif
612 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false;
613 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
614 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
615 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
616
617 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
618 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
619
620 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
621 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
622
623 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
624 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
625 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
626 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
627
628 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
629 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
630 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
631 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
632 = denorm_absent;
633 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
634
635 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
636 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept
637 { return static_cast<unsigned char>(0); }
638
639 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
640 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
641 { return static_cast<unsigned char>(0); }
642
643 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
644 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
645 { return static_cast<unsigned char>(0); }
646
647 static _GLIBCXX_CONSTEXPRconstexpr unsigned char
648 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept
649 { return static_cast<unsigned char>(0); }
650
651 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
652 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
653 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = true;
654
655 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
656 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
657 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
658 = round_toward_zero;
659 };
660
661 /// numeric_limits<wchar_t> specialization.
662 template<>
663 struct numeric_limits<wchar_t>
664 {
665 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
666
667 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
668 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_min (wchar_t); }
669
670 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
671 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_max (wchar_t); }
672
673#if __cplusplus201703L >= 201103L
674 static constexpr wchar_t
675 lowest() noexcept { return min(); }
676#endif
677
678 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __glibcxx_digits (wchar_t);
679 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
680 = __glibcxx_digits10 (wchar_t);
681#if __cplusplus201703L >= 201103L
682 static constexpr int max_digits10 = 0;
683#endif
684 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = __glibcxx_signed (wchar_t);
685 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
686 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
687 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
688
689 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
690 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
691
692 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
693 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
694
695 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
696 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
697 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
698 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
699
700 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
701 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
702 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
703 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
704 = denorm_absent;
705 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
706
707 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
708 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return wchar_t(); }
709
710 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
711 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return wchar_t(); }
712
713 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
714 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return wchar_t(); }
715
716 static _GLIBCXX_CONSTEXPRconstexpr wchar_t
717 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return wchar_t(); }
718
719 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
720 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
721 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = !is_signed;
722
723 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
724 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
725 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
726 = round_toward_zero;
727 };
728
729#if _GLIBCXX_USE_CHAR8_T
730 /// numeric_limits<char8_t> specialization.
731 template<>
732 struct numeric_limits<char8_t>
733 {
734 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
735
736 static _GLIBCXX_CONSTEXPRconstexpr char8_t
737 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_min (char8_t); }
738
739 static _GLIBCXX_CONSTEXPRconstexpr char8_t
740 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_max (char8_t); }
741
742 static _GLIBCXX_CONSTEXPRconstexpr char8_t
743 lowest() _GLIBCXX_USE_NOEXCEPTnoexcept { return min(); }
744
745 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __glibcxx_digits (char8_t);
746 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __glibcxx_digits10 (char8_t);
747 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_digits10 = 0;
748 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = __glibcxx_signed (char8_t);
749 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
750 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
751 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
752
753 static _GLIBCXX_CONSTEXPRconstexpr char8_t
754 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
755
756 static _GLIBCXX_CONSTEXPRconstexpr char8_t
757 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
758
759 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
760 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
761 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
762 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
763
764 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
765 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
766 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
767 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
768 = denorm_absent;
769 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
770
771 static _GLIBCXX_CONSTEXPRconstexpr char8_t
772 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return char8_t(); }
773
774 static _GLIBCXX_CONSTEXPRconstexpr char8_t
775 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return char8_t(); }
776
777 static _GLIBCXX_CONSTEXPRconstexpr char8_t
778 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return char8_t(); }
779
780 static _GLIBCXX_CONSTEXPRconstexpr char8_t
781 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return char8_t(); }
782
783 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
784 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
785 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = !is_signed;
786
787 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
788 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
789 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
790 = round_toward_zero;
791 };
792#endif
793
794#if __cplusplus201703L >= 201103L
795 /// numeric_limits<char16_t> specialization.
796 template<>
797 struct numeric_limits<char16_t>
798 {
799 static constexpr bool is_specialized = true;
800
801 static constexpr char16_t
802 min() noexcept { return __glibcxx_min (char16_t); }
803
804 static constexpr char16_t
805 max() noexcept { return __glibcxx_max (char16_t); }
806
807 static constexpr char16_t
808 lowest() noexcept { return min(); }
809
810 static constexpr int digits = __glibcxx_digits (char16_t);
811 static constexpr int digits10 = __glibcxx_digits10 (char16_t);
812 static constexpr int max_digits10 = 0;
813 static constexpr bool is_signed = __glibcxx_signed (char16_t);
814 static constexpr bool is_integer = true;
815 static constexpr bool is_exact = true;
816 static constexpr int radix = 2;
817
818 static constexpr char16_t
819 epsilon() noexcept { return 0; }
820
821 static constexpr char16_t
822 round_error() noexcept { return 0; }
823
824 static constexpr int min_exponent = 0;
825 static constexpr int min_exponent10 = 0;
826 static constexpr int max_exponent = 0;
827 static constexpr int max_exponent10 = 0;
828
829 static constexpr bool has_infinity = false;
830 static constexpr bool has_quiet_NaN = false;
831 static constexpr bool has_signaling_NaN = false;
832 static constexpr float_denorm_style has_denorm = denorm_absent;
833 static constexpr bool has_denorm_loss = false;
834
835 static constexpr char16_t
836 infinity() noexcept { return char16_t(); }
837
838 static constexpr char16_t
839 quiet_NaN() noexcept { return char16_t(); }
840
841 static constexpr char16_t
842 signaling_NaN() noexcept { return char16_t(); }
843
844 static constexpr char16_t
845 denorm_min() noexcept { return char16_t(); }
846
847 static constexpr bool is_iec559 = false;
848 static constexpr bool is_bounded = true;
849 static constexpr bool is_modulo = !is_signed;
850
851 static constexpr bool traps = __glibcxx_integral_trapstrue;
852 static constexpr bool tinyness_before = false;
853 static constexpr float_round_style round_style = round_toward_zero;
854 };
855
856 /// numeric_limits<char32_t> specialization.
857 template<>
858 struct numeric_limits<char32_t>
859 {
860 static constexpr bool is_specialized = true;
861
862 static constexpr char32_t
863 min() noexcept { return __glibcxx_min (char32_t); }
864
865 static constexpr char32_t
866 max() noexcept { return __glibcxx_max (char32_t); }
867
868 static constexpr char32_t
869 lowest() noexcept { return min(); }
870
871 static constexpr int digits = __glibcxx_digits (char32_t);
872 static constexpr int digits10 = __glibcxx_digits10 (char32_t);
873 static constexpr int max_digits10 = 0;
874 static constexpr bool is_signed = __glibcxx_signed (char32_t);
875 static constexpr bool is_integer = true;
876 static constexpr bool is_exact = true;
877 static constexpr int radix = 2;
878
879 static constexpr char32_t
880 epsilon() noexcept { return 0; }
881
882 static constexpr char32_t
883 round_error() noexcept { return 0; }
884
885 static constexpr int min_exponent = 0;
886 static constexpr int min_exponent10 = 0;
887 static constexpr int max_exponent = 0;
888 static constexpr int max_exponent10 = 0;
889
890 static constexpr bool has_infinity = false;
891 static constexpr bool has_quiet_NaN = false;
892 static constexpr bool has_signaling_NaN = false;
893 static constexpr float_denorm_style has_denorm = denorm_absent;
894 static constexpr bool has_denorm_loss = false;
895
896 static constexpr char32_t
897 infinity() noexcept { return char32_t(); }
898
899 static constexpr char32_t
900 quiet_NaN() noexcept { return char32_t(); }
901
902 static constexpr char32_t
903 signaling_NaN() noexcept { return char32_t(); }
904
905 static constexpr char32_t
906 denorm_min() noexcept { return char32_t(); }
907
908 static constexpr bool is_iec559 = false;
909 static constexpr bool is_bounded = true;
910 static constexpr bool is_modulo = !is_signed;
911
912 static constexpr bool traps = __glibcxx_integral_trapstrue;
913 static constexpr bool tinyness_before = false;
914 static constexpr float_round_style round_style = round_toward_zero;
915 };
916#endif
917
918 /// numeric_limits<short> specialization.
919 template<>
920 struct numeric_limits<short>
921 {
922 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
923
924 static _GLIBCXX_CONSTEXPRconstexpr short
925 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return -__SHRT_MAX__32767 - 1; }
926
927 static _GLIBCXX_CONSTEXPRconstexpr short
928 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __SHRT_MAX__32767; }
929
930#if __cplusplus201703L >= 201103L
931 static constexpr short
932 lowest() noexcept { return min(); }
933#endif
934
935 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __glibcxx_digits (short);
936 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __glibcxx_digits10 (short);
937#if __cplusplus201703L >= 201103L
938 static constexpr int max_digits10 = 0;
939#endif
940 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
941 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
942 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
943 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
944
945 static _GLIBCXX_CONSTEXPRconstexpr short
946 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
947
948 static _GLIBCXX_CONSTEXPRconstexpr short
949 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
950
951 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
952 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
953 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
954 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
955
956 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
957 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
958 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
959 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
960 = denorm_absent;
961 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
962
963 static _GLIBCXX_CONSTEXPRconstexpr short
964 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return short(); }
965
966 static _GLIBCXX_CONSTEXPRconstexpr short
967 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return short(); }
968
969 static _GLIBCXX_CONSTEXPRconstexpr short
970 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return short(); }
971
972 static _GLIBCXX_CONSTEXPRconstexpr short
973 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return short(); }
974
975 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
976 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
977 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
978
979 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
980 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
981 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
982 = round_toward_zero;
983 };
984
985 /// numeric_limits<unsigned short> specialization.
986 template<>
987 struct numeric_limits<unsigned short>
988 {
989 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
990
991 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
992 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
993
994 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
995 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __SHRT_MAX__32767 * 2U + 1; }
996
997#if __cplusplus201703L >= 201103L
998 static constexpr unsigned short
999 lowest() noexcept { return min(); }
1000#endif
1001
1002 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits
1003 = __glibcxx_digits (unsigned short);
1004 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
1005 = __glibcxx_digits10 (unsigned short);
1006#if __cplusplus201703L >= 201103L
1007 static constexpr int max_digits10 = 0;
1008#endif
1009 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false;
1010 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
1011 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
1012 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
1013
1014 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
1015 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1016
1017 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
1018 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1019
1020 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
1021 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
1022 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
1023 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
1024
1025 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
1026 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
1027 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
1028 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1029 = denorm_absent;
1030 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
1031
1032 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
1033 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept
1034 { return static_cast<unsigned short>(0); }
1035
1036 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
1037 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1038 { return static_cast<unsigned short>(0); }
1039
1040 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
1041 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1042 { return static_cast<unsigned short>(0); }
1043
1044 static _GLIBCXX_CONSTEXPRconstexpr unsigned short
1045 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept
1046 { return static_cast<unsigned short>(0); }
1047
1048 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
1049 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1050 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = true;
1051
1052 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
1053 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
1054 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1055 = round_toward_zero;
1056 };
1057
1058 /// numeric_limits<int> specialization.
1059 template<>
1060 struct numeric_limits<int>
1061 {
1062 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1063
1064 static _GLIBCXX_CONSTEXPRconstexpr int
1065 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return -__INT_MAX__2147483647 - 1; }
1066
1067 static _GLIBCXX_CONSTEXPRconstexpr int
1068 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __INT_MAX__2147483647; }
1069
1070#if __cplusplus201703L >= 201103L
1071 static constexpr int
1072 lowest() noexcept { return min(); }
1073#endif
1074
1075 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __glibcxx_digits (int);
1076 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __glibcxx_digits10 (int);
1077#if __cplusplus201703L >= 201103L
1078 static constexpr int max_digits10 = 0;
1079#endif
1080 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
1081 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
1082 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
1083 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
1084
1085 static _GLIBCXX_CONSTEXPRconstexpr int
1086 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1087
1088 static _GLIBCXX_CONSTEXPRconstexpr int
1089 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1090
1091 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
1092 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
1093 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
1094 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
1095
1096 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
1097 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
1098 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
1099 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1100 = denorm_absent;
1101 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
1102
1103 static _GLIBCXX_CONSTEXPRconstexpr int
1104 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<int>(0); }
1105
1106 static _GLIBCXX_CONSTEXPRconstexpr int
1107 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<int>(0); }
1108
1109 static _GLIBCXX_CONSTEXPRconstexpr int
1110 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<int>(0); }
1111
1112 static _GLIBCXX_CONSTEXPRconstexpr int
1113 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<int>(0); }
1114
1115 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
1116 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1117 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
1118
1119 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
1120 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
1121 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1122 = round_toward_zero;
1123 };
1124
1125 /// numeric_limits<unsigned int> specialization.
1126 template<>
1127 struct numeric_limits<unsigned int>
1128 {
1129 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1130
1131 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1132 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1133
1134 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1135 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __INT_MAX__2147483647 * 2U + 1; }
1136
1137#if __cplusplus201703L >= 201103L
1138 static constexpr unsigned int
1139 lowest() noexcept { return min(); }
1140#endif
1141
1142 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits
1143 = __glibcxx_digits (unsigned int);
1144 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
1145 = __glibcxx_digits10 (unsigned int);
1146#if __cplusplus201703L >= 201103L
1147 static constexpr int max_digits10 = 0;
1148#endif
1149 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false;
1150 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
1151 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
1152 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
1153
1154 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1155 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1156
1157 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1158 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1159
1160 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
1161 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
1162 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
1163 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
1164
1165 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
1166 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
1167 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
1168 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1169 = denorm_absent;
1170 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
1171
1172 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1173 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<unsigned int>(0); }
1174
1175 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1176 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1177 { return static_cast<unsigned int>(0); }
1178
1179 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1180 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1181 { return static_cast<unsigned int>(0); }
1182
1183 static _GLIBCXX_CONSTEXPRconstexpr unsigned int
1184 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept
1185 { return static_cast<unsigned int>(0); }
1186
1187 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
1188 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1189 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = true;
1190
1191 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
1192 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
1193 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1194 = round_toward_zero;
1195 };
1196
1197 /// numeric_limits<long> specialization.
1198 template<>
1199 struct numeric_limits<long>
1200 {
1201 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1202
1203 static _GLIBCXX_CONSTEXPRconstexpr long
1204 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return -__LONG_MAX__9223372036854775807L - 1; }
1205
1206 static _GLIBCXX_CONSTEXPRconstexpr long
1207 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LONG_MAX__9223372036854775807L; }
1208
1209#if __cplusplus201703L >= 201103L
1210 static constexpr long
1211 lowest() noexcept { return min(); }
1212#endif
1213
1214 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __glibcxx_digits (long);
1215 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __glibcxx_digits10 (long);
1216#if __cplusplus201703L >= 201103L
1217 static constexpr int max_digits10 = 0;
1218#endif
1219 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
1220 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
1221 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
1222 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
1223
1224 static _GLIBCXX_CONSTEXPRconstexpr long
1225 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1226
1227 static _GLIBCXX_CONSTEXPRconstexpr long
1228 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1229
1230 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
1231 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
1232 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
1233 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
1234
1235 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
1236 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
1237 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
1238 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1239 = denorm_absent;
1240 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
1241
1242 static _GLIBCXX_CONSTEXPRconstexpr long
1243 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<long>(0); }
1244
1245 static _GLIBCXX_CONSTEXPRconstexpr long
1246 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<long>(0); }
1247
1248 static _GLIBCXX_CONSTEXPRconstexpr long
1249 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<long>(0); }
1250
1251 static _GLIBCXX_CONSTEXPRconstexpr long
1252 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<long>(0); }
1253
1254 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
1255 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1256 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
1257
1258 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
1259 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
1260 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1261 = round_toward_zero;
1262 };
1263
1264 /// numeric_limits<unsigned long> specialization.
1265 template<>
1266 struct numeric_limits<unsigned long>
1267 {
1268 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1269
1270 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1271 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1272
1273 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1274 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LONG_MAX__9223372036854775807L * 2UL + 1; }
5
Returning the value 18446744073709551615
1275
1276#if __cplusplus201703L >= 201103L
1277 static constexpr unsigned long
1278 lowest() noexcept { return min(); }
1279#endif
1280
1281 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits
1282 = __glibcxx_digits (unsigned long);
1283 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
1284 = __glibcxx_digits10 (unsigned long);
1285#if __cplusplus201703L >= 201103L
1286 static constexpr int max_digits10 = 0;
1287#endif
1288 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false;
1289 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
1290 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
1291 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
1292
1293 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1294 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1295
1296 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1297 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1298
1299 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
1300 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
1301 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
1302 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
1303
1304 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
1305 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
1306 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
1307 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1308 = denorm_absent;
1309 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
1310
1311 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1312 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept
1313 { return static_cast<unsigned long>(0); }
1314
1315 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1316 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1317 { return static_cast<unsigned long>(0); }
1318
1319 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1320 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1321 { return static_cast<unsigned long>(0); }
1322
1323 static _GLIBCXX_CONSTEXPRconstexpr unsigned long
1324 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept
1325 { return static_cast<unsigned long>(0); }
1326
1327 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
1328 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1329 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = true;
1330
1331 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
1332 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
1333 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1334 = round_toward_zero;
1335 };
1336
1337 /// numeric_limits<long long> specialization.
1338 template<>
1339 struct numeric_limits<long long>
1340 {
1341 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1342
1343 static _GLIBCXX_CONSTEXPRconstexpr long long
1344 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return -__LONG_LONG_MAX__9223372036854775807LL - 1; }
1345
1346 static _GLIBCXX_CONSTEXPRconstexpr long long
1347 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LONG_LONG_MAX__9223372036854775807LL; }
1348
1349#if __cplusplus201703L >= 201103L
1350 static constexpr long long
1351 lowest() noexcept { return min(); }
1352#endif
1353
1354 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits
1355 = __glibcxx_digits (long long);
1356 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
1357 = __glibcxx_digits10 (long long);
1358#if __cplusplus201703L >= 201103L
1359 static constexpr int max_digits10 = 0;
1360#endif
1361 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
1362 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
1363 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
1364 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
1365
1366 static _GLIBCXX_CONSTEXPRconstexpr long long
1367 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1368
1369 static _GLIBCXX_CONSTEXPRconstexpr long long
1370 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1371
1372 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
1373 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
1374 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
1375 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
1376
1377 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
1378 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
1379 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
1380 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1381 = denorm_absent;
1382 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
1383
1384 static _GLIBCXX_CONSTEXPRconstexpr long long
1385 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<long long>(0); }
1386
1387 static _GLIBCXX_CONSTEXPRconstexpr long long
1388 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<long long>(0); }
1389
1390 static _GLIBCXX_CONSTEXPRconstexpr long long
1391 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1392 { return static_cast<long long>(0); }
1393
1394 static _GLIBCXX_CONSTEXPRconstexpr long long
1395 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return static_cast<long long>(0); }
1396
1397 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
1398 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1399 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
1400
1401 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
1402 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
1403 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1404 = round_toward_zero;
1405 };
1406
1407 /// numeric_limits<unsigned long long> specialization.
1408 template<>
1409 struct numeric_limits<unsigned long long>
1410 {
1411 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1412
1413 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1414 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1415
1416 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1417 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LONG_LONG_MAX__9223372036854775807LL * 2ULL + 1; }
1418
1419#if __cplusplus201703L >= 201103L
1420 static constexpr unsigned long long
1421 lowest() noexcept { return min(); }
1422#endif
1423
1424 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits
1425 = __glibcxx_digits (unsigned long long);
1426 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10
1427 = __glibcxx_digits10 (unsigned long long);
1428#if __cplusplus201703L >= 201103L
1429 static constexpr int max_digits10 = 0;
1430#endif
1431 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false;
1432 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true;
1433 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true;
1434 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2;
1435
1436 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1437 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1438
1439 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1440 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; }
1441
1442 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0;
1443 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0;
1444 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0;
1445 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0;
1446
1447 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false;
1448 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false;
1449 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false;
1450 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1451 = denorm_absent;
1452 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false;
1453
1454 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1455 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept
1456 { return static_cast<unsigned long long>(0); }
1457
1458 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1459 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1460 { return static_cast<unsigned long long>(0); }
1461
1462 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1463 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept
1464 { return static_cast<unsigned long long>(0); }
1465
1466 static _GLIBCXX_CONSTEXPRconstexpr unsigned long long
1467 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept
1468 { return static_cast<unsigned long long>(0); }
1469
1470 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false;
1471 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1472 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = true;
1473
1474 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue;
1475 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false;
1476 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1477 = round_toward_zero;
1478 };
1479
1480#define __INT_N(TYPE, BITSIZE, EXT, UEXT) \
1481 template<> \
1482 struct numeric_limits<TYPE> \
1483 { \
1484 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true; \
1485 \
1486 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1487 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_min_b (TYPE, BITSIZE)(((TYPE)(-1) < 0) ? -(((TYPE)(-1) < 0) ? (((((TYPE)1 <<
((BITSIZE - ((TYPE)(-1) < 0)) - 1)) - 1) << 1) + 1)
: ~(TYPE)0) - 1 : (TYPE)0)
; } \
1488 \
1489 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1490 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __glibcxx_max_b (TYPE, BITSIZE)(((TYPE)(-1) < 0) ? (((((TYPE)1 << ((BITSIZE - ((TYPE
)(-1) < 0)) - 1)) - 1) << 1) + 1) : ~(TYPE)0)
; } \
1491 \
1492 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits \
1493 = BITSIZE - 1; \
1494 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 \
1495 = (BITSIZE - 1) * 643L / 2136; \
1496 \
1497 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true; \
1498 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true; \
1499 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true; \
1500 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2; \
1501 \
1502 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1503 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; } \
1504 \
1505 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1506 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; } \
1507 \
1508 EXT \
1509 \
1510 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0; \
1511 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0; \
1512 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0; \
1513 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0; \
1514 \
1515 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false; \
1516 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false; \
1517 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false; \
1518 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm \
1519 = denorm_absent; \
1520 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false; \
1521 \
1522 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1523 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept \
1524 { return static_cast<TYPE>(0); } \
1525 \
1526 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1527 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept \
1528 { return static_cast<TYPE>(0); } \
1529 \
1530 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1531 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept \
1532 { return static_cast<TYPE>(0); } \
1533 \
1534 static _GLIBCXX_CONSTEXPRconstexpr TYPE \
1535 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept \
1536 { return static_cast<TYPE>(0); } \
1537 \
1538 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false; \
1539 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true; \
1540 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false; \
1541 \
1542 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps \
1543 = __glibcxx_integral_trapstrue; \
1544 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false; \
1545 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style \
1546 = round_toward_zero; \
1547 }; \
1548 \
1549 template<> \
1550 struct numeric_limits<unsigned TYPE> \
1551 { \
1552 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true; \
1553 \
1554 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1555 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; } \
1556 \
1557 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1558 max() _GLIBCXX_USE_NOEXCEPTnoexcept \
1559 { return __glibcxx_max_b (unsigned TYPE, BITSIZE)(((unsigned TYPE)(-1) < 0) ? (((((unsigned TYPE)1 <<
((BITSIZE - ((unsigned TYPE)(-1) < 0)) - 1)) - 1) <<
1) + 1) : ~(unsigned TYPE)0)
; } \
1560 \
1561 UEXT \
1562 \
1563 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits \
1564 = BITSIZE; \
1565 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 \
1566 = BITSIZE * 643L / 2136; \
1567 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = false; \
1568 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = true; \
1569 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = true; \
1570 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = 2; \
1571 \
1572 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1573 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; } \
1574 \
1575 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1576 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0; } \
1577 \
1578 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = 0; \
1579 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = 0; \
1580 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = 0; \
1581 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = 0; \
1582 \
1583 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = false; \
1584 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = false; \
1585 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = false; \
1586 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm \
1587 = denorm_absent; \
1588 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss = false; \
1589 \
1590 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1591 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept \
1592 { return static_cast<unsigned TYPE>(0); } \
1593 \
1594 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1595 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept \
1596 { return static_cast<unsigned TYPE>(0); } \
1597 \
1598 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1599 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept \
1600 { return static_cast<unsigned TYPE>(0); } \
1601 \
1602 static _GLIBCXX_CONSTEXPRconstexpr unsigned TYPE \
1603 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept \
1604 { return static_cast<unsigned TYPE>(0); } \
1605 \
1606 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559 = false; \
1607 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true; \
1608 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = true; \
1609 \
1610 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_integral_trapstrue; \
1611 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before = false; \
1612 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style \
1613 = round_toward_zero; \
1614 };
1615
1616#if __cplusplus201703L >= 201103L
1617
1618#define __INT_N_201103(TYPE) \
1619 static constexpr TYPE \
1620 lowest() noexcept { return min(); } \
1621 static constexpr int max_digits10 = 0;
1622
1623#define __INT_N_U201103(TYPE) \
1624 static constexpr unsigned TYPE \
1625 lowest() noexcept { return min(); } \
1626 static constexpr int max_digits10 = 0;
1627
1628#else
1629#define __INT_N_201103(TYPE)
1630#define __INT_N_U201103(TYPE)
1631#endif
1632
1633#if !defined(__STRICT_ANSI__1)
1634#ifdef __GLIBCXX_TYPE_INT_N_0
1635 __INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0,
1636 __INT_N_201103 (__GLIBCXX_TYPE_INT_N_0), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_0))
1637#endif
1638#ifdef __GLIBCXX_TYPE_INT_N_1
1639 __INT_N (__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1,
1640 __INT_N_201103 (__GLIBCXX_TYPE_INT_N_1), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_1))
1641#endif
1642#ifdef __GLIBCXX_TYPE_INT_N_2
1643 __INT_N (__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2,
1644 __INT_N_201103 (__GLIBCXX_TYPE_INT_N_2), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_2))
1645#endif
1646#ifdef __GLIBCXX_TYPE_INT_N_3
1647 __INT_N (__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3,
1648 __INT_N_201103 (__GLIBCXX_TYPE_INT_N_3), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3))
1649#endif
1650
1651#elif defined __STRICT_ANSI__1 && defined __SIZEOF_INT128__16
1652 __INT_N(__int128, 128,
1653 __INT_N_201103 (__int128),
1654 __INT_N_U201103 (__int128))
1655#endif
1656
1657#undef __INT_N
1658#undef __INT_N_201103
1659#undef __INT_N_U201103
1660
1661
1662 /// numeric_limits<float> specialization.
1663 template<>
1664 struct numeric_limits<float>
1665 {
1666 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1667
1668 static _GLIBCXX_CONSTEXPRconstexpr float
1669 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __FLT_MIN__1.17549435e-38F; }
1670
1671 static _GLIBCXX_CONSTEXPRconstexpr float
1672 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __FLT_MAX__3.40282347e+38F; }
1673
1674#if __cplusplus201703L >= 201103L
1675 static constexpr float
1676 lowest() noexcept { return -__FLT_MAX__3.40282347e+38F; }
1677#endif
1678
1679 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __FLT_MANT_DIG__24;
1680 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __FLT_DIG__6;
1681#if __cplusplus201703L >= 201103L
1682 static constexpr int max_digits10
1683 = __glibcxx_max_digits10 (__FLT_MANT_DIG__24);
1684#endif
1685 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
1686 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = false;
1687 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = false;
1688 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = __FLT_RADIX__2;
1689
1690 static _GLIBCXX_CONSTEXPRconstexpr float
1691 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return __FLT_EPSILON__1.19209290e-7F; }
1692
1693 static _GLIBCXX_CONSTEXPRconstexpr float
1694 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0.5F; }
1695
1696 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = __FLT_MIN_EXP__(-125);
1697 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = __FLT_MIN_10_EXP__(-37);
1698 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = __FLT_MAX_EXP__128;
1699 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = __FLT_MAX_10_EXP__38;
1700
1701 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = __FLT_HAS_INFINITY__1;
1702 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__1;
1703 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = has_quiet_NaN;
1704 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1705 = bool(__FLT_HAS_DENORM__1) ? denorm_present : denorm_absent;
1706 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss
1707 = __glibcxx_float_has_denorm_loss;
1708
1709 static _GLIBCXX_CONSTEXPRconstexpr float
1710 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_huge_valf(); }
1711
1712 static _GLIBCXX_CONSTEXPRconstexpr float
1713 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_nanf(""); }
1714
1715 static _GLIBCXX_CONSTEXPRconstexpr float
1716 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_nansf(""); }
1717
1718 static _GLIBCXX_CONSTEXPRconstexpr float
1719 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __FLT_DENORM_MIN__1.40129846e-45F; }
1720
1721 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559
1722 = has_infinity && has_quiet_NaN && has_denorm == denorm_present;
1723 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1724 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
1725
1726 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_float_traps;
1727 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before
1728 = __glibcxx_float_tinyness_before;
1729 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1730 = round_to_nearest;
1731 };
1732
1733#undef __glibcxx_float_has_denorm_loss
1734#undef __glibcxx_float_traps
1735#undef __glibcxx_float_tinyness_before
1736
1737 /// numeric_limits<double> specialization.
1738 template<>
1739 struct numeric_limits<double>
1740 {
1741 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1742
1743 static _GLIBCXX_CONSTEXPRconstexpr double
1744 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __DBL_MIN__2.2250738585072014e-308; }
1745
1746 static _GLIBCXX_CONSTEXPRconstexpr double
1747 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __DBL_MAX__1.7976931348623157e+308; }
1748
1749#if __cplusplus201703L >= 201103L
1750 static constexpr double
1751 lowest() noexcept { return -__DBL_MAX__1.7976931348623157e+308; }
1752#endif
1753
1754 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __DBL_MANT_DIG__53;
1755 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __DBL_DIG__15;
1756#if __cplusplus201703L >= 201103L
1757 static constexpr int max_digits10
1758 = __glibcxx_max_digits10 (__DBL_MANT_DIG__53);
1759#endif
1760 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
1761 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = false;
1762 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = false;
1763 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = __FLT_RADIX__2;
1764
1765 static _GLIBCXX_CONSTEXPRconstexpr double
1766 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return __DBL_EPSILON__2.2204460492503131e-16; }
1767
1768 static _GLIBCXX_CONSTEXPRconstexpr double
1769 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0.5; }
1770
1771 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = __DBL_MIN_EXP__(-1021);
1772 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = __DBL_MIN_10_EXP__(-307);
1773 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = __DBL_MAX_EXP__1024;
1774 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = __DBL_MAX_10_EXP__308;
1775
1776 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = __DBL_HAS_INFINITY__1;
1777 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__1;
1778 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = has_quiet_NaN;
1779 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1780 = bool(__DBL_HAS_DENORM__1) ? denorm_present : denorm_absent;
1781 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss
1782 = __glibcxx_double_has_denorm_loss;
1783
1784 static _GLIBCXX_CONSTEXPRconstexpr double
1785 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_huge_val(); }
1786
1787 static _GLIBCXX_CONSTEXPRconstexpr double
1788 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_nan(""); }
1789
1790 static _GLIBCXX_CONSTEXPRconstexpr double
1791 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_nans(""); }
1792
1793 static _GLIBCXX_CONSTEXPRconstexpr double
1794 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __DBL_DENORM_MIN__4.9406564584124654e-324; }
1795
1796 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559
1797 = has_infinity && has_quiet_NaN && has_denorm == denorm_present;
1798 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1799 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
1800
1801 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_double_traps;
1802 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before
1803 = __glibcxx_double_tinyness_before;
1804 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style
1805 = round_to_nearest;
1806 };
1807
1808#undef __glibcxx_double_has_denorm_loss
1809#undef __glibcxx_double_traps
1810#undef __glibcxx_double_tinyness_before
1811
1812 /// numeric_limits<long double> specialization.
1813 template<>
1814 struct numeric_limits<long double>
1815 {
1816 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_specialized = true;
1817
1818 static _GLIBCXX_CONSTEXPRconstexpr long double
1819 min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LDBL_MIN__3.36210314311209350626e-4932L; }
1820
1821 static _GLIBCXX_CONSTEXPRconstexpr long double
1822 max() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LDBL_MAX__1.18973149535723176502e+4932L; }
1823
1824#if __cplusplus201703L >= 201103L
1825 static constexpr long double
1826 lowest() noexcept { return -__LDBL_MAX__1.18973149535723176502e+4932L; }
1827#endif
1828
1829 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits = __LDBL_MANT_DIG__64;
1830 static _GLIBCXX_USE_CONSTEXPRconstexpr int digits10 = __LDBL_DIG__18;
1831#if __cplusplus201703L >= 201103L
1832 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_digits10
1833 = __glibcxx_max_digits10 (__LDBL_MANT_DIG__64);
1834#endif
1835 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_signed = true;
1836 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_integer = false;
1837 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_exact = false;
1838 static _GLIBCXX_USE_CONSTEXPRconstexpr int radix = __FLT_RADIX__2;
1839
1840 static _GLIBCXX_CONSTEXPRconstexpr long double
1841 epsilon() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LDBL_EPSILON__1.08420217248550443401e-19L; }
1842
1843 static _GLIBCXX_CONSTEXPRconstexpr long double
1844 round_error() _GLIBCXX_USE_NOEXCEPTnoexcept { return 0.5L; }
1845
1846 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent = __LDBL_MIN_EXP__(-16381);
1847 static _GLIBCXX_USE_CONSTEXPRconstexpr int min_exponent10 = __LDBL_MIN_10_EXP__(-4931);
1848 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent = __LDBL_MAX_EXP__16384;
1849 static _GLIBCXX_USE_CONSTEXPRconstexpr int max_exponent10 = __LDBL_MAX_10_EXP__4932;
1850
1851 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_infinity = __LDBL_HAS_INFINITY__1;
1852 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__1;
1853 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_signaling_NaN = has_quiet_NaN;
1854 static _GLIBCXX_USE_CONSTEXPRconstexpr float_denorm_style has_denorm
1855 = bool(__LDBL_HAS_DENORM__1) ? denorm_present : denorm_absent;
1856 static _GLIBCXX_USE_CONSTEXPRconstexpr bool has_denorm_loss
1857 = __glibcxx_long_double_has_denorm_loss;
1858
1859 static _GLIBCXX_CONSTEXPRconstexpr long double
1860 infinity() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_huge_vall(); }
1861
1862 static _GLIBCXX_CONSTEXPRconstexpr long double
1863 quiet_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_nanl(""); }
1864
1865 static _GLIBCXX_CONSTEXPRconstexpr long double
1866 signaling_NaN() _GLIBCXX_USE_NOEXCEPTnoexcept { return __builtin_nansl(""); }
1867
1868 static _GLIBCXX_CONSTEXPRconstexpr long double
1869 denorm_min() _GLIBCXX_USE_NOEXCEPTnoexcept { return __LDBL_DENORM_MIN__3.64519953188247460253e-4951L; }
1870
1871 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_iec559
1872 = has_infinity && has_quiet_NaN && has_denorm == denorm_present;
1873 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_bounded = true;
1874 static _GLIBCXX_USE_CONSTEXPRconstexpr bool is_modulo = false;
1875
1876 static _GLIBCXX_USE_CONSTEXPRconstexpr bool traps = __glibcxx_long_double_traps;
1877 static _GLIBCXX_USE_CONSTEXPRconstexpr bool tinyness_before =
1878 __glibcxx_long_double_tinyness_before;
1879 static _GLIBCXX_USE_CONSTEXPRconstexpr float_round_style round_style =
1880 round_to_nearest;
1881 };
1882
1883#undef __glibcxx_long_double_has_denorm_loss
1884#undef __glibcxx_long_double_traps
1885#undef __glibcxx_long_double_tinyness_before
1886
1887_GLIBCXX_END_NAMESPACE_VERSION
1888} // namespace
1889
1890#undef __glibcxx_signed
1891#undef __glibcxx_min
1892#undef __glibcxx_max
1893#undef __glibcxx_digits
1894#undef __glibcxx_digits10
1895#undef __glibcxx_max_digits10
1896
1897#endif // _GLIBCXX_NUMERIC_LIMITS