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