1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
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
7 //===----------------------------------------------------------------------===//
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/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/BinaryFormat/ELF.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrDesc.h"
26 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCParser/MCAsmLexer.h"
29 #include "llvm/MC/MCParser/MCAsmParser.h"
30 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
31 #include "llvm/MC/MCParser/MCAsmParserUtils.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/TargetRegistry.h"
41 #include "llvm/Support/Alignment.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Compiler.h"
45 #include "llvm/Support/Debug.h"
46 #include "llvm/Support/ErrorHandling.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/SMLoc.h"
49 #include "llvm/Support/SourceMgr.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include "llvm/TargetParser/SubtargetFeature.h"
52 #include "llvm/TargetParser/Triple.h"
62 #define DEBUG_TYPE "mips-asm-parser"
68 } // end namespace llvm
70 extern cl::opt
<bool> EmitJalrReloc
;
74 class MipsAssemblerOptions
{
76 MipsAssemblerOptions(const FeatureBitset
&Features_
) : Features(Features_
) {}
78 MipsAssemblerOptions(const MipsAssemblerOptions
*Opts
) {
79 ATReg
= Opts
->getATRegIndex();
80 Reorder
= Opts
->isReorder();
81 Macro
= Opts
->isMacro();
82 Features
= Opts
->getFeatures();
85 unsigned getATRegIndex() const { return ATReg
; }
86 bool setATRegIndex(unsigned Reg
) {
94 bool isReorder() const { return Reorder
; }
95 void setReorder() { Reorder
= true; }
96 void setNoReorder() { Reorder
= false; }
98 bool isMacro() const { return Macro
; }
99 void setMacro() { Macro
= true; }
100 void setNoMacro() { Macro
= false; }
102 const FeatureBitset
&getFeatures() const { return Features
; }
103 void setFeatures(const FeatureBitset
&Features_
) { Features
= Features_
; }
105 // Set of features that are either architecture features or referenced
106 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
107 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
108 // The reason we need this mask is explained in the selectArch function.
109 // FIXME: Ideally we would like TableGen to generate this information.
110 static const FeatureBitset AllArchRelatedMask
;
116 FeatureBitset Features
;
119 } // end anonymous namespace
121 const FeatureBitset
MipsAssemblerOptions::AllArchRelatedMask
= {
122 Mips::FeatureMips1
, Mips::FeatureMips2
, Mips::FeatureMips3
,
123 Mips::FeatureMips3_32
, Mips::FeatureMips3_32r2
, Mips::FeatureMips4
,
124 Mips::FeatureMips4_32
, Mips::FeatureMips4_32r2
, Mips::FeatureMips5
,
125 Mips::FeatureMips5_32r2
, Mips::FeatureMips32
, Mips::FeatureMips32r2
,
126 Mips::FeatureMips32r3
, Mips::FeatureMips32r5
, Mips::FeatureMips32r6
,
127 Mips::FeatureMips64
, Mips::FeatureMips64r2
, Mips::FeatureMips64r3
,
128 Mips::FeatureMips64r5
, Mips::FeatureMips64r6
, Mips::FeatureCnMips
,
129 Mips::FeatureCnMipsP
, Mips::FeatureFP64Bit
, Mips::FeatureGP64Bit
,
135 class MipsAsmParser
: public MCTargetAsmParser
{
136 MipsTargetStreamer
&getTargetStreamer() {
137 assert(getParser().getStreamer().getTargetStreamer() &&
138 "do not have a target streamer");
139 MCTargetStreamer
&TS
= *getParser().getStreamer().getTargetStreamer();
140 return static_cast<MipsTargetStreamer
&>(TS
);
144 SmallVector
<std::unique_ptr
<MipsAssemblerOptions
>, 2> AssemblerOptions
;
145 MCSymbol
*CurrentFn
; // Pointer to the function being parsed. It may be a
146 // nullptr, which indicates that no function is currently
147 // selected. This usually happens after an '.end func'
152 bool CurForbiddenSlotAttr
;
155 unsigned CpSaveLocation
;
156 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
157 bool CpSaveLocationIsRegister
;
159 // Map of register aliases created via the .set directive.
160 StringMap
<AsmToken
> RegisterSets
;
162 // Print a warning along with its fix-it message at the given range.
163 void printWarningWithFixIt(const Twine
&Msg
, const Twine
&FixMsg
,
164 SMRange Range
, bool ShowColors
= true);
166 void ConvertXWPOperands(MCInst
&Inst
, const OperandVector
&Operands
);
168 #define GET_ASSEMBLER_HEADER
169 #include "MipsGenAsmMatcher.inc"
172 checkEarlyTargetMatchPredicate(MCInst
&Inst
,
173 const OperandVector
&Operands
) override
;
174 unsigned checkTargetMatchPredicate(MCInst
&Inst
) override
;
176 bool matchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
177 OperandVector
&Operands
, MCStreamer
&Out
,
179 bool MatchingInlineAsm
) override
;
181 /// Parse a register as used in CFI directives
182 bool parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
183 ParseStatus
tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
184 SMLoc
&EndLoc
) override
;
186 bool parseParenSuffix(StringRef Name
, OperandVector
&Operands
);
188 bool parseBracketSuffix(StringRef Name
, OperandVector
&Operands
);
190 bool mnemonicIsValid(StringRef Mnemonic
, unsigned VariantID
);
192 bool parseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
193 SMLoc NameLoc
, OperandVector
&Operands
) override
;
195 bool ParseDirective(AsmToken DirectiveID
) override
;
197 ParseStatus
parseMemOperand(OperandVector
&Operands
);
198 ParseStatus
matchAnyRegisterNameWithoutDollar(OperandVector
&Operands
,
199 StringRef Identifier
, SMLoc S
);
200 ParseStatus
matchAnyRegisterWithoutDollar(OperandVector
&Operands
,
201 const AsmToken
&Token
, SMLoc S
);
202 ParseStatus
matchAnyRegisterWithoutDollar(OperandVector
&Operands
, SMLoc S
);
203 ParseStatus
parseAnyRegister(OperandVector
&Operands
);
204 ParseStatus
parseImm(OperandVector
&Operands
);
205 ParseStatus
parseJumpTarget(OperandVector
&Operands
);
206 ParseStatus
parseInvNum(OperandVector
&Operands
);
207 ParseStatus
parseRegisterList(OperandVector
&Operands
);
209 bool searchSymbolAlias(OperandVector
&Operands
);
211 bool parseOperand(OperandVector
&, StringRef Mnemonic
);
213 enum MacroExpanderResultTy
{
219 // Expands assembly pseudo instructions.
220 MacroExpanderResultTy
tryExpandInstruction(MCInst
&Inst
, SMLoc IDLoc
,
222 const MCSubtargetInfo
*STI
);
224 bool expandJalWithRegs(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
225 const MCSubtargetInfo
*STI
);
227 bool loadImmediate(int64_t ImmValue
, unsigned DstReg
, unsigned SrcReg
,
228 bool Is32BitImm
, bool IsAddress
, SMLoc IDLoc
,
229 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
231 bool loadAndAddSymbolAddress(const MCExpr
*SymExpr
, unsigned DstReg
,
232 unsigned SrcReg
, bool Is32BitSym
, SMLoc IDLoc
,
233 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
235 bool emitPartialAddress(MipsTargetStreamer
&TOut
, SMLoc IDLoc
, MCSymbol
*Sym
);
237 bool expandLoadImm(MCInst
&Inst
, bool Is32BitImm
, SMLoc IDLoc
,
238 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
240 bool expandLoadSingleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
241 const MCSubtargetInfo
*STI
);
242 bool expandLoadSingleImmToFPR(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
243 const MCSubtargetInfo
*STI
);
244 bool expandLoadDoubleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
245 const MCSubtargetInfo
*STI
);
246 bool expandLoadDoubleImmToFPR(MCInst
&Inst
, bool Is64FPU
, SMLoc IDLoc
,
247 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
249 bool expandLoadAddress(unsigned DstReg
, unsigned BaseReg
,
250 const MCOperand
&Offset
, bool Is32BitAddress
,
251 SMLoc IDLoc
, MCStreamer
&Out
,
252 const MCSubtargetInfo
*STI
);
254 bool expandUncondBranchMMPseudo(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
255 const MCSubtargetInfo
*STI
);
257 void expandMem16Inst(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
258 const MCSubtargetInfo
*STI
, bool IsLoad
);
259 void expandMem9Inst(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
260 const MCSubtargetInfo
*STI
, bool IsLoad
);
262 bool expandLoadStoreMultiple(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
263 const MCSubtargetInfo
*STI
);
265 bool expandAliasImmediate(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
266 const MCSubtargetInfo
*STI
);
268 bool expandBranchImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
269 const MCSubtargetInfo
*STI
);
271 bool expandCondBranches(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
272 const MCSubtargetInfo
*STI
);
274 bool expandDivRem(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
275 const MCSubtargetInfo
*STI
, const bool IsMips64
,
278 bool expandTrunc(MCInst
&Inst
, bool IsDouble
, bool Is64FPU
, SMLoc IDLoc
,
279 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
281 bool expandUlh(MCInst
&Inst
, bool Signed
, SMLoc IDLoc
, MCStreamer
&Out
,
282 const MCSubtargetInfo
*STI
);
284 bool expandUsh(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
285 const MCSubtargetInfo
*STI
);
287 bool expandUxw(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
288 const MCSubtargetInfo
*STI
);
290 bool expandSge(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
291 const MCSubtargetInfo
*STI
);
293 bool expandSgeImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
294 const MCSubtargetInfo
*STI
);
296 bool expandSgtImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
297 const MCSubtargetInfo
*STI
);
299 bool expandSle(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
300 const MCSubtargetInfo
*STI
);
302 bool expandSleImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
303 const MCSubtargetInfo
*STI
);
305 bool expandRotation(MCInst
&Inst
, SMLoc IDLoc
,
306 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
307 bool expandRotationImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
308 const MCSubtargetInfo
*STI
);
309 bool expandDRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
310 const MCSubtargetInfo
*STI
);
311 bool expandDRotationImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
312 const MCSubtargetInfo
*STI
);
314 bool expandAbs(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
315 const MCSubtargetInfo
*STI
);
317 bool expandMulImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
318 const MCSubtargetInfo
*STI
);
320 bool expandMulO(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
321 const MCSubtargetInfo
*STI
);
323 bool expandMulOU(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
324 const MCSubtargetInfo
*STI
);
326 bool expandDMULMacro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
327 const MCSubtargetInfo
*STI
);
329 bool expandLoadStoreDMacro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
330 const MCSubtargetInfo
*STI
, bool IsLoad
);
332 bool expandStoreDM1Macro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
333 const MCSubtargetInfo
*STI
);
335 bool expandSeq(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
336 const MCSubtargetInfo
*STI
);
338 bool expandSeqI(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
339 const MCSubtargetInfo
*STI
);
341 bool expandSne(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
342 const MCSubtargetInfo
*STI
);
344 bool expandSneI(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
345 const MCSubtargetInfo
*STI
);
347 bool expandMXTRAlias(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
348 const MCSubtargetInfo
*STI
);
350 bool expandSaaAddr(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
351 const MCSubtargetInfo
*STI
);
353 bool reportParseError(const Twine
&ErrorMsg
);
354 bool reportParseError(SMLoc Loc
, const Twine
&ErrorMsg
);
356 bool parseMemOffset(const MCExpr
*&Res
, bool isParenExpr
);
358 bool parseSetMips0Directive();
359 bool parseSetArchDirective();
360 bool parseSetFeature(uint64_t Feature
);
361 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
362 bool parseDirectiveCpAdd(SMLoc Loc
);
363 bool parseDirectiveCpLoad(SMLoc Loc
);
364 bool parseDirectiveCpLocal(SMLoc Loc
);
365 bool parseDirectiveCpRestore(SMLoc Loc
);
366 bool parseDirectiveCPSetup();
367 bool parseDirectiveCPReturn();
368 bool parseDirectiveNaN();
369 bool parseDirectiveSet();
370 bool parseDirectiveOption();
371 bool parseInsnDirective();
372 bool parseRSectionDirective(StringRef Section
);
373 bool parseSSectionDirective(StringRef Section
, unsigned Type
);
375 bool parseSetAtDirective();
376 bool parseSetNoAtDirective();
377 bool parseSetMacroDirective();
378 bool parseSetNoMacroDirective();
379 bool parseSetMsaDirective();
380 bool parseSetNoMsaDirective();
381 bool parseSetNoDspDirective();
382 bool parseSetNoMips3DDirective();
383 bool parseSetReorderDirective();
384 bool parseSetNoReorderDirective();
385 bool parseSetMips16Directive();
386 bool parseSetNoMips16Directive();
387 bool parseSetFpDirective();
388 bool parseSetOddSPRegDirective();
389 bool parseSetNoOddSPRegDirective();
390 bool parseSetPopDirective();
391 bool parseSetPushDirective();
392 bool parseSetSoftFloatDirective();
393 bool parseSetHardFloatDirective();
394 bool parseSetMtDirective();
395 bool parseSetNoMtDirective();
396 bool parseSetNoCRCDirective();
397 bool parseSetNoVirtDirective();
398 bool parseSetNoGINVDirective();
400 bool parseSetAssignment();
402 bool parseDirectiveGpWord();
403 bool parseDirectiveGpDWord();
404 bool parseDirectiveDtpRelWord();
405 bool parseDirectiveDtpRelDWord();
406 bool parseDirectiveTpRelWord();
407 bool parseDirectiveTpRelDWord();
408 bool parseDirectiveModule();
409 bool parseDirectiveModuleFP();
410 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind
&FpABI
,
411 StringRef Directive
);
413 bool parseInternalDirectiveReallowModule();
415 bool eatComma(StringRef ErrorStr
);
417 int matchCPURegisterName(StringRef Symbol
);
419 int matchHWRegsRegisterName(StringRef Symbol
);
421 int matchFPURegisterName(StringRef Name
);
423 int matchFCCRegisterName(StringRef Name
);
425 int matchACRegisterName(StringRef Name
);
427 int matchMSA128RegisterName(StringRef Name
);
429 int matchMSA128CtrlRegisterName(StringRef Name
);
431 unsigned getReg(int RC
, int RegNo
);
433 /// Returns the internal register number for the current AT. Also checks if
434 /// the current AT is unavailable (set to $0) and gives an error if it is.
435 /// This should be used in pseudo-instruction expansions which need AT.
436 unsigned getATReg(SMLoc Loc
);
440 bool processInstruction(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
441 const MCSubtargetInfo
*STI
);
443 // Helper function that checks if the value of a vector index is within the
444 // boundaries of accepted values for each RegisterKind
445 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
446 bool validateMSAIndex(int Val
, int RegKind
);
448 // Selects a new architecture by updating the FeatureBits with the necessary
449 // info including implied dependencies.
450 // Internally, it clears all the feature bits related to *any* architecture
451 // and selects the new one using the ToggleFeature functionality of the
452 // MCSubtargetInfo object that handles implied dependencies. The reason we
453 // clear all the arch related bits manually is because ToggleFeature only
454 // clears the features that imply the feature being cleared and not the
455 // features implied by the feature being cleared. This is easier to see
457 // --------------------------------------------------
458 // | Feature | Implies |
459 // | -------------------------------------------------|
460 // | FeatureMips1 | None |
461 // | FeatureMips2 | FeatureMips1 |
462 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
463 // | FeatureMips4 | FeatureMips3 |
465 // --------------------------------------------------
467 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
468 // FeatureMipsGP64 | FeatureMips1)
469 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
470 void selectArch(StringRef ArchFeature
) {
471 MCSubtargetInfo
&STI
= copySTI();
472 FeatureBitset FeatureBits
= STI
.getFeatureBits();
473 FeatureBits
&= ~MipsAssemblerOptions::AllArchRelatedMask
;
474 STI
.setFeatureBits(FeatureBits
);
475 setAvailableFeatures(
476 ComputeAvailableFeatures(STI
.ToggleFeature(ArchFeature
)));
477 AssemblerOptions
.back()->setFeatures(STI
.getFeatureBits());
480 void setFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
481 if (!(getSTI().hasFeature(Feature
))) {
482 MCSubtargetInfo
&STI
= copySTI();
483 setAvailableFeatures(
484 ComputeAvailableFeatures(STI
.ToggleFeature(FeatureString
)));
485 AssemblerOptions
.back()->setFeatures(STI
.getFeatureBits());
489 void clearFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
490 if (getSTI().hasFeature(Feature
)) {
491 MCSubtargetInfo
&STI
= copySTI();
492 setAvailableFeatures(
493 ComputeAvailableFeatures(STI
.ToggleFeature(FeatureString
)));
494 AssemblerOptions
.back()->setFeatures(STI
.getFeatureBits());
498 void setModuleFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
499 setFeatureBits(Feature
, FeatureString
);
500 AssemblerOptions
.front()->setFeatures(getSTI().getFeatureBits());
503 void clearModuleFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
504 clearFeatureBits(Feature
, FeatureString
);
505 AssemblerOptions
.front()->setFeatures(getSTI().getFeatureBits());
509 enum MipsMatchResultTy
{
510 Match_RequiresDifferentSrcAndDst
= FIRST_TARGET_MATCH_RESULT_TY
,
511 Match_RequiresDifferentOperands
,
512 Match_RequiresNoZeroRegister
,
513 Match_RequiresSameSrcAndDst
,
514 Match_NoFCCRegisterForCurrentISA
,
515 Match_NonZeroOperandForSync
,
516 Match_NonZeroOperandForMTCX
,
517 Match_RequiresPosSizeRange0_32
,
518 Match_RequiresPosSizeRange33_64
,
519 Match_RequiresPosSizeUImm6
,
520 #define GET_OPERAND_DIAGNOSTIC_TYPES
521 #include "MipsGenAsmMatcher.inc"
522 #undef GET_OPERAND_DIAGNOSTIC_TYPES
525 MipsAsmParser(const MCSubtargetInfo
&sti
, MCAsmParser
&parser
,
526 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
527 : MCTargetAsmParser(Options
, sti
, MII
),
528 ABI(MipsABIInfo::computeTargetABI(Triple(sti
.getTargetTriple()),
529 sti
.getCPU(), Options
)) {
530 MCAsmParserExtension::Initialize(parser
);
532 parser
.addAliasForDirective(".asciiz", ".asciz");
533 parser
.addAliasForDirective(".hword", ".2byte");
534 parser
.addAliasForDirective(".word", ".4byte");
535 parser
.addAliasForDirective(".dword", ".8byte");
537 // Initialize the set of available features.
538 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
540 // Remember the initial assembler options. The user can not modify these.
541 AssemblerOptions
.push_back(
542 std::make_unique
<MipsAssemblerOptions
>(getSTI().getFeatureBits()));
544 // Create an assembler options environment for the user to modify.
545 AssemblerOptions
.push_back(
546 std::make_unique
<MipsAssemblerOptions
>(getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
551 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
555 CurForbiddenSlotAttr
= false;
556 IsPicEnabled
= getContext().getObjectFileInfo()->isPositionIndependent();
558 IsCpRestoreSet
= false;
559 CpRestoreOffset
= -1;
560 GPReg
= ABI
.GetGlobalPtr();
562 const Triple
&TheTriple
= sti
.getTargetTriple();
563 IsLittleEndian
= TheTriple
.isLittleEndian();
565 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
566 report_fatal_error("microMIPS64R6 is not supported", false);
568 if (!isABI_O32() && inMicroMipsMode())
569 report_fatal_error("microMIPS64 is not supported", false);
572 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
573 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
575 bool isGP64bit() const {
576 return getSTI().hasFeature(Mips::FeatureGP64Bit
);
579 bool isFP64bit() const {
580 return getSTI().hasFeature(Mips::FeatureFP64Bit
);
583 bool isJalrRelocAvailable(const MCExpr
*JalExpr
) {
587 if (!JalExpr
->evaluateAsRelocatable(Res
, nullptr, nullptr))
589 if (Res
.getSymB() != nullptr)
591 if (Res
.getConstant() != 0)
592 return ABI
.IsN32() || ABI
.IsN64();
596 const MipsABIInfo
&getABI() const { return ABI
; }
597 bool isABI_N32() const { return ABI
.IsN32(); }
598 bool isABI_N64() const { return ABI
.IsN64(); }
599 bool isABI_O32() const { return ABI
.IsO32(); }
600 bool isABI_FPXX() const {
601 return getSTI().hasFeature(Mips::FeatureFPXX
);
604 bool useOddSPReg() const {
605 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg
));
608 bool inMicroMipsMode() const {
609 return getSTI().hasFeature(Mips::FeatureMicroMips
);
612 bool hasMips1() const {
613 return getSTI().hasFeature(Mips::FeatureMips1
);
616 bool hasMips2() const {
617 return getSTI().hasFeature(Mips::FeatureMips2
);
620 bool hasMips3() const {
621 return getSTI().hasFeature(Mips::FeatureMips3
);
624 bool hasMips4() const {
625 return getSTI().hasFeature(Mips::FeatureMips4
);
628 bool hasMips5() const {
629 return getSTI().hasFeature(Mips::FeatureMips5
);
632 bool hasMips32() const {
633 return getSTI().hasFeature(Mips::FeatureMips32
);
636 bool hasMips64() const {
637 return getSTI().hasFeature(Mips::FeatureMips64
);
640 bool hasMips32r2() const {
641 return getSTI().hasFeature(Mips::FeatureMips32r2
);
644 bool hasMips64r2() const {
645 return getSTI().hasFeature(Mips::FeatureMips64r2
);
648 bool hasMips32r3() const {
649 return (getSTI().hasFeature(Mips::FeatureMips32r3
));
652 bool hasMips64r3() const {
653 return (getSTI().hasFeature(Mips::FeatureMips64r3
));
656 bool hasMips32r5() const {
657 return (getSTI().hasFeature(Mips::FeatureMips32r5
));
660 bool hasMips64r5() const {
661 return (getSTI().hasFeature(Mips::FeatureMips64r5
));
664 bool hasMips32r6() const {
665 return getSTI().hasFeature(Mips::FeatureMips32r6
);
668 bool hasMips64r6() const {
669 return getSTI().hasFeature(Mips::FeatureMips64r6
);
672 bool hasDSP() const {
673 return getSTI().hasFeature(Mips::FeatureDSP
);
676 bool hasDSPR2() const {
677 return getSTI().hasFeature(Mips::FeatureDSPR2
);
680 bool hasDSPR3() const {
681 return getSTI().hasFeature(Mips::FeatureDSPR3
);
684 bool hasMSA() const {
685 return getSTI().hasFeature(Mips::FeatureMSA
);
688 bool hasCnMips() const {
689 return (getSTI().hasFeature(Mips::FeatureCnMips
));
692 bool hasCnMipsP() const {
693 return (getSTI().hasFeature(Mips::FeatureCnMipsP
));
700 bool inMips16Mode() const {
701 return getSTI().hasFeature(Mips::FeatureMips16
);
704 bool useTraps() const {
705 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV
);
708 bool useSoftFloat() const {
709 return getSTI().hasFeature(Mips::FeatureSoftFloat
);
712 return getSTI().hasFeature(Mips::FeatureMT
);
715 bool hasCRC() const {
716 return getSTI().hasFeature(Mips::FeatureCRC
);
719 bool hasVirt() const {
720 return getSTI().hasFeature(Mips::FeatureVirt
);
723 bool hasGINV() const {
724 return getSTI().hasFeature(Mips::FeatureGINV
);
727 bool hasForbiddenSlot(const MCInstrDesc
&MCID
) const {
728 return !inMicroMipsMode() && (MCID
.TSFlags
& MipsII::HasForbiddenSlot
);
731 bool SafeInForbiddenSlot(const MCInstrDesc
&MCID
) const {
732 return !(MCID
.TSFlags
& MipsII::IsCTI
);
735 void onEndOfFile() override
;
737 /// Warn if RegIndex is the same as the current AT.
738 void warnIfRegIndexIsAT(unsigned RegIndex
, SMLoc Loc
);
740 void warnIfNoMacro(SMLoc Loc
);
742 bool isLittle() const { return IsLittleEndian
; }
744 const MCExpr
*createTargetUnaryExpr(const MCExpr
*E
,
745 AsmToken::TokenKind OperatorToken
,
746 MCContext
&Ctx
) override
{
747 switch(OperatorToken
) {
749 llvm_unreachable("Unknown token");
751 case AsmToken::PercentCall16
:
752 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL
, E
, Ctx
);
753 case AsmToken::PercentCall_Hi
:
754 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16
, E
, Ctx
);
755 case AsmToken::PercentCall_Lo
:
756 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16
, E
, Ctx
);
757 case AsmToken::PercentDtprel_Hi
:
758 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI
, E
, Ctx
);
759 case AsmToken::PercentDtprel_Lo
:
760 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO
, E
, Ctx
);
761 case AsmToken::PercentGot
:
762 return MipsMCExpr::create(MipsMCExpr::MEK_GOT
, E
, Ctx
);
763 case AsmToken::PercentGot_Disp
:
764 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP
, E
, Ctx
);
765 case AsmToken::PercentGot_Hi
:
766 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16
, E
, Ctx
);
767 case AsmToken::PercentGot_Lo
:
768 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16
, E
, Ctx
);
769 case AsmToken::PercentGot_Ofst
:
770 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST
, E
, Ctx
);
771 case AsmToken::PercentGot_Page
:
772 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE
, E
, Ctx
);
773 case AsmToken::PercentGottprel
:
774 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL
, E
, Ctx
);
775 case AsmToken::PercentGp_Rel
:
776 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL
, E
, Ctx
);
777 case AsmToken::PercentHi
:
778 return MipsMCExpr::create(MipsMCExpr::MEK_HI
, E
, Ctx
);
779 case AsmToken::PercentHigher
:
780 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER
, E
, Ctx
);
781 case AsmToken::PercentHighest
:
782 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST
, E
, Ctx
);
783 case AsmToken::PercentLo
:
784 return MipsMCExpr::create(MipsMCExpr::MEK_LO
, E
, Ctx
);
785 case AsmToken::PercentNeg
:
786 return MipsMCExpr::create(MipsMCExpr::MEK_NEG
, E
, Ctx
);
787 case AsmToken::PercentPcrel_Hi
:
788 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16
, E
, Ctx
);
789 case AsmToken::PercentPcrel_Lo
:
790 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16
, E
, Ctx
);
791 case AsmToken::PercentTlsgd
:
792 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD
, E
, Ctx
);
793 case AsmToken::PercentTlsldm
:
794 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM
, E
, Ctx
);
795 case AsmToken::PercentTprel_Hi
:
796 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI
, E
, Ctx
);
797 case AsmToken::PercentTprel_Lo
:
798 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO
, E
, Ctx
);
802 bool areEqualRegs(const MCParsedAsmOperand
&Op1
,
803 const MCParsedAsmOperand
&Op2
) const override
;
806 /// MipsOperand - Instances of this class represent a parsed Mips machine
808 class MipsOperand
: public MCParsedAsmOperand
{
810 /// Broad categories of register classes
811 /// The exact class is finalized by the render method.
813 RegKind_GPR
= 1, /// GPR32 and GPR64 (depending on isGP64bit())
814 RegKind_FGR
= 2, /// FGR32, FGR64, AFGR64 (depending on context and
816 RegKind_FCC
= 4, /// FCC
817 RegKind_MSA128
= 8, /// MSA128[BHWD] (makes no difference which)
818 RegKind_MSACtrl
= 16, /// MSA control registers
819 RegKind_COP2
= 32, /// COP2
820 RegKind_ACC
= 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
822 RegKind_CCR
= 128, /// CCR
823 RegKind_HWRegs
= 256, /// HWRegs
824 RegKind_COP3
= 512, /// COP3
825 RegKind_COP0
= 1024, /// COP0
826 /// Potentially any (e.g. $1)
827 RegKind_Numeric
= RegKind_GPR
| RegKind_FGR
| RegKind_FCC
| RegKind_MSA128
|
828 RegKind_MSACtrl
| RegKind_COP2
| RegKind_ACC
|
829 RegKind_CCR
| RegKind_HWRegs
| RegKind_COP3
| RegKind_COP0
834 k_Immediate
, /// An immediate (possibly involving symbol references)
835 k_Memory
, /// Base + Offset Memory Address
836 k_RegisterIndex
, /// A register index in one or more RegKind.
837 k_Token
, /// A simple token
838 k_RegList
, /// A physical register list
842 MipsOperand(KindTy K
, MipsAsmParser
&Parser
) : Kind(K
), AsmParser(Parser
) {}
844 ~MipsOperand() override
{
853 case k_RegisterIndex
:
860 /// For diagnostics, and checking the assembler temporary
861 MipsAsmParser
&AsmParser
;
869 unsigned Index
; /// Index into the register class
870 RegKind Kind
; /// Bitfield of the kinds it could possibly be
871 struct Token Tok
; /// The input token this operand originated from.
872 const MCRegisterInfo
*RegInfo
;
885 SmallVector
<unsigned, 10> *List
;
890 struct RegIdxOp RegIdx
;
893 struct RegListOp RegList
;
896 SMLoc StartLoc
, EndLoc
;
898 /// Internal constructor for register kinds
899 static std::unique_ptr
<MipsOperand
> CreateReg(unsigned Index
, StringRef Str
,
901 const MCRegisterInfo
*RegInfo
,
903 MipsAsmParser
&Parser
) {
904 auto Op
= std::make_unique
<MipsOperand
>(k_RegisterIndex
, Parser
);
905 Op
->RegIdx
.Index
= Index
;
906 Op
->RegIdx
.RegInfo
= RegInfo
;
907 Op
->RegIdx
.Kind
= RegKind
;
908 Op
->RegIdx
.Tok
.Data
= Str
.data();
909 Op
->RegIdx
.Tok
.Length
= Str
.size();
916 /// Coerce the register to GPR32 and return the real register for the current
918 unsigned getGPR32Reg() const {
919 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_GPR
) && "Invalid access!");
920 AsmParser
.warnIfRegIndexIsAT(RegIdx
.Index
, StartLoc
);
921 unsigned ClassID
= Mips::GPR32RegClassID
;
922 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
925 /// Coerce the register to GPR32 and return the real register for the current
927 unsigned getGPRMM16Reg() const {
928 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_GPR
) && "Invalid access!");
929 unsigned ClassID
= Mips::GPR32RegClassID
;
930 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
933 /// Coerce the register to GPR64 and return the real register for the current
935 unsigned getGPR64Reg() const {
936 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_GPR
) && "Invalid access!");
937 unsigned ClassID
= Mips::GPR64RegClassID
;
938 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
942 /// Coerce the register to AFGR64 and return the real register for the current
944 unsigned getAFGR64Reg() const {
945 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FGR
) && "Invalid access!");
946 if (RegIdx
.Index
% 2 != 0)
947 AsmParser
.Warning(StartLoc
, "Float register should be even.");
948 return RegIdx
.RegInfo
->getRegClass(Mips::AFGR64RegClassID
)
949 .getRegister(RegIdx
.Index
/ 2);
952 /// Coerce the register to FGR64 and return the real register for the current
954 unsigned getFGR64Reg() const {
955 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FGR
) && "Invalid access!");
956 return RegIdx
.RegInfo
->getRegClass(Mips::FGR64RegClassID
)
957 .getRegister(RegIdx
.Index
);
960 /// Coerce the register to FGR32 and return the real register for the current
962 unsigned getFGR32Reg() const {
963 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FGR
) && "Invalid access!");
964 return RegIdx
.RegInfo
->getRegClass(Mips::FGR32RegClassID
)
965 .getRegister(RegIdx
.Index
);
968 /// Coerce the register to FCC and return the real register for the current
970 unsigned getFCCReg() const {
971 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FCC
) && "Invalid access!");
972 return RegIdx
.RegInfo
->getRegClass(Mips::FCCRegClassID
)
973 .getRegister(RegIdx
.Index
);
976 /// Coerce the register to MSA128 and return the real register for the current
978 unsigned getMSA128Reg() const {
979 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_MSA128
) && "Invalid access!");
980 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
982 unsigned ClassID
= Mips::MSA128BRegClassID
;
983 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
986 /// Coerce the register to MSACtrl and return the real register for the
988 unsigned getMSACtrlReg() const {
989 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_MSACtrl
) && "Invalid access!");
990 unsigned ClassID
= Mips::MSACtrlRegClassID
;
991 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
994 /// Coerce the register to COP0 and return the real register for the
996 unsigned getCOP0Reg() const {
997 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_COP0
) && "Invalid access!");
998 unsigned ClassID
= Mips::COP0RegClassID
;
999 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1002 /// Coerce the register to COP2 and return the real register for the
1004 unsigned getCOP2Reg() const {
1005 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_COP2
) && "Invalid access!");
1006 unsigned ClassID
= Mips::COP2RegClassID
;
1007 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1010 /// Coerce the register to COP3 and return the real register for the
1012 unsigned getCOP3Reg() const {
1013 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_COP3
) && "Invalid access!");
1014 unsigned ClassID
= Mips::COP3RegClassID
;
1015 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1018 /// Coerce the register to ACC64DSP and return the real register for the
1020 unsigned getACC64DSPReg() const {
1021 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_ACC
) && "Invalid access!");
1022 unsigned ClassID
= Mips::ACC64DSPRegClassID
;
1023 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1026 /// Coerce the register to HI32DSP and return the real register for the
1028 unsigned getHI32DSPReg() const {
1029 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_ACC
) && "Invalid access!");
1030 unsigned ClassID
= Mips::HI32DSPRegClassID
;
1031 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1034 /// Coerce the register to LO32DSP and return the real register for the
1036 unsigned getLO32DSPReg() const {
1037 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_ACC
) && "Invalid access!");
1038 unsigned ClassID
= Mips::LO32DSPRegClassID
;
1039 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1042 /// Coerce the register to CCR and return the real register for the
1044 unsigned getCCRReg() const {
1045 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_CCR
) && "Invalid access!");
1046 unsigned ClassID
= Mips::CCRRegClassID
;
1047 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1050 /// Coerce the register to HWRegs and return the real register for the
1052 unsigned getHWRegsReg() const {
1053 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_HWRegs
) && "Invalid access!");
1054 unsigned ClassID
= Mips::HWRegsRegClassID
;
1055 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1059 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
1060 // Add as immediate when possible. Null MCExpr = 0.
1062 Inst
.addOperand(MCOperand::createImm(0));
1063 else if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Expr
))
1064 Inst
.addOperand(MCOperand::createImm(CE
->getValue()));
1066 Inst
.addOperand(MCOperand::createExpr(Expr
));
1069 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
1070 llvm_unreachable("Use a custom parser instead");
1073 /// Render the operand to an MCInst as a GPR32
1074 /// Asserts if the wrong number of operands are requested, or the operand
1075 /// is not a k_RegisterIndex compatible with RegKind_GPR
1076 void addGPR32ZeroAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1077 assert(N
== 1 && "Invalid number of operands!");
1078 Inst
.addOperand(MCOperand::createReg(getGPR32Reg()));
1081 void addGPR32NonZeroAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1082 assert(N
== 1 && "Invalid number of operands!");
1083 Inst
.addOperand(MCOperand::createReg(getGPR32Reg()));
1086 void addGPR32AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1087 assert(N
== 1 && "Invalid number of operands!");
1088 Inst
.addOperand(MCOperand::createReg(getGPR32Reg()));
1091 void addGPRMM16AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1092 assert(N
== 1 && "Invalid number of operands!");
1093 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1096 void addGPRMM16AsmRegZeroOperands(MCInst
&Inst
, unsigned N
) const {
1097 assert(N
== 1 && "Invalid number of operands!");
1098 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1101 void addGPRMM16AsmRegMovePOperands(MCInst
&Inst
, unsigned N
) const {
1102 assert(N
== 1 && "Invalid number of operands!");
1103 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1106 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst
&Inst
, unsigned N
) const {
1107 assert(N
== 1 && "Invalid number of operands!");
1108 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1111 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst
&Inst
,
1113 assert(N
== 1 && "Invalid number of operands!");
1114 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1117 /// Render the operand to an MCInst as a GPR64
1118 /// Asserts if the wrong number of operands are requested, or the operand
1119 /// is not a k_RegisterIndex compatible with RegKind_GPR
1120 void addGPR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1121 assert(N
== 1 && "Invalid number of operands!");
1122 Inst
.addOperand(MCOperand::createReg(getGPR64Reg()));
1125 void addAFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1126 assert(N
== 1 && "Invalid number of operands!");
1127 Inst
.addOperand(MCOperand::createReg(getAFGR64Reg()));
1130 void addStrictlyAFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1131 assert(N
== 1 && "Invalid number of operands!");
1132 Inst
.addOperand(MCOperand::createReg(getAFGR64Reg()));
1135 void addStrictlyFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1136 assert(N
== 1 && "Invalid number of operands!");
1137 Inst
.addOperand(MCOperand::createReg(getFGR64Reg()));
1140 void addFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1141 assert(N
== 1 && "Invalid number of operands!");
1142 Inst
.addOperand(MCOperand::createReg(getFGR64Reg()));
1145 void addFGR32AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1146 assert(N
== 1 && "Invalid number of operands!");
1147 Inst
.addOperand(MCOperand::createReg(getFGR32Reg()));
1148 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1149 // FIXME: This should propagate failure up to parseStatement.
1150 if (!AsmParser
.useOddSPReg() && RegIdx
.Index
& 1)
1151 AsmParser
.getParser().printError(
1152 StartLoc
, "-mno-odd-spreg prohibits the use of odd FPU "
1156 void addStrictlyFGR32AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1157 assert(N
== 1 && "Invalid number of operands!");
1158 Inst
.addOperand(MCOperand::createReg(getFGR32Reg()));
1159 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1160 if (!AsmParser
.useOddSPReg() && RegIdx
.Index
& 1)
1161 AsmParser
.Error(StartLoc
, "-mno-odd-spreg prohibits the use of odd FPU "
1165 void addFCCAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1166 assert(N
== 1 && "Invalid number of operands!");
1167 Inst
.addOperand(MCOperand::createReg(getFCCReg()));
1170 void addMSA128AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1171 assert(N
== 1 && "Invalid number of operands!");
1172 Inst
.addOperand(MCOperand::createReg(getMSA128Reg()));
1175 void addMSACtrlAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1176 assert(N
== 1 && "Invalid number of operands!");
1177 Inst
.addOperand(MCOperand::createReg(getMSACtrlReg()));
1180 void addCOP0AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1181 assert(N
== 1 && "Invalid number of operands!");
1182 Inst
.addOperand(MCOperand::createReg(getCOP0Reg()));
1185 void addCOP2AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1186 assert(N
== 1 && "Invalid number of operands!");
1187 Inst
.addOperand(MCOperand::createReg(getCOP2Reg()));
1190 void addCOP3AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1191 assert(N
== 1 && "Invalid number of operands!");
1192 Inst
.addOperand(MCOperand::createReg(getCOP3Reg()));
1195 void addACC64DSPAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1196 assert(N
== 1 && "Invalid number of operands!");
1197 Inst
.addOperand(MCOperand::createReg(getACC64DSPReg()));
1200 void addHI32DSPAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1201 assert(N
== 1 && "Invalid number of operands!");
1202 Inst
.addOperand(MCOperand::createReg(getHI32DSPReg()));
1205 void addLO32DSPAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1206 assert(N
== 1 && "Invalid number of operands!");
1207 Inst
.addOperand(MCOperand::createReg(getLO32DSPReg()));
1210 void addCCRAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1211 assert(N
== 1 && "Invalid number of operands!");
1212 Inst
.addOperand(MCOperand::createReg(getCCRReg()));
1215 void addHWRegsAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1216 assert(N
== 1 && "Invalid number of operands!");
1217 Inst
.addOperand(MCOperand::createReg(getHWRegsReg()));
1220 template <unsigned Bits
, int Offset
= 0, int AdjustOffset
= 0>
1221 void addConstantUImmOperands(MCInst
&Inst
, unsigned N
) const {
1222 assert(N
== 1 && "Invalid number of operands!");
1223 uint64_t Imm
= getConstantImm() - Offset
;
1224 Imm
&= (1ULL << Bits
) - 1;
1226 Imm
+= AdjustOffset
;
1227 Inst
.addOperand(MCOperand::createImm(Imm
));
1230 template <unsigned Bits
>
1231 void addSImmOperands(MCInst
&Inst
, unsigned N
) const {
1232 if (isImm() && !isConstantImm()) {
1233 addExpr(Inst
, getImm());
1236 addConstantSImmOperands
<Bits
, 0, 0>(Inst
, N
);
1239 template <unsigned Bits
>
1240 void addUImmOperands(MCInst
&Inst
, unsigned N
) const {
1241 if (isImm() && !isConstantImm()) {
1242 addExpr(Inst
, getImm());
1245 addConstantUImmOperands
<Bits
, 0, 0>(Inst
, N
);
1248 template <unsigned Bits
, int Offset
= 0, int AdjustOffset
= 0>
1249 void addConstantSImmOperands(MCInst
&Inst
, unsigned N
) const {
1250 assert(N
== 1 && "Invalid number of operands!");
1251 int64_t Imm
= getConstantImm() - Offset
;
1252 Imm
= SignExtend64
<Bits
>(Imm
);
1254 Imm
+= AdjustOffset
;
1255 Inst
.addOperand(MCOperand::createImm(Imm
));
1258 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
1259 assert(N
== 1 && "Invalid number of operands!");
1260 const MCExpr
*Expr
= getImm();
1261 addExpr(Inst
, Expr
);
1264 void addMemOperands(MCInst
&Inst
, unsigned N
) const {
1265 assert(N
== 2 && "Invalid number of operands!");
1267 Inst
.addOperand(MCOperand::createReg(AsmParser
.getABI().ArePtrs64bit()
1268 ? getMemBase()->getGPR64Reg()
1269 : getMemBase()->getGPR32Reg()));
1271 const MCExpr
*Expr
= getMemOff();
1272 addExpr(Inst
, Expr
);
1275 void addMicroMipsMemOperands(MCInst
&Inst
, unsigned N
) const {
1276 assert(N
== 2 && "Invalid number of operands!");
1278 Inst
.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1280 const MCExpr
*Expr
= getMemOff();
1281 addExpr(Inst
, Expr
);
1284 void addRegListOperands(MCInst
&Inst
, unsigned N
) const {
1285 assert(N
== 1 && "Invalid number of operands!");
1287 for (auto RegNo
: getRegList())
1288 Inst
.addOperand(MCOperand::createReg(RegNo
));
1291 bool isReg() const override
{
1292 // As a special case until we sort out the definition of div/divu, accept
1293 // $0/$zero here so that MCK_ZERO works correctly.
1294 return isGPRAsmReg() && RegIdx
.Index
== 0;
1297 bool isRegIdx() const { return Kind
== k_RegisterIndex
; }
1298 bool isImm() const override
{ return Kind
== k_Immediate
; }
1300 bool isConstantImm() const {
1302 return isImm() && getImm()->evaluateAsAbsolute(Res
);
1305 bool isConstantImmz() const {
1306 return isConstantImm() && getConstantImm() == 0;
1309 template <unsigned Bits
, int Offset
= 0> bool isConstantUImm() const {
1310 return isConstantImm() && isUInt
<Bits
>(getConstantImm() - Offset
);
1313 template <unsigned Bits
> bool isSImm() const {
1314 return isConstantImm() ? isInt
<Bits
>(getConstantImm()) : isImm();
1317 template <unsigned Bits
> bool isUImm() const {
1318 return isConstantImm() ? isUInt
<Bits
>(getConstantImm()) : isImm();
1321 template <unsigned Bits
> bool isAnyImm() const {
1322 return isConstantImm() ? (isInt
<Bits
>(getConstantImm()) ||
1323 isUInt
<Bits
>(getConstantImm()))
1327 template <unsigned Bits
, int Offset
= 0> bool isConstantSImm() const {
1328 return isConstantImm() && isInt
<Bits
>(getConstantImm() - Offset
);
1331 template <unsigned Bottom
, unsigned Top
> bool isConstantUImmRange() const {
1332 return isConstantImm() && getConstantImm() >= Bottom
&&
1333 getConstantImm() <= Top
;
1336 bool isToken() const override
{
1337 // Note: It's not possible to pretend that other operand kinds are tokens.
1338 // The matcher emitter checks tokens first.
1339 return Kind
== k_Token
;
1342 bool isMem() const override
{ return Kind
== k_Memory
; }
1344 bool isConstantMemOff() const {
1345 return isMem() && isa
<MCConstantExpr
>(getMemOff());
1348 // Allow relocation operators.
1349 template <unsigned Bits
, unsigned ShiftAmount
= 0>
1350 bool isMemWithSimmOffset() const {
1353 if (!getMemBase()->isGPRAsmReg())
1355 if (isa
<MCTargetExpr
>(getMemOff()) ||
1356 (isConstantMemOff() &&
1357 isShiftedInt
<Bits
, ShiftAmount
>(getConstantMemOff())))
1360 bool IsReloc
= getMemOff()->evaluateAsRelocatable(Res
, nullptr, nullptr);
1361 return IsReloc
&& isShiftedInt
<Bits
, ShiftAmount
>(Res
.getConstant());
1364 bool isMemWithPtrSizeOffset() const {
1367 if (!getMemBase()->isGPRAsmReg())
1369 const unsigned PtrBits
= AsmParser
.getABI().ArePtrs64bit() ? 64 : 32;
1370 if (isa
<MCTargetExpr
>(getMemOff()) ||
1371 (isConstantMemOff() && isIntN(PtrBits
, getConstantMemOff())))
1374 bool IsReloc
= getMemOff()->evaluateAsRelocatable(Res
, nullptr, nullptr);
1375 return IsReloc
&& isIntN(PtrBits
, Res
.getConstant());
1378 bool isMemWithGRPMM16Base() const {
1379 return isMem() && getMemBase()->isMM16AsmReg();
1382 template <unsigned Bits
> bool isMemWithUimmOffsetSP() const {
1383 return isMem() && isConstantMemOff() && isUInt
<Bits
>(getConstantMemOff())
1384 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP
);
1387 template <unsigned Bits
> bool isMemWithUimmWordAlignedOffsetSP() const {
1388 return isMem() && isConstantMemOff() && isUInt
<Bits
>(getConstantMemOff())
1389 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1390 && (getMemBase()->getGPR32Reg() == Mips::SP
);
1393 template <unsigned Bits
> bool isMemWithSimmWordAlignedOffsetGP() const {
1394 return isMem() && isConstantMemOff() && isInt
<Bits
>(getConstantMemOff())
1395 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1396 && (getMemBase()->getGPR32Reg() == Mips::GP
);
1399 template <unsigned Bits
, unsigned ShiftLeftAmount
>
1400 bool isScaledUImm() const {
1401 return isConstantImm() &&
1402 isShiftedUInt
<Bits
, ShiftLeftAmount
>(getConstantImm());
1405 template <unsigned Bits
, unsigned ShiftLeftAmount
>
1406 bool isScaledSImm() const {
1407 if (isConstantImm() &&
1408 isShiftedInt
<Bits
, ShiftLeftAmount
>(getConstantImm()))
1410 // Operand can also be a symbol or symbol plus
1411 // offset in case of relocations.
1412 if (Kind
!= k_Immediate
)
1415 bool Success
= getImm()->evaluateAsRelocatable(Res
, nullptr, nullptr);
1416 return Success
&& isShiftedInt
<Bits
, ShiftLeftAmount
>(Res
.getConstant());
1419 bool isRegList16() const {
1423 int Size
= RegList
.List
->size();
1424 if (Size
< 2 || Size
> 5)
1427 unsigned R0
= RegList
.List
->front();
1428 unsigned R1
= RegList
.List
->back();
1429 if (!((R0
== Mips::S0
&& R1
== Mips::RA
) ||
1430 (R0
== Mips::S0_64
&& R1
== Mips::RA_64
)))
1433 int PrevReg
= *RegList
.List
->begin();
1434 for (int i
= 1; i
< Size
- 1; i
++) {
1435 int Reg
= (*(RegList
.List
))[i
];
1436 if ( Reg
!= PrevReg
+ 1)
1444 bool isInvNum() const { return Kind
== k_Immediate
; }
1446 bool isLSAImm() const {
1447 if (!isConstantImm())
1449 int64_t Val
= getConstantImm();
1450 return 1 <= Val
&& Val
<= 4;
1453 bool isRegList() const { return Kind
== k_RegList
; }
1455 StringRef
getToken() const {
1456 assert(Kind
== k_Token
&& "Invalid access!");
1457 return StringRef(Tok
.Data
, Tok
.Length
);
1460 MCRegister
getReg() const override
{
1461 // As a special case until we sort out the definition of div/divu, accept
1462 // $0/$zero here so that MCK_ZERO works correctly.
1463 if (Kind
== k_RegisterIndex
&& RegIdx
.Index
== 0 &&
1464 RegIdx
.Kind
& RegKind_GPR
)
1465 return getGPR32Reg(); // FIXME: GPR64 too
1467 llvm_unreachable("Invalid access!");
1471 const MCExpr
*getImm() const {
1472 assert((Kind
== k_Immediate
) && "Invalid access!");
1476 int64_t getConstantImm() const {
1477 const MCExpr
*Val
= getImm();
1479 (void)Val
->evaluateAsAbsolute(Value
);
1483 MipsOperand
*getMemBase() const {
1484 assert((Kind
== k_Memory
) && "Invalid access!");
1488 const MCExpr
*getMemOff() const {
1489 assert((Kind
== k_Memory
) && "Invalid access!");
1493 int64_t getConstantMemOff() const {
1494 return static_cast<const MCConstantExpr
*>(getMemOff())->getValue();
1497 const SmallVectorImpl
<unsigned> &getRegList() const {
1498 assert((Kind
== k_RegList
) && "Invalid access!");
1499 return *(RegList
.List
);
1502 static std::unique_ptr
<MipsOperand
> CreateToken(StringRef Str
, SMLoc S
,
1503 MipsAsmParser
&Parser
) {
1504 auto Op
= std::make_unique
<MipsOperand
>(k_Token
, Parser
);
1505 Op
->Tok
.Data
= Str
.data();
1506 Op
->Tok
.Length
= Str
.size();
1512 /// Create a numeric register (e.g. $1). The exact register remains
1513 /// unresolved until an instruction successfully matches
1514 static std::unique_ptr
<MipsOperand
>
1515 createNumericReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1516 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1517 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index
<< ", ...)\n");
1518 return CreateReg(Index
, Str
, RegKind_Numeric
, RegInfo
, S
, E
, Parser
);
1521 /// Create a register that is definitely a GPR.
1522 /// This is typically only used for named registers such as $gp.
1523 static std::unique_ptr
<MipsOperand
>
1524 createGPRReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1525 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1526 return CreateReg(Index
, Str
, RegKind_GPR
, RegInfo
, S
, E
, Parser
);
1529 /// Create a register that is definitely a FGR.
1530 /// This is typically only used for named registers such as $f0.
1531 static std::unique_ptr
<MipsOperand
>
1532 createFGRReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1533 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1534 return CreateReg(Index
, Str
, RegKind_FGR
, RegInfo
, S
, E
, Parser
);
1537 /// Create a register that is definitely a HWReg.
1538 /// This is typically only used for named registers such as $hwr_cpunum.
1539 static std::unique_ptr
<MipsOperand
>
1540 createHWRegsReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1541 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1542 return CreateReg(Index
, Str
, RegKind_HWRegs
, RegInfo
, S
, E
, Parser
);
1545 /// Create a register that is definitely an FCC.
1546 /// This is typically only used for named registers such as $fcc0.
1547 static std::unique_ptr
<MipsOperand
>
1548 createFCCReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1549 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1550 return CreateReg(Index
, Str
, RegKind_FCC
, RegInfo
, S
, E
, Parser
);
1553 /// Create a register that is definitely an ACC.
1554 /// This is typically only used for named registers such as $ac0.
1555 static std::unique_ptr
<MipsOperand
>
1556 createACCReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1557 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1558 return CreateReg(Index
, Str
, RegKind_ACC
, RegInfo
, S
, E
, Parser
);
1561 /// Create a register that is definitely an MSA128.
1562 /// This is typically only used for named registers such as $w0.
1563 static std::unique_ptr
<MipsOperand
>
1564 createMSA128Reg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1565 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1566 return CreateReg(Index
, Str
, RegKind_MSA128
, RegInfo
, S
, E
, Parser
);
1569 /// Create a register that is definitely an MSACtrl.
1570 /// This is typically only used for named registers such as $msaaccess.
1571 static std::unique_ptr
<MipsOperand
>
1572 createMSACtrlReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1573 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1574 return CreateReg(Index
, Str
, RegKind_MSACtrl
, RegInfo
, S
, E
, Parser
);
1577 static std::unique_ptr
<MipsOperand
>
1578 CreateImm(const MCExpr
*Val
, SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1579 auto Op
= std::make_unique
<MipsOperand
>(k_Immediate
, Parser
);
1586 static std::unique_ptr
<MipsOperand
>
1587 CreateMem(std::unique_ptr
<MipsOperand
> Base
, const MCExpr
*Off
, SMLoc S
,
1588 SMLoc E
, MipsAsmParser
&Parser
) {
1589 auto Op
= std::make_unique
<MipsOperand
>(k_Memory
, Parser
);
1590 Op
->Mem
.Base
= Base
.release();
1597 static std::unique_ptr
<MipsOperand
>
1598 CreateRegList(SmallVectorImpl
<unsigned> &Regs
, SMLoc StartLoc
, SMLoc EndLoc
,
1599 MipsAsmParser
&Parser
) {
1600 assert(Regs
.size() > 0 && "Empty list not allowed");
1602 auto Op
= std::make_unique
<MipsOperand
>(k_RegList
, Parser
);
1603 Op
->RegList
.List
= new SmallVector
<unsigned, 10>(Regs
.begin(), Regs
.end());
1604 Op
->StartLoc
= StartLoc
;
1605 Op
->EndLoc
= EndLoc
;
1609 bool isGPRZeroAsmReg() const {
1610 return isRegIdx() && RegIdx
.Kind
& RegKind_GPR
&& RegIdx
.Index
== 0;
1613 bool isGPRNonZeroAsmReg() const {
1614 return isRegIdx() && RegIdx
.Kind
& RegKind_GPR
&& RegIdx
.Index
> 0 &&
1618 bool isGPRAsmReg() const {
1619 return isRegIdx() && RegIdx
.Kind
& RegKind_GPR
&& RegIdx
.Index
<= 31;
1622 bool isMM16AsmReg() const {
1623 if (!(isRegIdx() && RegIdx
.Kind
))
1625 return ((RegIdx
.Index
>= 2 && RegIdx
.Index
<= 7)
1626 || RegIdx
.Index
== 16 || RegIdx
.Index
== 17);
1629 bool isMM16AsmRegZero() const {
1630 if (!(isRegIdx() && RegIdx
.Kind
))
1632 return (RegIdx
.Index
== 0 ||
1633 (RegIdx
.Index
>= 2 && RegIdx
.Index
<= 7) ||
1634 RegIdx
.Index
== 17);
1637 bool isMM16AsmRegMoveP() const {
1638 if (!(isRegIdx() && RegIdx
.Kind
))
1640 return (RegIdx
.Index
== 0 || (RegIdx
.Index
>= 2 && RegIdx
.Index
<= 3) ||
1641 (RegIdx
.Index
>= 16 && RegIdx
.Index
<= 20));
1644 bool isMM16AsmRegMovePPairFirst() const {
1645 if (!(isRegIdx() && RegIdx
.Kind
))
1647 return RegIdx
.Index
>= 4 && RegIdx
.Index
<= 6;
1650 bool isMM16AsmRegMovePPairSecond() const {
1651 if (!(isRegIdx() && RegIdx
.Kind
))
1653 return (RegIdx
.Index
== 21 || RegIdx
.Index
== 22 ||
1654 (RegIdx
.Index
>= 5 && RegIdx
.Index
<= 7));
1657 bool isFGRAsmReg() const {
1658 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1659 return isRegIdx() && RegIdx
.Kind
& RegKind_FGR
&& RegIdx
.Index
<= 31;
1662 bool isStrictlyFGRAsmReg() const {
1663 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1664 return isRegIdx() && RegIdx
.Kind
== RegKind_FGR
&& RegIdx
.Index
<= 31;
1667 bool isHWRegsAsmReg() const {
1668 return isRegIdx() && RegIdx
.Kind
& RegKind_HWRegs
&& RegIdx
.Index
<= 31;
1671 bool isCCRAsmReg() const {
1672 return isRegIdx() && RegIdx
.Kind
& RegKind_CCR
&& RegIdx
.Index
<= 31;
1675 bool isFCCAsmReg() const {
1676 if (!(isRegIdx() && RegIdx
.Kind
& RegKind_FCC
))
1678 return RegIdx
.Index
<= 7;
1681 bool isACCAsmReg() const {
1682 return isRegIdx() && RegIdx
.Kind
& RegKind_ACC
&& RegIdx
.Index
<= 3;
1685 bool isCOP0AsmReg() const {
1686 return isRegIdx() && RegIdx
.Kind
& RegKind_COP0
&& RegIdx
.Index
<= 31;
1689 bool isCOP2AsmReg() const {
1690 return isRegIdx() && RegIdx
.Kind
& RegKind_COP2
&& RegIdx
.Index
<= 31;
1693 bool isCOP3AsmReg() const {
1694 return isRegIdx() && RegIdx
.Kind
& RegKind_COP3
&& RegIdx
.Index
<= 31;
1697 bool isMSA128AsmReg() const {
1698 return isRegIdx() && RegIdx
.Kind
& RegKind_MSA128
&& RegIdx
.Index
<= 31;
1701 bool isMSACtrlAsmReg() const {
1702 return isRegIdx() && RegIdx
.Kind
& RegKind_MSACtrl
&& RegIdx
.Index
<= 7;
1705 /// getStartLoc - Get the location of the first token of this operand.
1706 SMLoc
getStartLoc() const override
{ return StartLoc
; }
1707 /// getEndLoc - Get the location of the last token of this operand.
1708 SMLoc
getEndLoc() const override
{ return EndLoc
; }
1710 void print(raw_ostream
&OS
) const override
{
1719 Mem
.Base
->print(OS
);
1724 case k_RegisterIndex
:
1725 OS
<< "RegIdx<" << RegIdx
.Index
<< ":" << RegIdx
.Kind
<< ", "
1726 << StringRef(RegIdx
.Tok
.Data
, RegIdx
.Tok
.Length
) << ">";
1733 for (auto Reg
: (*RegList
.List
))
1740 bool isValidForTie(const MipsOperand
&Other
) const {
1741 if (Kind
!= Other
.Kind
)
1746 llvm_unreachable("Unexpected kind");
1748 case k_RegisterIndex
: {
1749 StringRef
Token(RegIdx
.Tok
.Data
, RegIdx
.Tok
.Length
);
1750 StringRef
OtherToken(Other
.RegIdx
.Tok
.Data
, Other
.RegIdx
.Tok
.Length
);
1751 return Token
== OtherToken
;
1755 }; // class MipsOperand
1757 } // end anonymous namespace
1759 static bool hasShortDelaySlot(MCInst
&Inst
) {
1760 switch (Inst
.getOpcode()) {
1767 case Mips::JRC16_MM
:
1769 case Mips::JALRS_MM
:
1770 case Mips::JALRS16_MM
:
1771 case Mips::BGEZALS_MM
:
1772 case Mips::BLTZALS_MM
:
1775 return !Inst
.getOperand(0).isReg();
1781 static const MCSymbol
*getSingleMCSymbol(const MCExpr
*Expr
) {
1782 if (const MCSymbolRefExpr
*SRExpr
= dyn_cast
<MCSymbolRefExpr
>(Expr
)) {
1783 return &SRExpr
->getSymbol();
1786 if (const MCBinaryExpr
*BExpr
= dyn_cast
<MCBinaryExpr
>(Expr
)) {
1787 const MCSymbol
*LHSSym
= getSingleMCSymbol(BExpr
->getLHS());
1788 const MCSymbol
*RHSSym
= getSingleMCSymbol(BExpr
->getRHS());
1799 if (const MCUnaryExpr
*UExpr
= dyn_cast
<MCUnaryExpr
>(Expr
))
1800 return getSingleMCSymbol(UExpr
->getSubExpr());
1805 static unsigned countMCSymbolRefExpr(const MCExpr
*Expr
) {
1806 if (isa
<MCSymbolRefExpr
>(Expr
))
1809 if (const MCBinaryExpr
*BExpr
= dyn_cast
<MCBinaryExpr
>(Expr
))
1810 return countMCSymbolRefExpr(BExpr
->getLHS()) +
1811 countMCSymbolRefExpr(BExpr
->getRHS());
1813 if (const MCUnaryExpr
*UExpr
= dyn_cast
<MCUnaryExpr
>(Expr
))
1814 return countMCSymbolRefExpr(UExpr
->getSubExpr());
1819 static bool isEvaluated(const MCExpr
*Expr
) {
1820 switch (Expr
->getKind()) {
1821 case MCExpr::Constant
:
1823 case MCExpr::SymbolRef
:
1824 return (cast
<MCSymbolRefExpr
>(Expr
)->getKind() != MCSymbolRefExpr::VK_None
);
1825 case MCExpr::Binary
: {
1826 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Expr
);
1827 if (!isEvaluated(BE
->getLHS()))
1829 return isEvaluated(BE
->getRHS());
1832 return isEvaluated(cast
<MCUnaryExpr
>(Expr
)->getSubExpr());
1833 case MCExpr::Target
:
1839 static bool needsExpandMemInst(MCInst
&Inst
, const MCInstrDesc
&MCID
) {
1840 unsigned NumOp
= MCID
.getNumOperands();
1841 if (NumOp
!= 3 && NumOp
!= 4)
1844 const MCOperandInfo
&OpInfo
= MCID
.operands()[NumOp
- 1];
1845 if (OpInfo
.OperandType
!= MCOI::OPERAND_MEMORY
&&
1846 OpInfo
.OperandType
!= MCOI::OPERAND_UNKNOWN
&&
1847 OpInfo
.OperandType
!= MipsII::OPERAND_MEM_SIMM9
)
1850 MCOperand
&Op
= Inst
.getOperand(NumOp
- 1);
1852 if (OpInfo
.OperandType
== MipsII::OPERAND_MEM_SIMM9
)
1853 return !isInt
<9>(Op
.getImm());
1854 // Offset can't exceed 16bit value.
1855 return !isInt
<16>(Op
.getImm());
1859 const MCExpr
*Expr
= Op
.getExpr();
1860 if (Expr
->getKind() != MCExpr::SymbolRef
)
1861 return !isEvaluated(Expr
);
1864 const MCSymbolRefExpr
*SR
= static_cast<const MCSymbolRefExpr
*>(Expr
);
1865 return SR
->getKind() == MCSymbolRefExpr::VK_None
;
1871 bool MipsAsmParser::processInstruction(MCInst
&Inst
, SMLoc IDLoc
,
1873 const MCSubtargetInfo
*STI
) {
1874 MipsTargetStreamer
&TOut
= getTargetStreamer();
1875 const unsigned Opcode
= Inst
.getOpcode();
1876 const MCInstrDesc
&MCID
= MII
.get(Opcode
);
1877 bool ExpandedJalSym
= false;
1881 if (MCID
.isBranch() || MCID
.isCall()) {
1891 assert(hasCnMips() && "instruction only valid for octeon cpus");
1898 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
1899 Offset
= Inst
.getOperand(2);
1900 if (!Offset
.isImm())
1901 break; // We'll deal with this situation later on when applying fixups.
1902 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset
.getImm()))
1903 return Error(IDLoc
, "branch target out of range");
1904 if (offsetToAlignment(Offset
.getImm(),
1905 (inMicroMipsMode() ? Align(2) : Align(4))))
1906 return Error(IDLoc
, "branch to misaligned address");
1920 case Mips::BGEZAL_MM
:
1921 case Mips::BLTZAL_MM
:
1924 case Mips::BC1EQZC_MMR6
:
1925 case Mips::BC1NEZC_MMR6
:
1926 case Mips::BC2EQZC_MMR6
:
1927 case Mips::BC2NEZC_MMR6
:
1928 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1929 Offset
= Inst
.getOperand(1);
1930 if (!Offset
.isImm())
1931 break; // We'll deal with this situation later on when applying fixups.
1932 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset
.getImm()))
1933 return Error(IDLoc
, "branch target out of range");
1934 if (offsetToAlignment(Offset
.getImm(),
1935 (inMicroMipsMode() ? Align(2) : Align(4))))
1936 return Error(IDLoc
, "branch to misaligned address");
1938 case Mips::BGEC
: case Mips::BGEC_MMR6
:
1939 case Mips::BLTC
: case Mips::BLTC_MMR6
:
1940 case Mips::BGEUC
: case Mips::BGEUC_MMR6
:
1941 case Mips::BLTUC
: case Mips::BLTUC_MMR6
:
1942 case Mips::BEQC
: case Mips::BEQC_MMR6
:
1943 case Mips::BNEC
: case Mips::BNEC_MMR6
:
1944 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
1945 Offset
= Inst
.getOperand(2);
1946 if (!Offset
.isImm())
1947 break; // We'll deal with this situation later on when applying fixups.
1948 if (!isIntN(18, Offset
.getImm()))
1949 return Error(IDLoc
, "branch target out of range");
1950 if (offsetToAlignment(Offset
.getImm(), Align(4)))
1951 return Error(IDLoc
, "branch to misaligned address");
1953 case Mips::BLEZC
: case Mips::BLEZC_MMR6
:
1954 case Mips::BGEZC
: case Mips::BGEZC_MMR6
:
1955 case Mips::BGTZC
: case Mips::BGTZC_MMR6
:
1956 case Mips::BLTZC
: case Mips::BLTZC_MMR6
:
1957 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1958 Offset
= Inst
.getOperand(1);
1959 if (!Offset
.isImm())
1960 break; // We'll deal with this situation later on when applying fixups.
1961 if (!isIntN(18, Offset
.getImm()))
1962 return Error(IDLoc
, "branch target out of range");
1963 if (offsetToAlignment(Offset
.getImm(), Align(4)))
1964 return Error(IDLoc
, "branch to misaligned address");
1966 case Mips::BEQZC
: case Mips::BEQZC_MMR6
:
1967 case Mips::BNEZC
: case Mips::BNEZC_MMR6
:
1968 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1969 Offset
= Inst
.getOperand(1);
1970 if (!Offset
.isImm())
1971 break; // We'll deal with this situation later on when applying fixups.
1972 if (!isIntN(23, Offset
.getImm()))
1973 return Error(IDLoc
, "branch target out of range");
1974 if (offsetToAlignment(Offset
.getImm(), Align(4)))
1975 return Error(IDLoc
, "branch to misaligned address");
1977 case Mips::BEQZ16_MM
:
1978 case Mips::BEQZC16_MMR6
:
1979 case Mips::BNEZ16_MM
:
1980 case Mips::BNEZC16_MMR6
:
1981 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1982 Offset
= Inst
.getOperand(1);
1983 if (!Offset
.isImm())
1984 break; // We'll deal with this situation later on when applying fixups.
1985 if (!isInt
<8>(Offset
.getImm()))
1986 return Error(IDLoc
, "branch target out of range");
1987 if (offsetToAlignment(Offset
.getImm(), Align(2)))
1988 return Error(IDLoc
, "branch to misaligned address");
1993 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1994 // We still accept it but it is a normal nop.
1995 if (hasMips32r6() && Opcode
== Mips::SSNOP
) {
1996 std::string ISA
= hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1997 Warning(IDLoc
, "ssnop is deprecated for " + ISA
+ " and is equivalent to a "
2013 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
2014 // The offset is handled above
2015 Opnd
= Inst
.getOperand(1);
2017 return Error(IDLoc
, "expected immediate operand kind");
2018 Imm
= Opnd
.getImm();
2019 if (Imm
< 0 || Imm
> (Opcode
== Mips::BBIT0
||
2020 Opcode
== Mips::BBIT1
? 63 : 31))
2021 return Error(IDLoc
, "immediate operand value out of range");
2023 Inst
.setOpcode(Opcode
== Mips::BBIT0
? Mips::BBIT032
2025 Inst
.getOperand(1).setImm(Imm
- 32);
2031 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
2032 Opnd
= Inst
.getOperand(2);
2034 return Error(IDLoc
, "expected immediate operand kind");
2035 Imm
= Opnd
.getImm();
2036 if (!isInt
<10>(Imm
))
2037 return Error(IDLoc
, "immediate operand value out of range");
2042 // Warn on division by zero. We're checking here as all instructions get
2043 // processed here, not just the macros that need expansion.
2045 // The MIPS backend models most of the divison instructions and macros as
2046 // three operand instructions. The pre-R6 divide instructions however have
2047 // two operands and explicitly define HI/LO as part of the instruction,
2048 // not in the operands.
2049 unsigned FirstOp
= 1;
2050 unsigned SecondOp
= 2;
2054 case Mips::SDivIMacro
:
2055 case Mips::UDivIMacro
:
2056 case Mips::DSDivIMacro
:
2057 case Mips::DUDivIMacro
:
2058 if (Inst
.getOperand(2).getImm() == 0) {
2059 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
2060 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
2061 Warning(IDLoc
, "dividing zero by zero");
2063 Warning(IDLoc
, "division by zero");
2075 case Mips::SDivMacro
:
2076 case Mips::DSDivMacro
:
2077 case Mips::UDivMacro
:
2078 case Mips::DUDivMacro
:
2083 case Mips::DIVU_MMR6
:
2084 case Mips::DIV_MMR6
:
2085 if (Inst
.getOperand(SecondOp
).getReg() == Mips::ZERO
||
2086 Inst
.getOperand(SecondOp
).getReg() == Mips::ZERO_64
) {
2087 if (Inst
.getOperand(FirstOp
).getReg() == Mips::ZERO
||
2088 Inst
.getOperand(FirstOp
).getReg() == Mips::ZERO_64
)
2089 Warning(IDLoc
, "dividing zero by zero");
2091 Warning(IDLoc
, "division by zero");
2096 // For PIC code convert unconditional jump to unconditional branch.
2097 if ((Opcode
== Mips::J
|| Opcode
== Mips::J_MM
) && inPicMode()) {
2099 BInst
.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM
: Mips::BEQ
);
2100 BInst
.addOperand(MCOperand::createReg(Mips::ZERO
));
2101 BInst
.addOperand(MCOperand::createReg(Mips::ZERO
));
2102 BInst
.addOperand(Inst
.getOperand(0));
2106 // This expansion is not in a function called by tryExpandInstruction()
2107 // because the pseudo-instruction doesn't have a distinct opcode.
2108 if ((Opcode
== Mips::JAL
|| Opcode
== Mips::JAL_MM
) && inPicMode()) {
2109 warnIfNoMacro(IDLoc
);
2111 if (!Inst
.getOperand(0).isExpr()) {
2112 return Error(IDLoc
, "unsupported constant in relocation");
2115 const MCExpr
*JalExpr
= Inst
.getOperand(0).getExpr();
2117 // We can do this expansion if there's only 1 symbol in the argument
2119 if (countMCSymbolRefExpr(JalExpr
) > 1)
2120 return Error(IDLoc
, "jal doesn't support multiple symbols in PIC mode");
2122 // FIXME: This is checking the expression can be handled by the later stages
2123 // of the assembler. We ought to leave it to those later stages.
2124 const MCSymbol
*JalSym
= getSingleMCSymbol(JalExpr
);
2126 if (expandLoadAddress(Mips::T9
, Mips::NoRegister
, Inst
.getOperand(0),
2127 !isGP64bit(), IDLoc
, Out
, STI
))
2131 if (inMicroMipsMode())
2132 JalrInst
.setOpcode(IsCpRestoreSet
? Mips::JALRS_MM
: Mips::JALR_MM
);
2134 JalrInst
.setOpcode(Mips::JALR
);
2135 JalrInst
.addOperand(MCOperand::createReg(Mips::RA
));
2136 JalrInst
.addOperand(MCOperand::createReg(Mips::T9
));
2138 if (isJalrRelocAvailable(JalExpr
)) {
2139 // As an optimization hint for the linker, before the JALR we add:
2140 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2142 MCSymbol
*TmpLabel
= getContext().createTempSymbol();
2143 const MCExpr
*TmpExpr
= MCSymbolRefExpr::create(TmpLabel
, getContext());
2144 const MCExpr
*RelocJalrExpr
=
2145 MCSymbolRefExpr::create(JalSym
, MCSymbolRefExpr::VK_None
,
2146 getContext(), IDLoc
);
2148 TOut
.getStreamer().emitRelocDirective(
2149 *TmpExpr
, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2150 RelocJalrExpr
, IDLoc
, *STI
);
2151 TOut
.getStreamer().emitLabel(TmpLabel
);
2155 ExpandedJalSym
= true;
2158 if (MCID
.mayLoad() || MCID
.mayStore()) {
2159 // Check the offset of memory operand, if it is a symbol
2160 // reference or immediate we may have to expand instructions.
2161 if (needsExpandMemInst(Inst
, MCID
)) {
2162 switch (MCID
.operands()[MCID
.getNumOperands() - 1].OperandType
) {
2163 case MipsII::OPERAND_MEM_SIMM9
:
2164 expandMem9Inst(Inst
, IDLoc
, Out
, STI
, MCID
.mayLoad());
2167 expandMem16Inst(Inst
, IDLoc
, Out
, STI
, MCID
.mayLoad());
2170 return getParser().hasPendingError();
2174 if (inMicroMipsMode()) {
2175 if (MCID
.mayLoad() && Opcode
!= Mips::LWP_MM
) {
2176 // Try to create 16-bit GP relative load instruction.
2177 for (unsigned i
= 0; i
< MCID
.getNumOperands(); i
++) {
2178 const MCOperandInfo
&OpInfo
= MCID
.operands()[i
];
2179 if ((OpInfo
.OperandType
== MCOI::OPERAND_MEMORY
) ||
2180 (OpInfo
.OperandType
== MCOI::OPERAND_UNKNOWN
)) {
2181 MCOperand
&Op
= Inst
.getOperand(i
);
2183 int MemOffset
= Op
.getImm();
2184 MCOperand
&DstReg
= Inst
.getOperand(0);
2185 MCOperand
&BaseReg
= Inst
.getOperand(1);
2186 if (isInt
<9>(MemOffset
) && (MemOffset
% 4 == 0) &&
2187 getContext().getRegisterInfo()->getRegClass(
2188 Mips::GPRMM16RegClassID
).contains(DstReg
.getReg()) &&
2189 (BaseReg
.getReg() == Mips::GP
||
2190 BaseReg
.getReg() == Mips::GP_64
)) {
2192 TOut
.emitRRI(Mips::LWGP_MM
, DstReg
.getReg(), Mips::GP
, MemOffset
,
2201 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2209 case Mips::ADDIUSP_MM
:
2210 Opnd
= Inst
.getOperand(0);
2212 return Error(IDLoc
, "expected immediate operand kind");
2213 Imm
= Opnd
.getImm();
2214 if (Imm
< -1032 || Imm
> 1028 || (Imm
< 8 && Imm
> -12) ||
2216 return Error(IDLoc
, "immediate operand value out of range");
2218 case Mips::SLL16_MM
:
2219 case Mips::SRL16_MM
:
2220 Opnd
= Inst
.getOperand(2);
2222 return Error(IDLoc
, "expected immediate operand kind");
2223 Imm
= Opnd
.getImm();
2224 if (Imm
< 1 || Imm
> 8)
2225 return Error(IDLoc
, "immediate operand value out of range");
2228 Opnd
= Inst
.getOperand(1);
2230 return Error(IDLoc
, "expected immediate operand kind");
2231 Imm
= Opnd
.getImm();
2232 if (Imm
< -1 || Imm
> 126)
2233 return Error(IDLoc
, "immediate operand value out of range");
2235 case Mips::ADDIUR2_MM
:
2236 Opnd
= Inst
.getOperand(2);
2238 return Error(IDLoc
, "expected immediate operand kind");
2239 Imm
= Opnd
.getImm();
2240 if (!(Imm
== 1 || Imm
== -1 ||
2241 ((Imm
% 4 == 0) && Imm
< 28 && Imm
> 0)))
2242 return Error(IDLoc
, "immediate operand value out of range");
2244 case Mips::ANDI16_MM
:
2245 Opnd
= Inst
.getOperand(2);
2247 return Error(IDLoc
, "expected immediate operand kind");
2248 Imm
= Opnd
.getImm();
2249 if (!(Imm
== 128 || (Imm
>= 1 && Imm
<= 4) || Imm
== 7 || Imm
== 8 ||
2250 Imm
== 15 || Imm
== 16 || Imm
== 31 || Imm
== 32 || Imm
== 63 ||
2251 Imm
== 64 || Imm
== 255 || Imm
== 32768 || Imm
== 65535))
2252 return Error(IDLoc
, "immediate operand value out of range");
2254 case Mips::LBU16_MM
:
2255 Opnd
= Inst
.getOperand(2);
2257 return Error(IDLoc
, "expected immediate operand kind");
2258 Imm
= Opnd
.getImm();
2259 if (Imm
< -1 || Imm
> 14)
2260 return Error(IDLoc
, "immediate operand value out of range");
2263 case Mips::SB16_MMR6
:
2264 Opnd
= Inst
.getOperand(2);
2266 return Error(IDLoc
, "expected immediate operand kind");
2267 Imm
= Opnd
.getImm();
2268 if (Imm
< 0 || Imm
> 15)
2269 return Error(IDLoc
, "immediate operand value out of range");
2271 case Mips::LHU16_MM
:
2273 case Mips::SH16_MMR6
:
2274 Opnd
= Inst
.getOperand(2);
2276 return Error(IDLoc
, "expected immediate operand kind");
2277 Imm
= Opnd
.getImm();
2278 if (Imm
< 0 || Imm
> 30 || (Imm
% 2 != 0))
2279 return Error(IDLoc
, "immediate operand value out of range");
2283 case Mips::SW16_MMR6
:
2284 Opnd
= Inst
.getOperand(2);
2286 return Error(IDLoc
, "expected immediate operand kind");
2287 Imm
= Opnd
.getImm();
2288 if (Imm
< 0 || Imm
> 60 || (Imm
% 4 != 0))
2289 return Error(IDLoc
, "immediate operand value out of range");
2291 case Mips::ADDIUPC_MM
:
2292 Opnd
= Inst
.getOperand(1);
2294 return Error(IDLoc
, "expected immediate operand kind");
2295 Imm
= Opnd
.getImm();
2296 if ((Imm
% 4 != 0) || !isInt
<25>(Imm
))
2297 return Error(IDLoc
, "immediate operand value out of range");
2301 if (Inst
.getOperand(0).getReg() == Mips::RA
)
2302 return Error(IDLoc
, "invalid operand for instruction");
2304 case Mips::MOVEP_MM
:
2305 case Mips::MOVEP_MMR6
: {
2306 unsigned R0
= Inst
.getOperand(0).getReg();
2307 unsigned R1
= Inst
.getOperand(1).getReg();
2308 bool RegPair
= ((R0
== Mips::A1
&& R1
== Mips::A2
) ||
2309 (R0
== Mips::A1
&& R1
== Mips::A3
) ||
2310 (R0
== Mips::A2
&& R1
== Mips::A3
) ||
2311 (R0
== Mips::A0
&& R1
== Mips::S5
) ||
2312 (R0
== Mips::A0
&& R1
== Mips::S6
) ||
2313 (R0
== Mips::A0
&& R1
== Mips::A1
) ||
2314 (R0
== Mips::A0
&& R1
== Mips::A2
) ||
2315 (R0
== Mips::A0
&& R1
== Mips::A3
));
2317 return Error(IDLoc
, "invalid operand for instruction");
2323 bool FillDelaySlot
=
2324 MCID
.hasDelaySlot() && AssemblerOptions
.back()->isReorder();
2326 // Get previous instruction`s forbidden slot attribute and
2327 // whether set reorder.
2328 bool PrevForbiddenSlotAttr
= CurForbiddenSlotAttr
;
2330 // Flag represents we set reorder after nop.
2331 bool SetReorderAfterNop
= false;
2333 // If previous instruction has forbidden slot and .set reorder
2334 // is active and current instruction is CTI.
2335 // Then emit a NOP after it.
2336 if (PrevForbiddenSlotAttr
&& !SafeInForbiddenSlot(MCID
)) {
2337 TOut
.emitEmptyDelaySlot(false, IDLoc
, STI
);
2338 // When 'FillDelaySlot' is true, the existing logic will add
2339 // noreorder before instruction and reorder after it. So there
2340 // need exclude this case avoiding two '.set reorder'.
2341 // The format of the first case is:
2346 if (AssemblerOptions
.back()->isReorder() && !FillDelaySlot
) {
2347 SetReorderAfterNop
= true;
2348 TOut
.emitDirectiveSetReorder();
2352 // Save current instruction`s forbidden slot and whether set reorder.
2353 // This is the judgment condition for whether to add nop.
2354 // We would add a couple of '.set noreorder' and '.set reorder' to
2355 // wrap the current instruction and the next instruction.
2356 CurForbiddenSlotAttr
=
2357 hasForbiddenSlot(MCID
) && AssemblerOptions
.back()->isReorder();
2359 if (FillDelaySlot
|| CurForbiddenSlotAttr
)
2360 TOut
.emitDirectiveSetNoReorder();
2362 MacroExpanderResultTy ExpandResult
=
2363 tryExpandInstruction(Inst
, IDLoc
, Out
, STI
);
2364 switch (ExpandResult
) {
2366 Out
.emitInstruction(Inst
, *STI
);
2374 // When current instruction was not CTI, recover reorder state.
2375 // The format of the second case is:
2380 if (PrevForbiddenSlotAttr
&& !SetReorderAfterNop
&& !FillDelaySlot
&&
2381 AssemblerOptions
.back()->isReorder()) {
2382 TOut
.emitDirectiveSetReorder();
2385 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2386 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2387 if (inMicroMipsMode()) {
2388 TOut
.setUsesMicroMips();
2389 TOut
.updateABIInfo(*this);
2392 // If this instruction has a delay slot and .set reorder is active,
2393 // emit a NOP after it.
2394 // The format of the third case is:
2402 if (FillDelaySlot
) {
2403 TOut
.emitEmptyDelaySlot(hasShortDelaySlot(Inst
), IDLoc
, STI
);
2404 TOut
.emitDirectiveSetReorder();
2407 if ((Opcode
== Mips::JalOneReg
|| Opcode
== Mips::JalTwoReg
||
2409 isPicAndNotNxxAbi()) {
2410 if (IsCpRestoreSet
) {
2411 // We need a NOP between the JALR and the LW:
2412 // If .set reorder has been used, we've already emitted a NOP.
2413 // If .set noreorder has been used, we need to emit a NOP at this point.
2414 if (!AssemblerOptions
.back()->isReorder())
2415 TOut
.emitEmptyDelaySlot(hasShortDelaySlot(Inst
), IDLoc
,
2418 // Load the $gp from the stack.
2419 TOut
.emitGPRestore(CpRestoreOffset
, IDLoc
, STI
);
2421 Warning(IDLoc
, "no .cprestore used in PIC mode");
2427 void MipsAsmParser::onEndOfFile() {
2428 MipsTargetStreamer
&TOut
= getTargetStreamer();
2429 SMLoc IDLoc
= SMLoc();
2430 // If has pending forbidden slot, fill nop and recover reorder.
2431 if (CurForbiddenSlotAttr
) {
2432 TOut
.emitEmptyDelaySlot(false, IDLoc
, STI
);
2433 if (AssemblerOptions
.back()->isReorder())
2434 TOut
.emitDirectiveSetReorder();
2438 MipsAsmParser::MacroExpanderResultTy
2439 MipsAsmParser::tryExpandInstruction(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
2440 const MCSubtargetInfo
*STI
) {
2441 switch (Inst
.getOpcode()) {
2443 return MER_NotAMacro
;
2444 case Mips::LoadImm32
:
2445 return expandLoadImm(Inst
, true, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2446 case Mips::LoadImm64
:
2447 return expandLoadImm(Inst
, false, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2448 case Mips::LoadAddrImm32
:
2449 case Mips::LoadAddrImm64
:
2450 assert(Inst
.getOperand(0).isReg() && "expected register operand kind");
2451 assert((Inst
.getOperand(1).isImm() || Inst
.getOperand(1).isExpr()) &&
2452 "expected immediate operand kind");
2454 return expandLoadAddress(Inst
.getOperand(0).getReg(), Mips::NoRegister
,
2456 Inst
.getOpcode() == Mips::LoadAddrImm32
, IDLoc
,
2460 case Mips::LoadAddrReg32
:
2461 case Mips::LoadAddrReg64
:
2462 assert(Inst
.getOperand(0).isReg() && "expected register operand kind");
2463 assert(Inst
.getOperand(1).isReg() && "expected register operand kind");
2464 assert((Inst
.getOperand(2).isImm() || Inst
.getOperand(2).isExpr()) &&
2465 "expected immediate operand kind");
2467 return expandLoadAddress(Inst
.getOperand(0).getReg(),
2468 Inst
.getOperand(1).getReg(), Inst
.getOperand(2),
2469 Inst
.getOpcode() == Mips::LoadAddrReg32
, IDLoc
,
2473 case Mips::B_MM_Pseudo
:
2474 case Mips::B_MMR6_Pseudo
:
2475 return expandUncondBranchMMPseudo(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2479 return expandLoadStoreMultiple(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2481 case Mips::JalOneReg
:
2482 case Mips::JalTwoReg
:
2483 return expandJalWithRegs(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2486 case Mips::BEQLImmMacro
:
2487 case Mips::BNELImmMacro
:
2488 return expandBranchImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2505 case Mips::BLTImmMacro
:
2506 case Mips::BLEImmMacro
:
2507 case Mips::BGEImmMacro
:
2508 case Mips::BGTImmMacro
:
2509 case Mips::BLTUImmMacro
:
2510 case Mips::BLEUImmMacro
:
2511 case Mips::BGEUImmMacro
:
2512 case Mips::BGTUImmMacro
:
2513 case Mips::BLTLImmMacro
:
2514 case Mips::BLELImmMacro
:
2515 case Mips::BGELImmMacro
:
2516 case Mips::BGTLImmMacro
:
2517 case Mips::BLTULImmMacro
:
2518 case Mips::BLEULImmMacro
:
2519 case Mips::BGEULImmMacro
:
2520 case Mips::BGTULImmMacro
:
2521 return expandCondBranches(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2522 case Mips::SDivMacro
:
2523 case Mips::SDivIMacro
:
2524 case Mips::SRemMacro
:
2525 case Mips::SRemIMacro
:
2526 return expandDivRem(Inst
, IDLoc
, Out
, STI
, false, true) ? MER_Fail
2528 case Mips::DSDivMacro
:
2529 case Mips::DSDivIMacro
:
2530 case Mips::DSRemMacro
:
2531 case Mips::DSRemIMacro
:
2532 return expandDivRem(Inst
, IDLoc
, Out
, STI
, true, true) ? MER_Fail
2534 case Mips::UDivMacro
:
2535 case Mips::UDivIMacro
:
2536 case Mips::URemMacro
:
2537 case Mips::URemIMacro
:
2538 return expandDivRem(Inst
, IDLoc
, Out
, STI
, false, false) ? MER_Fail
2540 case Mips::DUDivMacro
:
2541 case Mips::DUDivIMacro
:
2542 case Mips::DURemMacro
:
2543 case Mips::DURemIMacro
:
2544 return expandDivRem(Inst
, IDLoc
, Out
, STI
, true, false) ? MER_Fail
2546 case Mips::PseudoTRUNC_W_S
:
2547 return expandTrunc(Inst
, false, false, IDLoc
, Out
, STI
) ? MER_Fail
2549 case Mips::PseudoTRUNC_W_D32
:
2550 return expandTrunc(Inst
, true, false, IDLoc
, Out
, STI
) ? MER_Fail
2552 case Mips::PseudoTRUNC_W_D
:
2553 return expandTrunc(Inst
, true, true, IDLoc
, Out
, STI
) ? MER_Fail
2556 case Mips::LoadImmSingleGPR
:
2557 return expandLoadSingleImmToGPR(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2559 case Mips::LoadImmSingleFGR
:
2560 return expandLoadSingleImmToFPR(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2562 case Mips::LoadImmDoubleGPR
:
2563 return expandLoadDoubleImmToGPR(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2565 case Mips::LoadImmDoubleFGR
:
2566 return expandLoadDoubleImmToFPR(Inst
, true, IDLoc
, Out
, STI
) ? MER_Fail
2568 case Mips::LoadImmDoubleFGR_32
:
2569 return expandLoadDoubleImmToFPR(Inst
, false, IDLoc
, Out
, STI
) ? MER_Fail
2573 return expandUlh(Inst
, true, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2575 return expandUlh(Inst
, false, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2577 return expandUsh(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2580 return expandUxw(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2582 case Mips::NORImm64
:
2583 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2586 return expandSge(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2589 case Mips::SGEImm64
:
2590 case Mips::SGEUImm64
:
2591 return expandSgeImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2594 case Mips::SGTImm64
:
2595 case Mips::SGTUImm64
:
2596 return expandSgtImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2599 return expandSle(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2602 case Mips::SLEImm64
:
2603 case Mips::SLEUImm64
:
2604 return expandSleImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2605 case Mips::SLTImm64
:
2606 if (isInt
<16>(Inst
.getOperand(2).getImm())) {
2607 Inst
.setOpcode(Mips::SLTi64
);
2608 return MER_NotAMacro
;
2610 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2611 case Mips::SLTUImm64
:
2612 if (isInt
<16>(Inst
.getOperand(2).getImm())) {
2613 Inst
.setOpcode(Mips::SLTiu64
);
2614 return MER_NotAMacro
;
2616 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2617 case Mips::ADDi
: case Mips::ADDi_MM
:
2618 case Mips::ADDiu
: case Mips::ADDiu_MM
:
2619 case Mips::SLTi
: case Mips::SLTi_MM
:
2620 case Mips::SLTiu
: case Mips::SLTiu_MM
:
2621 if ((Inst
.getNumOperands() == 3) && Inst
.getOperand(0).isReg() &&
2622 Inst
.getOperand(1).isReg() && Inst
.getOperand(2).isImm()) {
2623 int64_t ImmValue
= Inst
.getOperand(2).getImm();
2624 if (isInt
<16>(ImmValue
))
2625 return MER_NotAMacro
;
2626 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2629 return MER_NotAMacro
;
2630 case Mips::ANDi
: case Mips::ANDi_MM
: case Mips::ANDi64
:
2631 case Mips::ORi
: case Mips::ORi_MM
: case Mips::ORi64
:
2632 case Mips::XORi
: case Mips::XORi_MM
: case Mips::XORi64
:
2633 if ((Inst
.getNumOperands() == 3) && Inst
.getOperand(0).isReg() &&
2634 Inst
.getOperand(1).isReg() && Inst
.getOperand(2).isImm()) {
2635 int64_t ImmValue
= Inst
.getOperand(2).getImm();
2636 if (isUInt
<16>(ImmValue
))
2637 return MER_NotAMacro
;
2638 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2641 return MER_NotAMacro
;
2644 return expandRotation(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2647 return expandRotationImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2650 return expandDRotation(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2653 return expandDRotationImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2654 case Mips::ABSMacro
:
2655 return expandAbs(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2656 case Mips::MULImmMacro
:
2657 case Mips::DMULImmMacro
:
2658 return expandMulImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2659 case Mips::MULOMacro
:
2660 case Mips::DMULOMacro
:
2661 return expandMulO(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2662 case Mips::MULOUMacro
:
2663 case Mips::DMULOUMacro
:
2664 return expandMulOU(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2665 case Mips::DMULMacro
:
2666 return expandDMULMacro(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2669 return expandLoadStoreDMacro(Inst
, IDLoc
, Out
, STI
,
2670 Inst
.getOpcode() == Mips::LDMacro
)
2674 return expandStoreDM1Macro(Inst
, IDLoc
, Out
, STI
)
2677 case Mips::SEQMacro
:
2678 return expandSeq(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2679 case Mips::SEQIMacro
:
2680 return expandSeqI(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2681 case Mips::SNEMacro
:
2682 return expandSne(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2683 case Mips::SNEIMacro
:
2684 return expandSneI(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2685 case Mips::MFTC0
: case Mips::MTTC0
:
2686 case Mips::MFTGPR
: case Mips::MTTGPR
:
2687 case Mips::MFTLO
: case Mips::MTTLO
:
2688 case Mips::MFTHI
: case Mips::MTTHI
:
2689 case Mips::MFTACX
: case Mips::MTTACX
:
2690 case Mips::MFTDSP
: case Mips::MTTDSP
:
2691 case Mips::MFTC1
: case Mips::MTTC1
:
2692 case Mips::MFTHC1
: case Mips::MTTHC1
:
2693 case Mips::CFTC1
: case Mips::CTTC1
:
2694 return expandMXTRAlias(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2696 case Mips::SaadAddr
:
2697 return expandSaaAddr(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2701 bool MipsAsmParser::expandJalWithRegs(MCInst
&Inst
, SMLoc IDLoc
,
2703 const MCSubtargetInfo
*STI
) {
2704 MipsTargetStreamer
&TOut
= getTargetStreamer();
2706 // Create a JALR instruction which is going to replace the pseudo-JAL.
2708 JalrInst
.setLoc(IDLoc
);
2709 const MCOperand FirstRegOp
= Inst
.getOperand(0);
2710 const unsigned Opcode
= Inst
.getOpcode();
2712 if (Opcode
== Mips::JalOneReg
) {
2713 // jal $rs => jalr $rs
2714 if (IsCpRestoreSet
&& inMicroMipsMode()) {
2715 JalrInst
.setOpcode(Mips::JALRS16_MM
);
2716 JalrInst
.addOperand(FirstRegOp
);
2717 } else if (inMicroMipsMode()) {
2718 JalrInst
.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6
: Mips::JALR16_MM
);
2719 JalrInst
.addOperand(FirstRegOp
);
2721 JalrInst
.setOpcode(Mips::JALR
);
2722 JalrInst
.addOperand(MCOperand::createReg(Mips::RA
));
2723 JalrInst
.addOperand(FirstRegOp
);
2725 } else if (Opcode
== Mips::JalTwoReg
) {
2726 // jal $rd, $rs => jalr $rd, $rs
2727 if (IsCpRestoreSet
&& inMicroMipsMode())
2728 JalrInst
.setOpcode(Mips::JALRS_MM
);
2730 JalrInst
.setOpcode(inMicroMipsMode() ? Mips::JALR_MM
: Mips::JALR
);
2731 JalrInst
.addOperand(FirstRegOp
);
2732 const MCOperand SecondRegOp
= Inst
.getOperand(1);
2733 JalrInst
.addOperand(SecondRegOp
);
2735 Out
.emitInstruction(JalrInst
, *STI
);
2737 // If .set reorder is active and branch instruction has a delay slot,
2738 // emit a NOP after it.
2739 const MCInstrDesc
&MCID
= MII
.get(JalrInst
.getOpcode());
2740 if (MCID
.hasDelaySlot() && AssemblerOptions
.back()->isReorder())
2741 TOut
.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst
), IDLoc
,
2747 /// Can the value be represented by a unsigned N-bit value and a shift left?
2748 template <unsigned N
> static bool isShiftedUIntAtAnyPosition(uint64_t x
) {
2749 return x
&& isUInt
<N
>(x
>> llvm::countr_zero(x
));
2752 /// Load (or add) an immediate into a register.
2754 /// @param ImmValue The immediate to load.
2755 /// @param DstReg The register that will hold the immediate.
2756 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2757 /// for a simple initialization.
2758 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2759 /// @param IsAddress True if the immediate represents an address. False if it
2761 /// @param IDLoc Location of the immediate in the source file.
2762 bool MipsAsmParser::loadImmediate(int64_t ImmValue
, unsigned DstReg
,
2763 unsigned SrcReg
, bool Is32BitImm
,
2764 bool IsAddress
, SMLoc IDLoc
, MCStreamer
&Out
,
2765 const MCSubtargetInfo
*STI
) {
2766 MipsTargetStreamer
&TOut
= getTargetStreamer();
2768 if (!Is32BitImm
&& !isGP64bit()) {
2769 Error(IDLoc
, "instruction requires a 64-bit architecture");
2774 if (isInt
<32>(ImmValue
) || isUInt
<32>(ImmValue
)) {
2775 // Sign extend up to 64-bit so that the predicates match the hardware
2776 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2778 ImmValue
= SignExtend64
<32>(ImmValue
);
2780 Error(IDLoc
, "instruction requires a 32-bit immediate");
2785 unsigned ZeroReg
= IsAddress
? ABI
.GetNullPtr() : ABI
.GetZeroReg();
2786 unsigned AdduOp
= !Is32BitImm
? Mips::DADDu
: Mips::ADDu
;
2788 bool UseSrcReg
= false;
2789 if (SrcReg
!= Mips::NoRegister
)
2792 unsigned TmpReg
= DstReg
;
2794 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, SrcReg
)) {
2795 // At this point we need AT to perform the expansions and we exit if it is
2797 unsigned ATReg
= getATReg(IDLoc
);
2803 if (isInt
<16>(ImmValue
)) {
2807 // This doesn't quite follow the usual ABI expectations for N32 but matches
2808 // traditional assembler behaviour. N32 would normally use addiu for both
2809 // integers and addresses.
2810 if (IsAddress
&& !Is32BitImm
) {
2811 TOut
.emitRRI(Mips::DADDiu
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
2815 TOut
.emitRRI(Mips::ADDiu
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
2819 if (isUInt
<16>(ImmValue
)) {
2820 unsigned TmpReg
= DstReg
;
2821 if (SrcReg
== DstReg
) {
2822 TmpReg
= getATReg(IDLoc
);
2827 TOut
.emitRRI(Mips::ORi
, TmpReg
, ZeroReg
, ImmValue
, IDLoc
, STI
);
2829 TOut
.emitRRR(ABI
.GetPtrAdduOp(), DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2833 if (isInt
<32>(ImmValue
) || isUInt
<32>(ImmValue
)) {
2834 warnIfNoMacro(IDLoc
);
2836 uint16_t Bits31To16
= (ImmValue
>> 16) & 0xffff;
2837 uint16_t Bits15To0
= ImmValue
& 0xffff;
2838 if (!Is32BitImm
&& !isInt
<32>(ImmValue
)) {
2839 // Traditional behaviour seems to special case this particular value. It's
2840 // not clear why other masks are handled differently.
2841 if (ImmValue
== 0xffffffff) {
2842 TOut
.emitRI(Mips::LUi
, TmpReg
, 0xffff, IDLoc
, STI
);
2843 TOut
.emitRRI(Mips::DSRL32
, TmpReg
, TmpReg
, 0, IDLoc
, STI
);
2845 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2849 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2851 TOut
.emitRRI(Mips::ORi
, TmpReg
, ZeroReg
, Bits31To16
, IDLoc
, STI
);
2852 TOut
.emitRRI(Mips::DSLL
, TmpReg
, TmpReg
, 16, IDLoc
, STI
);
2854 TOut
.emitRRI(Mips::ORi
, TmpReg
, TmpReg
, Bits15To0
, IDLoc
, STI
);
2856 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2860 TOut
.emitRI(Mips::LUi
, TmpReg
, Bits31To16
, IDLoc
, STI
);
2862 TOut
.emitRRI(Mips::ORi
, TmpReg
, TmpReg
, Bits15To0
, IDLoc
, STI
);
2864 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2868 if (isShiftedUIntAtAnyPosition
<16>(ImmValue
)) {
2870 Error(IDLoc
, "instruction requires a 32-bit immediate");
2874 // We've processed ImmValue satisfying isUInt<16> above, so ImmValue must be
2875 // at least 17-bit wide here.
2876 unsigned BitWidth
= llvm::bit_width((uint64_t)ImmValue
);
2877 assert(BitWidth
>= 17 && "ImmValue must be at least 17-bit wide");
2879 // Traditionally, these immediates are shifted as little as possible and as
2880 // such we align the most significant bit to bit 15 of our temporary.
2881 unsigned ShiftAmount
= BitWidth
- 16;
2882 uint16_t Bits
= (ImmValue
>> ShiftAmount
) & 0xffff;
2883 TOut
.emitRRI(Mips::ORi
, TmpReg
, ZeroReg
, Bits
, IDLoc
, STI
);
2884 TOut
.emitRRI(Mips::DSLL
, TmpReg
, TmpReg
, ShiftAmount
, IDLoc
, STI
);
2887 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2892 warnIfNoMacro(IDLoc
);
2894 // The remaining case is packed with a sequence of dsll and ori with zeros
2895 // being omitted and any neighbouring dsll's being coalesced.
2896 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2898 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2899 if (loadImmediate(ImmValue
>> 32, TmpReg
, Mips::NoRegister
, true, false,
2903 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2904 // skip it and defer the shift to the next chunk.
2905 unsigned ShiftCarriedForwards
= 16;
2906 for (int BitNum
= 16; BitNum
>= 0; BitNum
-= 16) {
2907 uint16_t ImmChunk
= (ImmValue
>> BitNum
) & 0xffff;
2909 if (ImmChunk
!= 0) {
2910 TOut
.emitDSLL(TmpReg
, TmpReg
, ShiftCarriedForwards
, IDLoc
, STI
);
2911 TOut
.emitRRI(Mips::ORi
, TmpReg
, TmpReg
, ImmChunk
, IDLoc
, STI
);
2912 ShiftCarriedForwards
= 0;
2915 ShiftCarriedForwards
+= 16;
2917 ShiftCarriedForwards
-= 16;
2919 // Finish any remaining shifts left by trailing zeros.
2920 if (ShiftCarriedForwards
)
2921 TOut
.emitDSLL(TmpReg
, TmpReg
, ShiftCarriedForwards
, IDLoc
, STI
);
2924 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2929 bool MipsAsmParser::expandLoadImm(MCInst
&Inst
, bool Is32BitImm
, SMLoc IDLoc
,
2930 MCStreamer
&Out
, const MCSubtargetInfo
*STI
) {
2931 const MCOperand
&ImmOp
= Inst
.getOperand(1);
2932 assert(ImmOp
.isImm() && "expected immediate operand kind");
2933 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
2934 assert(DstRegOp
.isReg() && "expected register operand kind");
2936 if (loadImmediate(ImmOp
.getImm(), DstRegOp
.getReg(), Mips::NoRegister
,
2937 Is32BitImm
, false, IDLoc
, Out
, STI
))
2943 bool MipsAsmParser::expandLoadAddress(unsigned DstReg
, unsigned BaseReg
,
2944 const MCOperand
&Offset
,
2945 bool Is32BitAddress
, SMLoc IDLoc
,
2947 const MCSubtargetInfo
*STI
) {
2948 // la can't produce a usable address when addresses are 64-bit.
2949 if (Is32BitAddress
&& ABI
.ArePtrs64bit()) {
2950 Warning(IDLoc
, "la used to load 64-bit address");
2951 // Continue as if we had 'dla' instead.
2952 Is32BitAddress
= false;
2955 // dla requires 64-bit addresses.
2956 if (!Is32BitAddress
&& !hasMips3()) {
2957 Error(IDLoc
, "instruction requires a 64-bit architecture");
2961 if (!Offset
.isImm())
2962 return loadAndAddSymbolAddress(Offset
.getExpr(), DstReg
, BaseReg
,
2963 Is32BitAddress
, IDLoc
, Out
, STI
);
2965 if (!ABI
.ArePtrs64bit()) {
2966 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2967 Is32BitAddress
= true;
2970 return loadImmediate(Offset
.getImm(), DstReg
, BaseReg
, Is32BitAddress
, true,
2974 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr
*SymExpr
,
2975 unsigned DstReg
, unsigned SrcReg
,
2976 bool Is32BitSym
, SMLoc IDLoc
,
2978 const MCSubtargetInfo
*STI
) {
2979 MipsTargetStreamer
&TOut
= getTargetStreamer();
2980 bool UseSrcReg
= SrcReg
!= Mips::NoRegister
&& SrcReg
!= Mips::ZERO
&&
2981 SrcReg
!= Mips::ZERO_64
;
2982 warnIfNoMacro(IDLoc
);
2986 if (!SymExpr
->evaluateAsRelocatable(Res
, nullptr, nullptr)) {
2987 Error(IDLoc
, "expected relocatable expression");
2990 if (Res
.getSymB() != nullptr) {
2991 Error(IDLoc
, "expected relocatable expression with only one symbol");
2995 bool IsPtr64
= ABI
.ArePtrs64bit();
2997 Res
.getSymA()->getSymbol().isInSection() ||
2998 Res
.getSymA()->getSymbol().isTemporary() ||
2999 (Res
.getSymA()->getSymbol().isELF() &&
3000 cast
<MCSymbolELF
>(Res
.getSymA()->getSymbol()).getBinding() ==
3002 // For O32, "$"-prefixed symbols are recognized as temporary while
3003 // .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
3005 if (ABI
.IsO32() && Res
.getSymA()->getSymbol().getName().starts_with(".L"))
3007 bool UseXGOT
= STI
->hasFeature(Mips::FeatureXGOT
) && !IsLocalSym
;
3009 // The case where the result register is $25 is somewhat special. If the
3010 // symbol in the final relocation is external and not modified with a
3011 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
3012 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
3013 if ((DstReg
== Mips::T9
|| DstReg
== Mips::T9_64
) && !UseSrcReg
&&
3014 Res
.getConstant() == 0 && !IsLocalSym
) {
3016 const MCExpr
*CallHiExpr
= MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16
,
3017 SymExpr
, getContext());
3018 const MCExpr
*CallLoExpr
= MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16
,
3019 SymExpr
, getContext());
3020 TOut
.emitRX(Mips::LUi
, DstReg
, MCOperand::createExpr(CallHiExpr
), IDLoc
,
3022 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, DstReg
, DstReg
, GPReg
,
3024 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, DstReg
, DstReg
,
3025 MCOperand::createExpr(CallLoExpr
), IDLoc
, STI
);
3027 const MCExpr
*CallExpr
=
3028 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL
, SymExpr
, getContext());
3029 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, DstReg
, GPReg
,
3030 MCOperand::createExpr(CallExpr
), IDLoc
, STI
);
3035 unsigned TmpReg
= DstReg
;
3037 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
,
3039 // If $rs is the same as $rd, we need to use AT.
3040 // If it is not available we exit.
3041 unsigned ATReg
= getATReg(IDLoc
);
3047 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
3048 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
3049 // FIXME: Implement XGOT for microMIPS.
3051 // Loading address from XGOT
3052 // External GOT: lui $tmp, %got_hi(symbol)($gp)
3053 // addu $tmp, $tmp, $gp
3054 // lw $tmp, %got_lo(symbol)($tmp)
3055 // >addiu $tmp, $tmp, offset
3056 // >addiu $rd, $tmp, $rs
3057 // The addiu's marked with a '>' may be omitted if they are redundant. If
3058 // this happens then the last instruction must use $rd as the result
3060 const MCExpr
*CallHiExpr
=
3061 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16
, SymExpr
, getContext());
3062 const MCExpr
*CallLoExpr
= MipsMCExpr::create(
3063 MipsMCExpr::MEK_GOT_LO16
, Res
.getSymA(), getContext());
3065 TOut
.emitRX(Mips::LUi
, TmpReg
, MCOperand::createExpr(CallHiExpr
), IDLoc
,
3067 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, TmpReg
, TmpReg
, GPReg
,
3069 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, TmpReg
, TmpReg
,
3070 MCOperand::createExpr(CallLoExpr
), IDLoc
, STI
);
3072 if (Res
.getConstant() != 0)
3073 TOut
.emitRRX(IsPtr64
? Mips::DADDiu
: Mips::ADDiu
, TmpReg
, TmpReg
,
3074 MCOperand::createExpr(MCConstantExpr::create(
3075 Res
.getConstant(), getContext())),
3079 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, DstReg
, TmpReg
, SrcReg
,
3084 const MipsMCExpr
*GotExpr
= nullptr;
3085 const MCExpr
*LoExpr
= nullptr;
3086 if (ABI
.IsN32() || ABI
.IsN64()) {
3087 // The remaining cases are:
3088 // Small offset: ld $tmp, %got_disp(symbol)($gp)
3089 // >daddiu $tmp, $tmp, offset
3090 // >daddu $rd, $tmp, $rs
3091 // The daddiu's marked with a '>' may be omitted if they are redundant. If
3092 // this happens then the last instruction must use $rd as the result
3094 GotExpr
= MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP
, Res
.getSymA(),
3096 if (Res
.getConstant() != 0) {
3097 // Symbols fully resolve with just the %got_disp(symbol) but we
3098 // must still account for any offset to the symbol for
3099 // expressions like symbol+8.
3100 LoExpr
= MCConstantExpr::create(Res
.getConstant(), getContext());
3102 // FIXME: Offsets greater than 16 bits are not yet implemented.
3103 // FIXME: The correct range is a 32-bit sign-extended number.
3104 if (Res
.getConstant() < -0x8000 || Res
.getConstant() > 0x7fff) {
3105 Error(IDLoc
, "macro instruction uses large offset, which is not "
3106 "currently supported");
3111 // The remaining cases are:
3112 // External GOT: lw $tmp, %got(symbol)($gp)
3113 // >addiu $tmp, $tmp, offset
3114 // >addiu $rd, $tmp, $rs
3115 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3116 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3117 // >addiu $rd, $tmp, $rs
3118 // The addiu's marked with a '>' may be omitted if they are redundant. If
3119 // this happens then the last instruction must use $rd as the result
3123 MipsMCExpr::create(MipsMCExpr::MEK_GOT
, SymExpr
, getContext());
3124 LoExpr
= MipsMCExpr::create(MipsMCExpr::MEK_LO
, SymExpr
, getContext());
3126 // External symbols fully resolve the symbol with just the %got(symbol)
3127 // but we must still account for any offset to the symbol for
3128 // expressions like symbol+8.
3129 GotExpr
= MipsMCExpr::create(MipsMCExpr::MEK_GOT
, Res
.getSymA(),
3131 if (Res
.getConstant() != 0)
3132 LoExpr
= MCConstantExpr::create(Res
.getConstant(), getContext());
3136 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, TmpReg
, GPReg
,
3137 MCOperand::createExpr(GotExpr
), IDLoc
, STI
);
3140 TOut
.emitRRX(IsPtr64
? Mips::DADDiu
: Mips::ADDiu
, TmpReg
, TmpReg
,
3141 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3144 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, DstReg
, TmpReg
, SrcReg
,
3150 const MipsMCExpr
*HiExpr
=
3151 MipsMCExpr::create(MipsMCExpr::MEK_HI
, SymExpr
, getContext());
3152 const MipsMCExpr
*LoExpr
=
3153 MipsMCExpr::create(MipsMCExpr::MEK_LO
, SymExpr
, getContext());
3155 // This is the 64-bit symbol address expansion.
3156 if (ABI
.ArePtrs64bit() && isGP64bit()) {
3157 // We need AT for the 64-bit expansion in the cases where the optional
3158 // source register is the destination register and for the superscalar
3161 // If it is not available we exit if the destination is the same as the
3164 const MipsMCExpr
*HighestExpr
=
3165 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST
, SymExpr
, getContext());
3166 const MipsMCExpr
*HigherExpr
=
3167 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER
, SymExpr
, getContext());
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, SrcReg
);
3173 if (canUseATReg() && UseSrcReg
&& RdRegIsRsReg
) {
3174 unsigned ATReg
= getATReg(IDLoc
);
3176 // If $rs is the same as $rd:
3177 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3178 // daddiu $at, $at, %higher(sym)
3179 // dsll $at, $at, 16
3180 // daddiu $at, $at, %hi(sym)
3181 // dsll $at, $at, 16
3182 // daddiu $at, $at, %lo(sym)
3183 // daddu $rd, $at, $rd
3184 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3186 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
,
3187 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3188 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3189 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(HiExpr
),
3191 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3192 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(LoExpr
),
3194 TOut
.emitRRR(Mips::DADDu
, DstReg
, ATReg
, SrcReg
, IDLoc
, STI
);
3197 } else if (canUseATReg() && !RdRegIsRsReg
&& DstReg
!= getATReg(IDLoc
)) {
3198 unsigned ATReg
= getATReg(IDLoc
);
3200 // If the $rs is different from $rd or if $rs isn't specified and we
3201 // have $at available:
3202 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3203 // lui $at, %hi(sym)
3204 // daddiu $rd, $rd, %higher(sym)
3205 // daddiu $at, $at, %lo(sym)
3206 // dsll32 $rd, $rd, 0
3207 // daddu $rd, $rd, $at
3208 // (daddu $rd, $rd, $rs)
3210 // Which is preferred for superscalar issue.
3211 TOut
.emitRX(Mips::LUi
, DstReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3213 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3214 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3215 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3216 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(LoExpr
),
3218 TOut
.emitRRI(Mips::DSLL32
, DstReg
, DstReg
, 0, IDLoc
, STI
);
3219 TOut
.emitRRR(Mips::DADDu
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
3221 TOut
.emitRRR(Mips::DADDu
, DstReg
, DstReg
, SrcReg
, IDLoc
, STI
);
3224 } else if ((!canUseATReg() && !RdRegIsRsReg
) ||
3225 (canUseATReg() && DstReg
== getATReg(IDLoc
))) {
3226 // Otherwise, synthesize the address in the destination register
3228 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3229 // daddiu $rd, $rd, %higher(sym)
3230 // dsll $rd, $rd, 16
3231 // daddiu $rd, $rd, %hi(sym)
3232 // dsll $rd, $rd, 16
3233 // daddiu $rd, $rd, %lo(sym)
3234 TOut
.emitRX(Mips::LUi
, DstReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3236 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3237 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3238 TOut
.emitRRI(Mips::DSLL
, DstReg
, DstReg
, 16, IDLoc
, STI
);
3239 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3240 MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3241 TOut
.emitRRI(Mips::DSLL
, DstReg
, DstReg
, 16, IDLoc
, STI
);
3242 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3243 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3245 TOut
.emitRRR(Mips::DADDu
, DstReg
, DstReg
, SrcReg
, IDLoc
, STI
);
3249 // We have a case where SrcReg == DstReg and we don't have $at
3250 // available. We can't expand this case, so error out appropriately.
3251 assert(SrcReg
== DstReg
&& !canUseATReg() &&
3252 "Could have expanded dla but didn't?");
3253 reportParseError(IDLoc
,
3254 "pseudo-instruction requires $at, which is not available");
3259 // And now, the 32-bit symbol address expansion:
3260 // If $rs is the same as $rd:
3261 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3262 // ori $at, $at, %lo(sym)
3263 // addu $rd, $at, $rd
3264 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3265 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3266 // ori $rd, $rd, %lo(sym)
3267 // (addu $rd, $rd, $rs)
3268 unsigned TmpReg
= DstReg
;
3270 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, SrcReg
)) {
3271 // If $rs is the same as $rd, we need to use AT.
3272 // If it is not available we exit.
3273 unsigned ATReg
= getATReg(IDLoc
);
3279 TOut
.emitRX(Mips::LUi
, TmpReg
, MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3280 TOut
.emitRRX(Mips::ADDiu
, TmpReg
, TmpReg
, MCOperand::createExpr(LoExpr
),
3284 TOut
.emitRRR(Mips::ADDu
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
3287 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg
));
3292 // Each double-precision register DO-D15 overlaps with two of the single
3293 // precision registers F0-F31. As an example, all of the following hold true:
3294 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3295 static unsigned nextReg(unsigned Reg
) {
3296 if (MipsMCRegisterClasses
[Mips::FGR32RegClassID
].contains(Reg
))
3297 return Reg
== (unsigned)Mips::F31
? (unsigned)Mips::F0
: Reg
+ 1;
3299 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3300 case Mips::ZERO
: return Mips::AT
;
3301 case Mips::AT
: return Mips::V0
;
3302 case Mips::V0
: return Mips::V1
;
3303 case Mips::V1
: return Mips::A0
;
3304 case Mips::A0
: return Mips::A1
;
3305 case Mips::A1
: return Mips::A2
;
3306 case Mips::A2
: return Mips::A3
;
3307 case Mips::A3
: return Mips::T0
;
3308 case Mips::T0
: return Mips::T1
;
3309 case Mips::T1
: return Mips::T2
;
3310 case Mips::T2
: return Mips::T3
;
3311 case Mips::T3
: return Mips::T4
;
3312 case Mips::T4
: return Mips::T5
;
3313 case Mips::T5
: return Mips::T6
;
3314 case Mips::T6
: return Mips::T7
;
3315 case Mips::T7
: return Mips::S0
;
3316 case Mips::S0
: return Mips::S1
;
3317 case Mips::S1
: return Mips::S2
;
3318 case Mips::S2
: return Mips::S3
;
3319 case Mips::S3
: return Mips::S4
;
3320 case Mips::S4
: return Mips::S5
;
3321 case Mips::S5
: return Mips::S6
;
3322 case Mips::S6
: return Mips::S7
;
3323 case Mips::S7
: return Mips::T8
;
3324 case Mips::T8
: return Mips::T9
;
3325 case Mips::T9
: return Mips::K0
;
3326 case Mips::K0
: return Mips::K1
;
3327 case Mips::K1
: return Mips::GP
;
3328 case Mips::GP
: return Mips::SP
;
3329 case Mips::SP
: return Mips::FP
;
3330 case Mips::FP
: return Mips::RA
;
3331 case Mips::RA
: return Mips::ZERO
;
3332 case Mips::D0
: return Mips::F1
;
3333 case Mips::D1
: return Mips::F3
;
3334 case Mips::D2
: return Mips::F5
;
3335 case Mips::D3
: return Mips::F7
;
3336 case Mips::D4
: return Mips::F9
;
3337 case Mips::D5
: return Mips::F11
;
3338 case Mips::D6
: return Mips::F13
;
3339 case Mips::D7
: return Mips::F15
;
3340 case Mips::D8
: return Mips::F17
;
3341 case Mips::D9
: return Mips::F19
;
3342 case Mips::D10
: return Mips::F21
;
3343 case Mips::D11
: return Mips::F23
;
3344 case Mips::D12
: return Mips::F25
;
3345 case Mips::D13
: return Mips::F27
;
3346 case Mips::D14
: return Mips::F29
;
3347 case Mips::D15
: return Mips::F31
;
3351 // FIXME: This method is too general. In principle we should compute the number
3352 // of instructions required to synthesize the immediate inline compared to
3353 // synthesizing the address inline and relying on non .text sections.
3354 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3355 // likely to yield a much larger benefit as we have to synthesize a 64bit
3356 // address to load a 64 bit value.
3357 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer
&TOut
, SMLoc IDLoc
,
3359 unsigned ATReg
= getATReg(IDLoc
);
3364 const MCExpr
*GotSym
=
3365 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3366 const MipsMCExpr
*GotExpr
=
3367 MipsMCExpr::create(MipsMCExpr::MEK_GOT
, GotSym
, getContext());
3369 if(isABI_O32() || isABI_N32()) {
3370 TOut
.emitRRX(Mips::LW
, ATReg
, GPReg
, MCOperand::createExpr(GotExpr
),
3372 } else { //isABI_N64()
3373 TOut
.emitRRX(Mips::LD
, ATReg
, GPReg
, MCOperand::createExpr(GotExpr
),
3376 } else { //!IsPicEnabled
3377 const MCExpr
*HiSym
=
3378 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3379 const MipsMCExpr
*HiExpr
=
3380 MipsMCExpr::create(MipsMCExpr::MEK_HI
, HiSym
, getContext());
3382 // FIXME: This is technically correct but gives a different result to gas,
3383 // but gas is incomplete there (it has a fixme noting it doesn't work with
3384 // 64-bit addresses).
3385 // FIXME: With -msym32 option, the address expansion for N64 should probably
3386 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3387 // symbol's value is considered sign extended.
3388 if(isABI_O32() || isABI_N32()) {
3389 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3390 } else { //isABI_N64()
3391 const MCExpr
*HighestSym
=
3392 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3393 const MipsMCExpr
*HighestExpr
=
3394 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST
, HighestSym
, getContext());
3395 const MCExpr
*HigherSym
=
3396 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3397 const MipsMCExpr
*HigherExpr
=
3398 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER
, HigherSym
, getContext());
3400 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3402 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
,
3403 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3404 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3405 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(HiExpr
),
3407 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3413 static uint64_t convertIntToDoubleImm(uint64_t ImmOp64
) {
3414 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3415 // exponent field), convert it to double (e.g. 1 to 1.0)
3416 if ((Hi_32(ImmOp64
) & 0x7ff00000) == 0) {
3417 APFloat
RealVal(APFloat::IEEEdouble(), ImmOp64
);
3418 ImmOp64
= RealVal
.bitcastToAPInt().getZExtValue();
3423 static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64
) {
3424 // Conversion of a double in an uint64_t to a float in a uint32_t,
3425 // retaining the bit pattern of a float.
3426 double DoubleImm
= llvm::bit_cast
<double>(ImmOp64
);
3427 float TmpFloat
= static_cast<float>(DoubleImm
);
3428 return llvm::bit_cast
<uint32_t>(TmpFloat
);
3431 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
,
3433 const MCSubtargetInfo
*STI
) {
3434 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3435 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3436 "Invalid instruction operand.");
3438 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3439 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3441 uint32_t ImmOp32
= covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64
));
3443 return loadImmediate(ImmOp32
, FirstReg
, Mips::NoRegister
, true, false, IDLoc
,
3447 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst
&Inst
, SMLoc IDLoc
,
3449 const MCSubtargetInfo
*STI
) {
3450 MipsTargetStreamer
&TOut
= getTargetStreamer();
3451 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3452 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3453 "Invalid instruction operand.");
3455 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3456 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3458 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3460 uint32_t ImmOp32
= covertDoubleImmToSingleImm(ImmOp64
);
3462 unsigned TmpReg
= Mips::ZERO
;
3464 TmpReg
= getATReg(IDLoc
);
3469 if (Lo_32(ImmOp64
) == 0) {
3470 if (TmpReg
!= Mips::ZERO
&& loadImmediate(ImmOp32
, TmpReg
, Mips::NoRegister
,
3471 true, false, IDLoc
, Out
, STI
))
3473 TOut
.emitRR(Mips::MTC1
, FirstReg
, TmpReg
, IDLoc
, STI
);
3477 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3478 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3479 // where appropriate.
3480 MCSection
*ReadOnlySection
=
3481 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3483 MCSymbol
*Sym
= getContext().createTempSymbol();
3484 const MCExpr
*LoSym
=
3485 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3486 const MipsMCExpr
*LoExpr
=
3487 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3489 getStreamer().switchSection(ReadOnlySection
);
3490 getStreamer().emitLabel(Sym
, IDLoc
);
3491 getStreamer().emitInt32(ImmOp32
);
3492 getStreamer().switchSection(CS
);
3494 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3496 TOut
.emitRRX(Mips::LWC1
, FirstReg
, TmpReg
, MCOperand::createExpr(LoExpr
),
3501 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
,
3503 const MCSubtargetInfo
*STI
) {
3504 MipsTargetStreamer
&TOut
= getTargetStreamer();
3505 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3506 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3507 "Invalid instruction operand.");
3509 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3510 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3512 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3514 if (Lo_32(ImmOp64
) == 0) {
3516 if (loadImmediate(ImmOp64
, FirstReg
, Mips::NoRegister
, false, false,
3520 if (loadImmediate(Hi_32(ImmOp64
), FirstReg
, Mips::NoRegister
, true, false,
3524 if (loadImmediate(0, nextReg(FirstReg
), Mips::NoRegister
, true, false,
3531 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3532 MCSection
*ReadOnlySection
=
3533 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3535 MCSymbol
*Sym
= getContext().createTempSymbol();
3536 const MCExpr
*LoSym
=
3537 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3538 const MipsMCExpr
*LoExpr
=
3539 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3541 getStreamer().switchSection(ReadOnlySection
);
3542 getStreamer().emitLabel(Sym
, IDLoc
);
3543 getStreamer().emitValueToAlignment(Align(8));
3544 getStreamer().emitIntValue(ImmOp64
, 8);
3545 getStreamer().switchSection(CS
);
3547 unsigned TmpReg
= getATReg(IDLoc
);
3551 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3554 TOut
.emitRRX(isABI_N64() ? Mips::DADDiu
: Mips::ADDiu
, TmpReg
, TmpReg
,
3555 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3558 TOut
.emitRRI(Mips::LD
, FirstReg
, TmpReg
, 0, IDLoc
, STI
);
3560 TOut
.emitRRI(Mips::LW
, FirstReg
, TmpReg
, 0, IDLoc
, STI
);
3561 TOut
.emitRRI(Mips::LW
, nextReg(FirstReg
), TmpReg
, 4, IDLoc
, STI
);
3566 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst
&Inst
, bool Is64FPU
,
3567 SMLoc IDLoc
, MCStreamer
&Out
,
3568 const MCSubtargetInfo
*STI
) {
3569 MipsTargetStreamer
&TOut
= getTargetStreamer();
3570 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3571 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3572 "Invalid instruction operand.");
3574 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3575 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3577 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3579 unsigned TmpReg
= Mips::ZERO
;
3581 TmpReg
= getATReg(IDLoc
);
3586 if ((Lo_32(ImmOp64
) == 0) &&
3587 !((Hi_32(ImmOp64
) & 0xffff0000) && (Hi_32(ImmOp64
) & 0x0000ffff))) {
3589 if (TmpReg
!= Mips::ZERO
&&
3590 loadImmediate(ImmOp64
, TmpReg
, Mips::NoRegister
, false, false, IDLoc
,
3593 TOut
.emitRR(Mips::DMTC1
, FirstReg
, TmpReg
, IDLoc
, STI
);
3597 if (TmpReg
!= Mips::ZERO
&&
3598 loadImmediate(Hi_32(ImmOp64
), TmpReg
, Mips::NoRegister
, true, false,
3602 if (hasMips32r2()) {
3603 TOut
.emitRR(Mips::MTC1
, FirstReg
, Mips::ZERO
, IDLoc
, STI
);
3604 TOut
.emitRRR(Mips::MTHC1_D32
, FirstReg
, FirstReg
, TmpReg
, IDLoc
, STI
);
3606 TOut
.emitRR(Mips::MTC1
, nextReg(FirstReg
), TmpReg
, IDLoc
, STI
);
3607 TOut
.emitRR(Mips::MTC1
, FirstReg
, Mips::ZERO
, IDLoc
, STI
);
3612 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3613 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3614 // where appropriate.
3615 MCSection
*ReadOnlySection
=
3616 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3618 MCSymbol
*Sym
= getContext().createTempSymbol();
3619 const MCExpr
*LoSym
=
3620 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3621 const MipsMCExpr
*LoExpr
=
3622 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3624 getStreamer().switchSection(ReadOnlySection
);
3625 getStreamer().emitLabel(Sym
, IDLoc
);
3626 getStreamer().emitValueToAlignment(Align(8));
3627 getStreamer().emitIntValue(ImmOp64
, 8);
3628 getStreamer().switchSection(CS
);
3630 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3633 TOut
.emitRRX(Is64FPU
? Mips::LDC164
: Mips::LDC1
, FirstReg
, TmpReg
,
3634 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3639 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst
&Inst
, SMLoc IDLoc
,
3641 const MCSubtargetInfo
*STI
) {
3642 MipsTargetStreamer
&TOut
= getTargetStreamer();
3644 assert(MII
.get(Inst
.getOpcode()).getNumOperands() == 1 &&
3645 "unexpected number of operands");
3647 MCOperand Offset
= Inst
.getOperand(0);
3648 if (Offset
.isExpr()) {
3650 Inst
.setOpcode(Mips::BEQ_MM
);
3651 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3652 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3653 Inst
.addOperand(MCOperand::createExpr(Offset
.getExpr()));
3655 assert(Offset
.isImm() && "expected immediate operand kind");
3656 if (isInt
<11>(Offset
.getImm())) {
3657 // If offset fits into 11 bits then this instruction becomes microMIPS
3658 // 16-bit unconditional branch instruction.
3659 if (inMicroMipsMode())
3660 Inst
.setOpcode(hasMips32r6() ? Mips::BC16_MMR6
: Mips::B16_MM
);
3662 if (!isInt
<17>(Offset
.getImm()))
3663 return Error(IDLoc
, "branch target out of range");
3664 if (offsetToAlignment(Offset
.getImm(), Align(2)))
3665 return Error(IDLoc
, "branch to misaligned address");
3667 Inst
.setOpcode(Mips::BEQ_MM
);
3668 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3669 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3670 Inst
.addOperand(MCOperand::createImm(Offset
.getImm()));
3673 Out
.emitInstruction(Inst
, *STI
);
3675 // If .set reorder is active and branch instruction has a delay slot,
3676 // emit a NOP after it.
3677 const MCInstrDesc
&MCID
= MII
.get(Inst
.getOpcode());
3678 if (MCID
.hasDelaySlot() && AssemblerOptions
.back()->isReorder())
3679 TOut
.emitEmptyDelaySlot(true, IDLoc
, STI
);
3684 bool MipsAsmParser::expandBranchImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
3685 const MCSubtargetInfo
*STI
) {
3686 MipsTargetStreamer
&TOut
= getTargetStreamer();
3687 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
3688 assert(DstRegOp
.isReg() && "expected register operand kind");
3690 const MCOperand
&ImmOp
= Inst
.getOperand(1);
3691 assert(ImmOp
.isImm() && "expected immediate operand kind");
3693 const MCOperand
&MemOffsetOp
= Inst
.getOperand(2);
3694 assert((MemOffsetOp
.isImm() || MemOffsetOp
.isExpr()) &&
3695 "expected immediate or expression operand");
3697 bool IsLikely
= false;
3699 unsigned OpCode
= 0;
3700 switch(Inst
.getOpcode()) {
3707 case Mips::BEQLImmMacro
:
3708 OpCode
= Mips::BEQL
;
3711 case Mips::BNELImmMacro
:
3712 OpCode
= Mips::BNEL
;
3716 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3720 int64_t ImmValue
= ImmOp
.getImm();
3721 if (ImmValue
== 0) {
3723 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), Mips::ZERO
,
3724 MCOperand::createExpr(MemOffsetOp
.getExpr()), IDLoc
, STI
);
3725 TOut
.emitRRI(Mips::SLL
, Mips::ZERO
, Mips::ZERO
, 0, IDLoc
, STI
);
3727 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), Mips::ZERO
, MemOffsetOp
, IDLoc
,
3730 warnIfNoMacro(IDLoc
);
3732 unsigned ATReg
= getATReg(IDLoc
);
3736 if (loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, !isGP64bit(), true,
3741 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), ATReg
,
3742 MCOperand::createExpr(MemOffsetOp
.getExpr()), IDLoc
, STI
);
3743 TOut
.emitRRI(Mips::SLL
, Mips::ZERO
, Mips::ZERO
, 0, IDLoc
, STI
);
3745 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), ATReg
, MemOffsetOp
, IDLoc
, STI
);
3750 void MipsAsmParser::expandMem16Inst(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
3751 const MCSubtargetInfo
*STI
, bool IsLoad
) {
3752 unsigned NumOp
= Inst
.getNumOperands();
3753 assert((NumOp
== 3 || NumOp
== 4) && "unexpected operands number");
3754 unsigned StartOp
= NumOp
== 3 ? 0 : 1;
3756 const MCOperand
&DstRegOp
= Inst
.getOperand(StartOp
);
3757 assert(DstRegOp
.isReg() && "expected register operand kind");
3758 const MCOperand
&BaseRegOp
= Inst
.getOperand(StartOp
+ 1);
3759 assert(BaseRegOp
.isReg() && "expected register operand kind");
3760 const MCOperand
&OffsetOp
= Inst
.getOperand(StartOp
+ 2);
3762 MipsTargetStreamer
&TOut
= getTargetStreamer();
3763 unsigned OpCode
= Inst
.getOpcode();
3764 unsigned DstReg
= DstRegOp
.getReg();
3765 unsigned BaseReg
= BaseRegOp
.getReg();
3766 unsigned TmpReg
= DstReg
;
3768 const MCInstrDesc
&Desc
= MII
.get(OpCode
);
3769 int16_t DstRegClass
= Desc
.operands()[StartOp
].RegClass
;
3770 unsigned DstRegClassID
=
3771 getContext().getRegisterInfo()->getRegClass(DstRegClass
).getID();
3772 bool IsGPR
= (DstRegClassID
== Mips::GPR32RegClassID
) ||
3773 (DstRegClassID
== Mips::GPR64RegClassID
);
3775 if (!IsLoad
|| !IsGPR
|| (BaseReg
== DstReg
)) {
3776 // At this point we need AT to perform the expansions
3777 // and we exit if it is not available.
3778 TmpReg
= getATReg(IDLoc
);
3783 auto emitInstWithOffset
= [&](const MCOperand
&Off
) {
3785 TOut
.emitRRX(OpCode
, DstReg
, TmpReg
, Off
, IDLoc
, STI
);
3787 TOut
.emitRRRX(OpCode
, DstReg
, DstReg
, TmpReg
, Off
, IDLoc
, STI
);
3790 if (OffsetOp
.isImm()) {
3791 int64_t LoOffset
= OffsetOp
.getImm() & 0xffff;
3792 int64_t HiOffset
= OffsetOp
.getImm() & ~0xffff;
3794 // If msb of LoOffset is 1(negative number) we must increment
3795 // HiOffset to account for the sign-extension of the low part.
3796 if (LoOffset
& 0x8000)
3797 HiOffset
+= 0x10000;
3799 bool IsLargeOffset
= HiOffset
!= 0;
3801 if (IsLargeOffset
) {
3802 bool Is32BitImm
= isInt
<32>(OffsetOp
.getImm());
3803 if (loadImmediate(HiOffset
, TmpReg
, Mips::NoRegister
, Is32BitImm
, true,
3808 if (BaseReg
!= Mips::ZERO
&& BaseReg
!= Mips::ZERO_64
)
3809 TOut
.emitRRR(ABI
.ArePtrs64bit() ? Mips::DADDu
: Mips::ADDu
, TmpReg
,
3810 TmpReg
, BaseReg
, IDLoc
, STI
);
3811 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset
)));
3815 if (OffsetOp
.isExpr()) {
3818 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3819 // do not exceed 16-bit.
3820 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3821 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3824 if (!OffsetOp
.getExpr()->evaluateAsRelocatable(Res
, nullptr, nullptr)) {
3825 Error(IDLoc
, "expected relocatable expression");
3828 if (Res
.getSymB() != nullptr) {
3829 Error(IDLoc
, "expected relocatable expression with only one symbol");
3833 loadAndAddSymbolAddress(Res
.getSymA(), TmpReg
, BaseReg
,
3834 !ABI
.ArePtrs64bit(), IDLoc
, Out
, STI
);
3835 emitInstWithOffset(MCOperand::createImm(int16_t(Res
.getConstant())));
3837 // FIXME: Implement 64-bit case.
3838 // 1) lw $8, sym => lui $8, %hi(sym)
3839 // lw $8, %lo(sym)($8)
3840 // 2) sw $8, sym => lui $at, %hi(sym)
3841 // sw $8, %lo(sym)($at)
3842 const MCExpr
*OffExpr
= OffsetOp
.getExpr();
3843 MCOperand LoOperand
= MCOperand::createExpr(
3844 MipsMCExpr::create(MipsMCExpr::MEK_LO
, OffExpr
, getContext()));
3845 MCOperand HiOperand
= MCOperand::createExpr(
3846 MipsMCExpr::create(MipsMCExpr::MEK_HI
, OffExpr
, getContext()));
3849 MCOperand HighestOperand
= MCOperand::createExpr(
3850 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST
, OffExpr
, getContext()));
3851 MCOperand HigherOperand
= MCOperand::createExpr(
3852 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER
, OffExpr
, getContext()));
3854 TOut
.emitRX(Mips::LUi
, TmpReg
, HighestOperand
, IDLoc
, STI
);
3855 TOut
.emitRRX(Mips::DADDiu
, TmpReg
, TmpReg
, HigherOperand
, IDLoc
, STI
);
3856 TOut
.emitRRI(Mips::DSLL
, TmpReg
, TmpReg
, 16, IDLoc
, STI
);
3857 TOut
.emitRRX(Mips::DADDiu
, TmpReg
, TmpReg
, HiOperand
, IDLoc
, STI
);
3858 TOut
.emitRRI(Mips::DSLL
, TmpReg
, TmpReg
, 16, IDLoc
, STI
);
3859 if (BaseReg
!= Mips::ZERO
&& BaseReg
!= Mips::ZERO_64
)
3860 TOut
.emitRRR(Mips::DADDu
, TmpReg
, TmpReg
, BaseReg
, IDLoc
, STI
);
3861 emitInstWithOffset(LoOperand
);
3863 // Generate the base address in TmpReg.
3864 TOut
.emitRX(Mips::LUi
, TmpReg
, HiOperand
, IDLoc
, STI
);
3865 if (BaseReg
!= Mips::ZERO
)
3866 TOut
.emitRRR(Mips::ADDu
, TmpReg
, TmpReg
, BaseReg
, IDLoc
, STI
);
3867 // Emit the load or store with the adjusted base and offset.
3868 emitInstWithOffset(LoOperand
);
3874 llvm_unreachable("unexpected operand type");
3877 void MipsAsmParser::expandMem9Inst(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
3878 const MCSubtargetInfo
*STI
, bool IsLoad
) {
3879 unsigned NumOp
= Inst
.getNumOperands();
3880 assert((NumOp
== 3 || NumOp
== 4) && "unexpected operands number");
3881 unsigned StartOp
= NumOp
== 3 ? 0 : 1;
3883 const MCOperand
&DstRegOp
= Inst
.getOperand(StartOp
);
3884 assert(DstRegOp
.isReg() && "expected register operand kind");
3885 const MCOperand
&BaseRegOp
= Inst
.getOperand(StartOp
+ 1);
3886 assert(BaseRegOp
.isReg() && "expected register operand kind");
3887 const MCOperand
&OffsetOp
= Inst
.getOperand(StartOp
+ 2);
3889 MipsTargetStreamer
&TOut
= getTargetStreamer();
3890 unsigned OpCode
= Inst
.getOpcode();
3891 unsigned DstReg
= DstRegOp
.getReg();
3892 unsigned BaseReg
= BaseRegOp
.getReg();
3893 unsigned TmpReg
= DstReg
;
3895 const MCInstrDesc
&Desc
= MII
.get(OpCode
);
3896 int16_t DstRegClass
= Desc
.operands()[StartOp
].RegClass
;
3897 unsigned DstRegClassID
=
3898 getContext().getRegisterInfo()->getRegClass(DstRegClass
).getID();
3899 bool IsGPR
= (DstRegClassID
== Mips::GPR32RegClassID
) ||
3900 (DstRegClassID
== Mips::GPR64RegClassID
);
3902 if (!IsLoad
|| !IsGPR
|| (BaseReg
== DstReg
)) {
3903 // At this point we need AT to perform the expansions
3904 // and we exit if it is not available.
3905 TmpReg
= getATReg(IDLoc
);
3910 auto emitInst
= [&]() {
3912 TOut
.emitRRX(OpCode
, DstReg
, TmpReg
, MCOperand::createImm(0), IDLoc
, STI
);
3914 TOut
.emitRRRX(OpCode
, DstReg
, DstReg
, TmpReg
, MCOperand::createImm(0),
3918 if (OffsetOp
.isImm()) {
3919 loadImmediate(OffsetOp
.getImm(), TmpReg
, BaseReg
, !ABI
.ArePtrs64bit(), true,
3925 if (OffsetOp
.isExpr()) {
3926 loadAndAddSymbolAddress(OffsetOp
.getExpr(), TmpReg
, BaseReg
,
3927 !ABI
.ArePtrs64bit(), IDLoc
, Out
, STI
);
3932 llvm_unreachable("unexpected operand type");
3935 bool MipsAsmParser::expandLoadStoreMultiple(MCInst
&Inst
, SMLoc IDLoc
,
3937 const MCSubtargetInfo
*STI
) {
3938 unsigned OpNum
= Inst
.getNumOperands();
3939 unsigned Opcode
= Inst
.getOpcode();
3940 unsigned NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM32_MM
: Mips::LWM32_MM
;
3942 assert(Inst
.getOperand(OpNum
- 1).isImm() &&
3943 Inst
.getOperand(OpNum
- 2).isReg() &&
3944 Inst
.getOperand(OpNum
- 3).isReg() && "Invalid instruction operand.");
3946 if (OpNum
< 8 && Inst
.getOperand(OpNum
- 1).getImm() <= 60 &&
3947 Inst
.getOperand(OpNum
- 1).getImm() >= 0 &&
3948 (Inst
.getOperand(OpNum
- 2).getReg() == Mips::SP
||
3949 Inst
.getOperand(OpNum
- 2).getReg() == Mips::SP_64
) &&
3950 (Inst
.getOperand(OpNum
- 3).getReg() == Mips::RA
||
3951 Inst
.getOperand(OpNum
- 3).getReg() == Mips::RA_64
)) {
3952 // It can be implemented as SWM16 or LWM16 instruction.
3953 if (inMicroMipsMode() && hasMips32r6())
3954 NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM16_MMR6
: Mips::LWM16_MMR6
;
3956 NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM16_MM
: Mips::LWM16_MM
;
3959 Inst
.setOpcode(NewOpcode
);
3960 Out
.emitInstruction(Inst
, *STI
);
3964 bool MipsAsmParser::expandCondBranches(MCInst
&Inst
, SMLoc IDLoc
,
3966 const MCSubtargetInfo
*STI
) {
3967 MipsTargetStreamer
&TOut
= getTargetStreamer();
3968 bool EmittedNoMacroWarning
= false;
3969 unsigned PseudoOpcode
= Inst
.getOpcode();
3970 unsigned SrcReg
= Inst
.getOperand(0).getReg();
3971 const MCOperand
&TrgOp
= Inst
.getOperand(1);
3972 const MCExpr
*OffsetExpr
= Inst
.getOperand(2).getExpr();
3974 unsigned ZeroSrcOpcode
, ZeroTrgOpcode
;
3975 bool ReverseOrderSLT
, IsUnsigned
, IsLikely
, AcceptsEquality
;
3979 TrgReg
= TrgOp
.getReg();
3980 else if (TrgOp
.isImm()) {
3981 warnIfNoMacro(IDLoc
);
3982 EmittedNoMacroWarning
= true;
3984 TrgReg
= getATReg(IDLoc
);
3988 switch(PseudoOpcode
) {
3990 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3991 case Mips::BLTImmMacro
:
3992 PseudoOpcode
= Mips::BLT
;
3994 case Mips::BLEImmMacro
:
3995 PseudoOpcode
= Mips::BLE
;
3997 case Mips::BGEImmMacro
:
3998 PseudoOpcode
= Mips::BGE
;
4000 case Mips::BGTImmMacro
:
4001 PseudoOpcode
= Mips::BGT
;
4003 case Mips::BLTUImmMacro
:
4004 PseudoOpcode
= Mips::BLTU
;
4006 case Mips::BLEUImmMacro
:
4007 PseudoOpcode
= Mips::BLEU
;
4009 case Mips::BGEUImmMacro
:
4010 PseudoOpcode
= Mips::BGEU
;
4012 case Mips::BGTUImmMacro
:
4013 PseudoOpcode
= Mips::BGTU
;
4015 case Mips::BLTLImmMacro
:
4016 PseudoOpcode
= Mips::BLTL
;
4018 case Mips::BLELImmMacro
:
4019 PseudoOpcode
= Mips::BLEL
;
4021 case Mips::BGELImmMacro
:
4022 PseudoOpcode
= Mips::BGEL
;
4024 case Mips::BGTLImmMacro
:
4025 PseudoOpcode
= Mips::BGTL
;
4027 case Mips::BLTULImmMacro
:
4028 PseudoOpcode
= Mips::BLTUL
;
4030 case Mips::BLEULImmMacro
:
4031 PseudoOpcode
= Mips::BLEUL
;
4033 case Mips::BGEULImmMacro
:
4034 PseudoOpcode
= Mips::BGEUL
;
4036 case Mips::BGTULImmMacro
:
4037 PseudoOpcode
= Mips::BGTUL
;
4041 if (loadImmediate(TrgOp
.getImm(), TrgReg
, Mips::NoRegister
, !isGP64bit(),
4042 false, IDLoc
, Out
, STI
))
4046 switch (PseudoOpcode
) {
4051 AcceptsEquality
= false;
4052 ReverseOrderSLT
= false;
4054 ((PseudoOpcode
== Mips::BLTU
) || (PseudoOpcode
== Mips::BLTUL
));
4055 IsLikely
= ((PseudoOpcode
== Mips::BLTL
) || (PseudoOpcode
== Mips::BLTUL
));
4056 ZeroSrcOpcode
= Mips::BGTZ
;
4057 ZeroTrgOpcode
= Mips::BLTZ
;
4063 AcceptsEquality
= true;
4064 ReverseOrderSLT
= true;
4066 ((PseudoOpcode
== Mips::BLEU
) || (PseudoOpcode
== Mips::BLEUL
));
4067 IsLikely
= ((PseudoOpcode
== Mips::BLEL
) || (PseudoOpcode
== Mips::BLEUL
));
4068 ZeroSrcOpcode
= Mips::BGEZ
;
4069 ZeroTrgOpcode
= Mips::BLEZ
;
4075 AcceptsEquality
= true;
4076 ReverseOrderSLT
= false;
4078 ((PseudoOpcode
== Mips::BGEU
) || (PseudoOpcode
== Mips::BGEUL
));
4079 IsLikely
= ((PseudoOpcode
== Mips::BGEL
) || (PseudoOpcode
== Mips::BGEUL
));
4080 ZeroSrcOpcode
= Mips::BLEZ
;
4081 ZeroTrgOpcode
= Mips::BGEZ
;
4087 AcceptsEquality
= false;
4088 ReverseOrderSLT
= true;
4090 ((PseudoOpcode
== Mips::BGTU
) || (PseudoOpcode
== Mips::BGTUL
));
4091 IsLikely
= ((PseudoOpcode
== Mips::BGTL
) || (PseudoOpcode
== Mips::BGTUL
));
4092 ZeroSrcOpcode
= Mips::BLTZ
;
4093 ZeroTrgOpcode
= Mips::BGTZ
;
4096 llvm_unreachable("unknown opcode for branch pseudo-instruction");
4099 bool IsTrgRegZero
= (TrgReg
== Mips::ZERO
);
4100 bool IsSrcRegZero
= (SrcReg
== Mips::ZERO
);
4101 if (IsSrcRegZero
&& IsTrgRegZero
) {
4102 // FIXME: All of these Opcode-specific if's are needed for compatibility
4103 // with GAS' behaviour. However, they may not generate the most efficient
4104 // code in some circumstances.
4105 if (PseudoOpcode
== Mips::BLT
) {
4106 TOut
.emitRX(Mips::BLTZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
4110 if (PseudoOpcode
== Mips::BLE
) {
4111 TOut
.emitRX(Mips::BLEZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
4113 Warning(IDLoc
, "branch is always taken");
4116 if (PseudoOpcode
== Mips::BGE
) {
4117 TOut
.emitRX(Mips::BGEZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
4119 Warning(IDLoc
, "branch is always taken");
4122 if (PseudoOpcode
== Mips::BGT
) {
4123 TOut
.emitRX(Mips::BGTZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
4127 if (PseudoOpcode
== Mips::BGTU
) {
4128 TOut
.emitRRX(Mips::BNE
, Mips::ZERO
, Mips::ZERO
,
4129 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4132 if (AcceptsEquality
) {
4133 // If both registers are $0 and the pseudo-branch accepts equality, it
4134 // will always be taken, so we emit an unconditional branch.
4135 TOut
.emitRRX(Mips::BEQ
, Mips::ZERO
, Mips::ZERO
,
4136 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4137 Warning(IDLoc
, "branch is always taken");
4140 // If both registers are $0 and the pseudo-branch does not accept
4141 // equality, it will never be taken, so we don't have to emit anything.
4144 if (IsSrcRegZero
|| IsTrgRegZero
) {
4145 if ((IsSrcRegZero
&& PseudoOpcode
== Mips::BGTU
) ||
4146 (IsTrgRegZero
&& PseudoOpcode
== Mips::BLTU
)) {
4147 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4148 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4149 // the pseudo-branch will never be taken, so we don't emit anything.
4150 // This only applies to unsigned pseudo-branches.
4153 if ((IsSrcRegZero
&& PseudoOpcode
== Mips::BLEU
) ||
4154 (IsTrgRegZero
&& PseudoOpcode
== Mips::BGEU
)) {
4155 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4156 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4157 // the pseudo-branch will always be taken, so we emit an unconditional
4159 // This only applies to unsigned pseudo-branches.
4160 TOut
.emitRRX(Mips::BEQ
, Mips::ZERO
, Mips::ZERO
,
4161 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4162 Warning(IDLoc
, "branch is always taken");
4166 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4167 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4168 // the pseudo-branch will be taken only when the non-zero register is
4169 // different from 0, so we emit a BNEZ.
4171 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4172 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4173 // the pseudo-branch will be taken only when the non-zero register is
4174 // equal to 0, so we emit a BEQZ.
4176 // Because only BLEU and BGEU branch on equality, we can use the
4177 // AcceptsEquality variable to decide when to emit the BEQZ.
4178 TOut
.emitRRX(AcceptsEquality
? Mips::BEQ
: Mips::BNE
,
4179 IsSrcRegZero
? TrgReg
: SrcReg
, Mips::ZERO
,
4180 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4183 // If we have a signed pseudo-branch and one of the registers is $0,
4184 // we can use an appropriate compare-to-zero branch. We select which one
4185 // to use in the switch statement above.
4186 TOut
.emitRX(IsSrcRegZero
? ZeroSrcOpcode
: ZeroTrgOpcode
,
4187 IsSrcRegZero
? TrgReg
: SrcReg
,
4188 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4192 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4193 // expansions. If it is not available, we return.
4194 unsigned ATRegNum
= getATReg(IDLoc
);
4198 if (!EmittedNoMacroWarning
)
4199 warnIfNoMacro(IDLoc
);
4201 // SLT fits well with 2 of our 4 pseudo-branches:
4202 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4203 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4204 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4205 // This is accomplished by using a BNEZ with the result of the SLT.
4207 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4208 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4209 // Because only BGE and BLE branch on equality, we can use the
4210 // AcceptsEquality variable to decide when to emit the BEQZ.
4211 // Note that the order of the SLT arguments doesn't change between
4214 // The same applies to the unsigned variants, except that SLTu is used
4216 TOut
.emitRRR(IsUnsigned
? Mips::SLTu
: Mips::SLT
, ATRegNum
,
4217 ReverseOrderSLT
? TrgReg
: SrcReg
,
4218 ReverseOrderSLT
? SrcReg
: TrgReg
, IDLoc
, STI
);
4220 TOut
.emitRRX(IsLikely
? (AcceptsEquality
? Mips::BEQL
: Mips::BNEL
)
4221 : (AcceptsEquality
? Mips::BEQ
: Mips::BNE
),
4222 ATRegNum
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
), IDLoc
,
4227 // Expand a integer division macro.
4229 // Notably we don't have to emit a warning when encountering $rt as the $zero
4230 // register, or 0 as an immediate. processInstruction() has already done that.
4232 // The destination register can only be $zero when expanding (S)DivIMacro or
4235 bool MipsAsmParser::expandDivRem(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4236 const MCSubtargetInfo
*STI
,
4237 const bool IsMips64
, const bool Signed
) {
4238 MipsTargetStreamer
&TOut
= getTargetStreamer();
4240 warnIfNoMacro(IDLoc
);
4242 const MCOperand
&RdRegOp
= Inst
.getOperand(0);
4243 assert(RdRegOp
.isReg() && "expected register operand kind");
4244 unsigned RdReg
= RdRegOp
.getReg();
4246 const MCOperand
&RsRegOp
= Inst
.getOperand(1);
4247 assert(RsRegOp
.isReg() && "expected register operand kind");
4248 unsigned RsReg
= RsRegOp
.getReg();
4253 const MCOperand
&RtOp
= Inst
.getOperand(2);
4254 assert((RtOp
.isReg() || RtOp
.isImm()) &&
4255 "expected register or immediate operand kind");
4257 RtReg
= RtOp
.getReg();
4259 ImmValue
= RtOp
.getImm();
4266 DivOp
= Signed
? Mips::DSDIV
: Mips::DUDIV
;
4267 ZeroReg
= Mips::ZERO_64
;
4270 DivOp
= Signed
? Mips::SDIV
: Mips::UDIV
;
4271 ZeroReg
= Mips::ZERO
;
4275 bool UseTraps
= useTraps();
4277 unsigned Opcode
= Inst
.getOpcode();
4278 bool isDiv
= Opcode
== Mips::SDivMacro
|| Opcode
== Mips::SDivIMacro
||
4279 Opcode
== Mips::UDivMacro
|| Opcode
== Mips::UDivIMacro
||
4280 Opcode
== Mips::DSDivMacro
|| Opcode
== Mips::DSDivIMacro
||
4281 Opcode
== Mips::DUDivMacro
|| Opcode
== Mips::DUDivIMacro
;
4283 bool isRem
= Opcode
== Mips::SRemMacro
|| Opcode
== Mips::SRemIMacro
||
4284 Opcode
== Mips::URemMacro
|| Opcode
== Mips::URemIMacro
||
4285 Opcode
== Mips::DSRemMacro
|| Opcode
== Mips::DSRemIMacro
||
4286 Opcode
== Mips::DURemMacro
|| Opcode
== Mips::DURemIMacro
;
4289 unsigned ATReg
= getATReg(IDLoc
);
4293 if (ImmValue
== 0) {
4295 TOut
.emitRRI(Mips::TEQ
, ZeroReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4297 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4301 if (isRem
&& (ImmValue
== 1 || (Signed
&& (ImmValue
== -1)))) {
4302 TOut
.emitRRR(Mips::OR
, RdReg
, ZeroReg
, ZeroReg
, IDLoc
, STI
);
4304 } else if (isDiv
&& ImmValue
== 1) {
4305 TOut
.emitRRR(Mips::OR
, RdReg
, RsReg
, Mips::ZERO
, IDLoc
, STI
);
4307 } else if (isDiv
&& Signed
&& ImmValue
== -1) {
4308 TOut
.emitRRR(SubOp
, RdReg
, ZeroReg
, RsReg
, IDLoc
, STI
);
4311 if (loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4312 false, Inst
.getLoc(), Out
, STI
))
4314 TOut
.emitRR(DivOp
, RsReg
, ATReg
, IDLoc
, STI
);
4315 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4321 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4322 // break, insert the trap/break and exit. This gives a different result to
4323 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4324 // are handled equivalently. As the observed behaviour is the same, we're ok.
4325 if (RtReg
== Mips::ZERO
|| RtReg
== Mips::ZERO_64
) {
4327 TOut
.emitRRI(Mips::TEQ
, ZeroReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4330 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4334 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4335 // not expand to macro sequence.
4336 if (isRem
&& (RdReg
== Mips::ZERO
|| RdReg
== Mips::ZERO_64
)) {
4337 TOut
.emitRR(DivOp
, RsReg
, RtReg
, IDLoc
, STI
);
4341 // Temporary label for first branch traget
4342 MCContext
&Context
= TOut
.getStreamer().getContext();
4347 TOut
.emitRRI(Mips::TEQ
, RtReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4349 // Branch to the li instruction.
4350 BrTarget
= Context
.createTempSymbol();
4351 LabelOp
= MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
4352 TOut
.emitRRX(Mips::BNE
, RtReg
, ZeroReg
, LabelOp
, IDLoc
, STI
);
4355 TOut
.emitRR(DivOp
, RsReg
, RtReg
, IDLoc
, STI
);
4358 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4362 TOut
.getStreamer().emitLabel(BrTarget
);
4364 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4368 unsigned ATReg
= getATReg(IDLoc
);
4373 TOut
.getStreamer().emitLabel(BrTarget
);
4375 TOut
.emitRRI(Mips::ADDiu
, ATReg
, ZeroReg
, -1, IDLoc
, STI
);
4377 // Temporary label for the second branch target.
4378 MCSymbol
*BrTargetEnd
= Context
.createTempSymbol();
4379 MCOperand LabelOpEnd
=
4380 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd
, Context
));
4382 // Branch to the mflo instruction.
4383 TOut
.emitRRX(Mips::BNE
, RtReg
, ATReg
, LabelOpEnd
, IDLoc
, STI
);
4386 TOut
.emitRRI(Mips::ADDiu
, ATReg
, ZeroReg
, 1, IDLoc
, STI
);
4387 TOut
.emitDSLL(ATReg
, ATReg
, 63, IDLoc
, STI
);
4389 TOut
.emitRI(Mips::LUi
, ATReg
, (uint16_t)0x8000, IDLoc
, STI
);
4393 TOut
.emitRRI(Mips::TEQ
, RsReg
, ATReg
, 0x6, IDLoc
, STI
);
4395 // Branch to the mflo instruction.
4396 TOut
.emitRRX(Mips::BNE
, RsReg
, ATReg
, LabelOpEnd
, IDLoc
, STI
);
4397 TOut
.emitNop(IDLoc
, STI
);
4398 TOut
.emitII(Mips::BREAK
, 0x6, 0, IDLoc
, STI
);
4401 TOut
.getStreamer().emitLabel(BrTargetEnd
);
4402 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4406 bool MipsAsmParser::expandTrunc(MCInst
&Inst
, bool IsDouble
, bool Is64FPU
,
4407 SMLoc IDLoc
, MCStreamer
&Out
,
4408 const MCSubtargetInfo
*STI
) {
4409 MipsTargetStreamer
&TOut
= getTargetStreamer();
4411 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4412 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isReg() &&
4413 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
4415 unsigned FirstReg
= Inst
.getOperand(0).getReg();
4416 unsigned SecondReg
= Inst
.getOperand(1).getReg();
4417 unsigned ThirdReg
= Inst
.getOperand(2).getReg();
4419 if (hasMips1() && !hasMips2()) {
4420 unsigned ATReg
= getATReg(IDLoc
);
4423 TOut
.emitRR(Mips::CFC1
, ThirdReg
, Mips::RA
, IDLoc
, STI
);
4424 TOut
.emitRR(Mips::CFC1
, ThirdReg
, Mips::RA
, IDLoc
, STI
);
4425 TOut
.emitNop(IDLoc
, STI
);
4426 TOut
.emitRRI(Mips::ORi
, ATReg
, ThirdReg
, 0x3, IDLoc
, STI
);
4427 TOut
.emitRRI(Mips::XORi
, ATReg
, ATReg
, 0x2, IDLoc
, STI
);
4428 TOut
.emitRR(Mips::CTC1
, Mips::RA
, ATReg
, IDLoc
, STI
);
4429 TOut
.emitNop(IDLoc
, STI
);
4430 TOut
.emitRR(IsDouble
? (Is64FPU
? Mips::CVT_W_D64
: Mips::CVT_W_D32
)
4432 FirstReg
, SecondReg
, IDLoc
, STI
);
4433 TOut
.emitRR(Mips::CTC1
, Mips::RA
, ThirdReg
, IDLoc
, STI
);
4434 TOut
.emitNop(IDLoc
, STI
);
4438 TOut
.emitRR(IsDouble
? (Is64FPU
? Mips::TRUNC_W_D64
: Mips::TRUNC_W_D32
)
4440 FirstReg
, SecondReg
, IDLoc
, STI
);
4445 bool MipsAsmParser::expandUlh(MCInst
&Inst
, bool Signed
, SMLoc IDLoc
,
4446 MCStreamer
&Out
, const MCSubtargetInfo
*STI
) {
4447 if (hasMips32r6() || hasMips64r6()) {
4448 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4451 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4452 assert(DstRegOp
.isReg() && "expected register operand kind");
4453 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4454 assert(SrcRegOp
.isReg() && "expected register operand kind");
4455 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4456 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4458 MipsTargetStreamer
&TOut
= getTargetStreamer();
4459 unsigned DstReg
= DstRegOp
.getReg();
4460 unsigned SrcReg
= SrcRegOp
.getReg();
4461 int64_t OffsetValue
= OffsetImmOp
.getImm();
4463 // NOTE: We always need AT for ULHU, as it is always used as the source
4464 // register for one of the LBu's.
4465 warnIfNoMacro(IDLoc
);
4466 unsigned ATReg
= getATReg(IDLoc
);
4470 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 1) && isInt
<16>(OffsetValue
));
4471 if (IsLargeOffset
) {
4472 if (loadImmediate(OffsetValue
, ATReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4477 int64_t FirstOffset
= IsLargeOffset
? 0 : OffsetValue
;
4478 int64_t SecondOffset
= IsLargeOffset
? 1 : (OffsetValue
+ 1);
4480 std::swap(FirstOffset
, SecondOffset
);
4482 unsigned FirstLbuDstReg
= IsLargeOffset
? DstReg
: ATReg
;
4483 unsigned SecondLbuDstReg
= IsLargeOffset
? ATReg
: DstReg
;
4485 unsigned LbuSrcReg
= IsLargeOffset
? ATReg
: SrcReg
;
4486 unsigned SllReg
= IsLargeOffset
? DstReg
: ATReg
;
4488 TOut
.emitRRI(Signed
? Mips::LB
: Mips::LBu
, FirstLbuDstReg
, LbuSrcReg
,
4489 FirstOffset
, IDLoc
, STI
);
4490 TOut
.emitRRI(Mips::LBu
, SecondLbuDstReg
, LbuSrcReg
, SecondOffset
, IDLoc
, STI
);
4491 TOut
.emitRRI(Mips::SLL
, SllReg
, SllReg
, 8, IDLoc
, STI
);
4492 TOut
.emitRRR(Mips::OR
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
4497 bool MipsAsmParser::expandUsh(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4498 const MCSubtargetInfo
*STI
) {
4499 if (hasMips32r6() || hasMips64r6()) {
4500 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4503 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4504 assert(DstRegOp
.isReg() && "expected register operand kind");
4505 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4506 assert(SrcRegOp
.isReg() && "expected register operand kind");
4507 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4508 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4510 MipsTargetStreamer
&TOut
= getTargetStreamer();
4511 unsigned DstReg
= DstRegOp
.getReg();
4512 unsigned SrcReg
= SrcRegOp
.getReg();
4513 int64_t OffsetValue
= OffsetImmOp
.getImm();
4515 warnIfNoMacro(IDLoc
);
4516 unsigned ATReg
= getATReg(IDLoc
);
4520 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 1) && isInt
<16>(OffsetValue
));
4521 if (IsLargeOffset
) {
4522 if (loadImmediate(OffsetValue
, ATReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4527 int64_t FirstOffset
= IsLargeOffset
? 1 : (OffsetValue
+ 1);
4528 int64_t SecondOffset
= IsLargeOffset
? 0 : OffsetValue
;
4530 std::swap(FirstOffset
, SecondOffset
);
4532 if (IsLargeOffset
) {
4533 TOut
.emitRRI(Mips::SB
, DstReg
, ATReg
, FirstOffset
, IDLoc
, STI
);
4534 TOut
.emitRRI(Mips::SRL
, DstReg
, DstReg
, 8, IDLoc
, STI
);
4535 TOut
.emitRRI(Mips::SB
, DstReg
, ATReg
, SecondOffset
, IDLoc
, STI
);
4536 TOut
.emitRRI(Mips::LBu
, ATReg
, ATReg
, 0, IDLoc
, STI
);
4537 TOut
.emitRRI(Mips::SLL
, DstReg
, DstReg
, 8, IDLoc
, STI
);
4538 TOut
.emitRRR(Mips::OR
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
4540 TOut
.emitRRI(Mips::SB
, DstReg
, SrcReg
, FirstOffset
, IDLoc
, STI
);
4541 TOut
.emitRRI(Mips::SRL
, ATReg
, DstReg
, 8, IDLoc
, STI
);
4542 TOut
.emitRRI(Mips::SB
, ATReg
, SrcReg
, SecondOffset
, IDLoc
, STI
);
4548 bool MipsAsmParser::expandUxw(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4549 const MCSubtargetInfo
*STI
) {
4550 if (hasMips32r6() || hasMips64r6()) {
4551 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4554 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4555 assert(DstRegOp
.isReg() && "expected register operand kind");
4556 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4557 assert(SrcRegOp
.isReg() && "expected register operand kind");
4558 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4559 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4561 MipsTargetStreamer
&TOut
= getTargetStreamer();
4562 unsigned DstReg
= DstRegOp
.getReg();
4563 unsigned SrcReg
= SrcRegOp
.getReg();
4564 int64_t OffsetValue
= OffsetImmOp
.getImm();
4566 // Compute left/right load/store offsets.
4567 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 3) && isInt
<16>(OffsetValue
));
4568 int64_t LxlOffset
= IsLargeOffset
? 0 : OffsetValue
;
4569 int64_t LxrOffset
= IsLargeOffset
? 3 : (OffsetValue
+ 3);
4571 std::swap(LxlOffset
, LxrOffset
);
4573 bool IsLoadInst
= (Inst
.getOpcode() == Mips::Ulw
);
4574 bool DoMove
= IsLoadInst
&& (SrcReg
== DstReg
) && !IsLargeOffset
;
4575 unsigned TmpReg
= SrcReg
;
4576 if (IsLargeOffset
|| DoMove
) {
4577 warnIfNoMacro(IDLoc
);
4578 TmpReg
= getATReg(IDLoc
);
4583 if (IsLargeOffset
) {
4584 if (loadImmediate(OffsetValue
, TmpReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4590 std::swap(DstReg
, TmpReg
);
4592 unsigned XWL
= IsLoadInst
? Mips::LWL
: Mips::SWL
;
4593 unsigned XWR
= IsLoadInst
? Mips::LWR
: Mips::SWR
;
4594 TOut
.emitRRI(XWL
, DstReg
, TmpReg
, LxlOffset
, IDLoc
, STI
);
4595 TOut
.emitRRI(XWR
, DstReg
, TmpReg
, LxrOffset
, IDLoc
, STI
);
4598 TOut
.emitRRR(Mips::OR
, TmpReg
, DstReg
, Mips::ZERO
, IDLoc
, STI
);
4603 bool MipsAsmParser::expandSge(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4604 const MCSubtargetInfo
*STI
) {
4605 MipsTargetStreamer
&TOut
= getTargetStreamer();
4607 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4608 assert(Inst
.getOperand(0).isReg() &&
4609 Inst
.getOperand(1).isReg() &&
4610 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
4612 unsigned DstReg
= Inst
.getOperand(0).getReg();
4613 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4614 unsigned OpReg
= Inst
.getOperand(2).getReg();
4617 warnIfNoMacro(IDLoc
);
4619 switch (Inst
.getOpcode()) {
4624 OpCode
= Mips::SLTu
;
4627 llvm_unreachable("unexpected 'sge' opcode");
4630 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4631 TOut
.emitRRR(OpCode
, DstReg
, SrcReg
, OpReg
, IDLoc
, STI
);
4632 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4637 bool MipsAsmParser::expandSgeImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4638 const MCSubtargetInfo
*STI
) {
4639 MipsTargetStreamer
&TOut
= getTargetStreamer();
4641 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4642 assert(Inst
.getOperand(0).isReg() &&
4643 Inst
.getOperand(1).isReg() &&
4644 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4646 unsigned DstReg
= Inst
.getOperand(0).getReg();
4647 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4648 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4649 unsigned OpRegCode
, OpImmCode
;
4651 warnIfNoMacro(IDLoc
);
4653 switch (Inst
.getOpcode()) {
4655 case Mips::SGEImm64
:
4656 OpRegCode
= Mips::SLT
;
4657 OpImmCode
= Mips::SLTi
;
4660 case Mips::SGEUImm64
:
4661 OpRegCode
= Mips::SLTu
;
4662 OpImmCode
= Mips::SLTiu
;
4665 llvm_unreachable("unexpected 'sge' opcode with immediate");
4668 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4669 if (isInt
<16>(ImmValue
)) {
4670 // Use immediate version of STL.
4671 TOut
.emitRRI(OpImmCode
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
4672 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4674 unsigned ImmReg
= DstReg
;
4675 if (DstReg
== SrcReg
) {
4676 unsigned ATReg
= getATReg(Inst
.getLoc());
4682 if (loadImmediate(ImmValue
, ImmReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4683 false, IDLoc
, Out
, STI
))
4686 TOut
.emitRRR(OpRegCode
, DstReg
, SrcReg
, ImmReg
, IDLoc
, STI
);
4687 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4693 bool MipsAsmParser::expandSgtImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4694 const MCSubtargetInfo
*STI
) {
4695 MipsTargetStreamer
&TOut
= getTargetStreamer();
4697 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4698 assert(Inst
.getOperand(0).isReg() &&
4699 Inst
.getOperand(1).isReg() &&
4700 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4702 unsigned DstReg
= Inst
.getOperand(0).getReg();
4703 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4704 unsigned ImmReg
= DstReg
;
4705 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4708 warnIfNoMacro(IDLoc
);
4710 switch (Inst
.getOpcode()) {
4712 case Mips::SGTImm64
:
4716 case Mips::SGTUImm64
:
4717 OpCode
= Mips::SLTu
;
4720 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4723 if (DstReg
== SrcReg
) {
4724 unsigned ATReg
= getATReg(Inst
.getLoc());
4730 if (loadImmediate(ImmValue
, ImmReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4731 false, IDLoc
, Out
, STI
))
4734 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4735 TOut
.emitRRR(OpCode
, DstReg
, ImmReg
, SrcReg
, IDLoc
, STI
);
4740 bool MipsAsmParser::expandSle(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4741 const MCSubtargetInfo
*STI
) {
4742 MipsTargetStreamer
&TOut
= getTargetStreamer();
4744 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4745 assert(Inst
.getOperand(0).isReg() &&
4746 Inst
.getOperand(1).isReg() &&
4747 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
4749 unsigned DstReg
= Inst
.getOperand(0).getReg();
4750 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4751 unsigned OpReg
= Inst
.getOperand(2).getReg();
4754 warnIfNoMacro(IDLoc
);
4756 switch (Inst
.getOpcode()) {
4761 OpCode
= Mips::SLTu
;
4764 llvm_unreachable("unexpected 'sge' opcode");
4767 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4768 TOut
.emitRRR(OpCode
, DstReg
, OpReg
, SrcReg
, IDLoc
, STI
);
4769 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4774 bool MipsAsmParser::expandSleImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4775 const MCSubtargetInfo
*STI
) {
4776 MipsTargetStreamer
&TOut
= getTargetStreamer();
4778 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4779 assert(Inst
.getOperand(0).isReg() &&
4780 Inst
.getOperand(1).isReg() &&
4781 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4783 unsigned DstReg
= Inst
.getOperand(0).getReg();
4784 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4785 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4788 warnIfNoMacro(IDLoc
);
4790 switch (Inst
.getOpcode()) {
4792 case Mips::SLEImm64
:
4793 OpRegCode
= Mips::SLT
;
4796 case Mips::SLEUImm64
:
4797 OpRegCode
= Mips::SLTu
;
4800 llvm_unreachable("unexpected 'sge' opcode with immediate");
4803 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4804 unsigned ImmReg
= DstReg
;
4805 if (DstReg
== SrcReg
) {
4806 unsigned ATReg
= getATReg(Inst
.getLoc());
4812 if (loadImmediate(ImmValue
, ImmReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4813 false, IDLoc
, Out
, STI
))
4816 TOut
.emitRRR(OpRegCode
, DstReg
, ImmReg
, SrcReg
, IDLoc
, STI
);
4817 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4822 bool MipsAsmParser::expandAliasImmediate(MCInst
&Inst
, SMLoc IDLoc
,
4824 const MCSubtargetInfo
*STI
) {
4825 MipsTargetStreamer
&TOut
= getTargetStreamer();
4827 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4828 assert(Inst
.getOperand(0).isReg() &&
4829 Inst
.getOperand(1).isReg() &&
4830 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4832 unsigned ATReg
= Mips::NoRegister
;
4833 unsigned FinalDstReg
= Mips::NoRegister
;
4834 unsigned DstReg
= Inst
.getOperand(0).getReg();
4835 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4836 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4838 bool Is32Bit
= isInt
<32>(ImmValue
) || (!isGP64bit() && isUInt
<32>(ImmValue
));
4840 unsigned FinalOpcode
= Inst
.getOpcode();
4842 if (DstReg
== SrcReg
) {
4843 ATReg
= getATReg(Inst
.getLoc());
4846 FinalDstReg
= DstReg
;
4850 if (!loadImmediate(ImmValue
, DstReg
, Mips::NoRegister
, Is32Bit
, false,
4851 Inst
.getLoc(), Out
, STI
)) {
4852 switch (FinalOpcode
) {
4854 llvm_unreachable("unimplemented expansion");
4856 FinalOpcode
= Mips::ADD
;
4859 FinalOpcode
= Mips::ADDu
;
4862 FinalOpcode
= Mips::AND
;
4865 FinalOpcode
= Mips::NOR
;
4868 FinalOpcode
= Mips::OR
;
4871 FinalOpcode
= Mips::SLT
;
4874 FinalOpcode
= Mips::SLTu
;
4877 FinalOpcode
= Mips::XOR
;
4880 FinalOpcode
= Mips::ADD_MM
;
4882 case Mips::ADDiu_MM
:
4883 FinalOpcode
= Mips::ADDu_MM
;
4886 FinalOpcode
= Mips::AND_MM
;
4889 FinalOpcode
= Mips::OR_MM
;
4892 FinalOpcode
= Mips::SLT_MM
;
4894 case Mips::SLTiu_MM
:
4895 FinalOpcode
= Mips::SLTu_MM
;
4898 FinalOpcode
= Mips::XOR_MM
;
4901 FinalOpcode
= Mips::AND64
;
4903 case Mips::NORImm64
:
4904 FinalOpcode
= Mips::NOR64
;
4907 FinalOpcode
= Mips::OR64
;
4909 case Mips::SLTImm64
:
4910 FinalOpcode
= Mips::SLT64
;
4912 case Mips::SLTUImm64
:
4913 FinalOpcode
= Mips::SLTu64
;
4916 FinalOpcode
= Mips::XOR64
;
4920 if (FinalDstReg
== Mips::NoRegister
)
4921 TOut
.emitRRR(FinalOpcode
, DstReg
, DstReg
, SrcReg
, IDLoc
, STI
);
4923 TOut
.emitRRR(FinalOpcode
, FinalDstReg
, FinalDstReg
, DstReg
, IDLoc
, STI
);
4929 bool MipsAsmParser::expandRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4930 const MCSubtargetInfo
*STI
) {
4931 MipsTargetStreamer
&TOut
= getTargetStreamer();
4932 unsigned ATReg
= Mips::NoRegister
;
4933 unsigned DReg
= Inst
.getOperand(0).getReg();
4934 unsigned SReg
= Inst
.getOperand(1).getReg();
4935 unsigned TReg
= Inst
.getOperand(2).getReg();
4936 unsigned TmpReg
= DReg
;
4938 unsigned FirstShift
= Mips::NOP
;
4939 unsigned SecondShift
= Mips::NOP
;
4941 if (hasMips32r2()) {
4943 TmpReg
= getATReg(Inst
.getLoc());
4948 if (Inst
.getOpcode() == Mips::ROL
) {
4949 TOut
.emitRRR(Mips::SUBu
, TmpReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4950 TOut
.emitRRR(Mips::ROTRV
, DReg
, SReg
, TmpReg
, Inst
.getLoc(), STI
);
4954 if (Inst
.getOpcode() == Mips::ROR
) {
4955 TOut
.emitRRR(Mips::ROTRV
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4963 switch (Inst
.getOpcode()) {
4965 llvm_unreachable("unexpected instruction opcode");
4967 FirstShift
= Mips::SRLV
;
4968 SecondShift
= Mips::SLLV
;
4971 FirstShift
= Mips::SLLV
;
4972 SecondShift
= Mips::SRLV
;
4976 ATReg
= getATReg(Inst
.getLoc());
4980 TOut
.emitRRR(Mips::SUBu
, ATReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4981 TOut
.emitRRR(FirstShift
, ATReg
, SReg
, ATReg
, Inst
.getLoc(), STI
);
4982 TOut
.emitRRR(SecondShift
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4983 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4991 bool MipsAsmParser::expandRotationImm(MCInst
&Inst
, SMLoc IDLoc
,
4993 const MCSubtargetInfo
*STI
) {
4994 MipsTargetStreamer
&TOut
= getTargetStreamer();
4995 unsigned ATReg
= Mips::NoRegister
;
4996 unsigned DReg
= Inst
.getOperand(0).getReg();
4997 unsigned SReg
= Inst
.getOperand(1).getReg();
4998 int64_t ImmValue
= Inst
.getOperand(2).getImm();
5000 unsigned FirstShift
= Mips::NOP
;
5001 unsigned SecondShift
= Mips::NOP
;
5003 if (hasMips32r2()) {
5004 if (Inst
.getOpcode() == Mips::ROLImm
) {
5005 uint64_t MaxShift
= 32;
5006 uint64_t ShiftValue
= ImmValue
;
5008 ShiftValue
= MaxShift
- ImmValue
;
5009 TOut
.emitRRI(Mips::ROTR
, DReg
, SReg
, ShiftValue
, Inst
.getLoc(), STI
);
5013 if (Inst
.getOpcode() == Mips::RORImm
) {
5014 TOut
.emitRRI(Mips::ROTR
, DReg
, SReg
, ImmValue
, Inst
.getLoc(), STI
);
5022 if (ImmValue
== 0) {
5023 TOut
.emitRRI(Mips::SRL
, DReg
, SReg
, 0, Inst
.getLoc(), STI
);
5027 switch (Inst
.getOpcode()) {
5029 llvm_unreachable("unexpected instruction opcode");
5031 FirstShift
= Mips::SLL
;
5032 SecondShift
= Mips::SRL
;
5035 FirstShift
= Mips::SRL
;
5036 SecondShift
= Mips::SLL
;
5040 ATReg
= getATReg(Inst
.getLoc());
5044 TOut
.emitRRI(FirstShift
, ATReg
, SReg
, ImmValue
, Inst
.getLoc(), STI
);
5045 TOut
.emitRRI(SecondShift
, DReg
, SReg
, 32 - ImmValue
, Inst
.getLoc(), STI
);
5046 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
5054 bool MipsAsmParser::expandDRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5055 const MCSubtargetInfo
*STI
) {
5056 MipsTargetStreamer
&TOut
= getTargetStreamer();
5057 unsigned ATReg
= Mips::NoRegister
;
5058 unsigned DReg
= Inst
.getOperand(0).getReg();
5059 unsigned SReg
= Inst
.getOperand(1).getReg();
5060 unsigned TReg
= Inst
.getOperand(2).getReg();
5061 unsigned TmpReg
= DReg
;
5063 unsigned FirstShift
= Mips::NOP
;
5064 unsigned SecondShift
= Mips::NOP
;
5066 if (hasMips64r2()) {
5067 if (TmpReg
== SReg
) {
5068 TmpReg
= getATReg(Inst
.getLoc());
5073 if (Inst
.getOpcode() == Mips::DROL
) {
5074 TOut
.emitRRR(Mips::DSUBu
, TmpReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
5075 TOut
.emitRRR(Mips::DROTRV
, DReg
, SReg
, TmpReg
, Inst
.getLoc(), STI
);
5079 if (Inst
.getOpcode() == Mips::DROR
) {
5080 TOut
.emitRRR(Mips::DROTRV
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
5088 switch (Inst
.getOpcode()) {
5090 llvm_unreachable("unexpected instruction opcode");
5092 FirstShift
= Mips::DSRLV
;
5093 SecondShift
= Mips::DSLLV
;
5096 FirstShift
= Mips::DSLLV
;
5097 SecondShift
= Mips::DSRLV
;
5101 ATReg
= getATReg(Inst
.getLoc());
5105 TOut
.emitRRR(Mips::DSUBu
, ATReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
5106 TOut
.emitRRR(FirstShift
, ATReg
, SReg
, ATReg
, Inst
.getLoc(), STI
);
5107 TOut
.emitRRR(SecondShift
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
5108 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
5116 bool MipsAsmParser::expandDRotationImm(MCInst
&Inst
, SMLoc IDLoc
,
5118 const MCSubtargetInfo
*STI
) {
5119 MipsTargetStreamer
&TOut
= getTargetStreamer();
5120 unsigned ATReg
= Mips::NoRegister
;
5121 unsigned DReg
= Inst
.getOperand(0).getReg();
5122 unsigned SReg
= Inst
.getOperand(1).getReg();
5123 int64_t ImmValue
= Inst
.getOperand(2).getImm() % 64;
5125 unsigned FirstShift
= Mips::NOP
;
5126 unsigned SecondShift
= Mips::NOP
;
5130 if (hasMips64r2()) {
5131 unsigned FinalOpcode
= Mips::NOP
;
5133 FinalOpcode
= Mips::DROTR
;
5134 else if (ImmValue
% 32 == 0)
5135 FinalOpcode
= Mips::DROTR32
;
5136 else if ((ImmValue
>= 1) && (ImmValue
<= 32)) {
5137 if (Inst
.getOpcode() == Mips::DROLImm
)
5138 FinalOpcode
= Mips::DROTR32
;
5140 FinalOpcode
= Mips::DROTR
;
5141 } else if (ImmValue
>= 33) {
5142 if (Inst
.getOpcode() == Mips::DROLImm
)
5143 FinalOpcode
= Mips::DROTR
;
5145 FinalOpcode
= Mips::DROTR32
;
5148 uint64_t ShiftValue
= ImmValue
% 32;
5149 if (Inst
.getOpcode() == Mips::DROLImm
)
5150 ShiftValue
= (32 - ImmValue
% 32) % 32;
5152 TOut
.emitRRI(FinalOpcode
, DReg
, SReg
, ShiftValue
, Inst
.getLoc(), STI
);
5158 if (ImmValue
== 0) {
5159 TOut
.emitRRI(Mips::DSRL
, DReg
, SReg
, 0, Inst
.getLoc(), STI
);
5163 switch (Inst
.getOpcode()) {
5165 llvm_unreachable("unexpected instruction opcode");
5167 if ((ImmValue
>= 1) && (ImmValue
<= 31)) {
5168 FirstShift
= Mips::DSLL
;
5169 SecondShift
= Mips::DSRL32
;
5171 if (ImmValue
== 32) {
5172 FirstShift
= Mips::DSLL32
;
5173 SecondShift
= Mips::DSRL32
;
5175 if ((ImmValue
>= 33) && (ImmValue
<= 63)) {
5176 FirstShift
= Mips::DSLL32
;
5177 SecondShift
= Mips::DSRL
;
5181 if ((ImmValue
>= 1) && (ImmValue
<= 31)) {
5182 FirstShift
= Mips::DSRL
;
5183 SecondShift
= Mips::DSLL32
;
5185 if (ImmValue
== 32) {
5186 FirstShift
= Mips::DSRL32
;
5187 SecondShift
= Mips::DSLL32
;
5189 if ((ImmValue
>= 33) && (ImmValue
<= 63)) {
5190 FirstShift
= Mips::DSRL32
;
5191 SecondShift
= Mips::DSLL
;
5196 ATReg
= getATReg(Inst
.getLoc());
5200 TOut
.emitRRI(FirstShift
, ATReg
, SReg
, ImmValue
% 32, Inst
.getLoc(), STI
);
5201 TOut
.emitRRI(SecondShift
, DReg
, SReg
, (32 - ImmValue
% 32) % 32,
5202 Inst
.getLoc(), STI
);
5203 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
5211 bool MipsAsmParser::expandAbs(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5212 const MCSubtargetInfo
*STI
) {
5213 MipsTargetStreamer
&TOut
= getTargetStreamer();
5214 unsigned FirstRegOp
= Inst
.getOperand(0).getReg();
5215 unsigned SecondRegOp
= Inst
.getOperand(1).getReg();
5217 TOut
.emitRI(Mips::BGEZ
, SecondRegOp
, 8, IDLoc
, STI
);
5218 if (FirstRegOp
!= SecondRegOp
)
5219 TOut
.emitRRR(Mips::ADDu
, FirstRegOp
, SecondRegOp
, Mips::ZERO
, IDLoc
, STI
);
5221 TOut
.emitEmptyDelaySlot(false, IDLoc
, STI
);
5222 TOut
.emitRRR(Mips::SUB
, FirstRegOp
, Mips::ZERO
, SecondRegOp
, IDLoc
, STI
);
5227 bool MipsAsmParser::expandMulImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5228 const MCSubtargetInfo
*STI
) {
5229 MipsTargetStreamer
&TOut
= getTargetStreamer();
5230 unsigned ATReg
= Mips::NoRegister
;
5231 unsigned DstReg
= Inst
.getOperand(0).getReg();
5232 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5233 int32_t ImmValue
= Inst
.getOperand(2).getImm();
5235 ATReg
= getATReg(IDLoc
);
5239 loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, true, false, IDLoc
, Out
,
5242 TOut
.emitRR(Inst
.getOpcode() == Mips::MULImmMacro
? Mips::MULT
: Mips::DMULT
,
5243 SrcReg
, ATReg
, IDLoc
, STI
);
5245 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5250 bool MipsAsmParser::expandMulO(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5251 const MCSubtargetInfo
*STI
) {
5252 MipsTargetStreamer
&TOut
= getTargetStreamer();
5253 unsigned ATReg
= Mips::NoRegister
;
5254 unsigned DstReg
= Inst
.getOperand(0).getReg();
5255 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5256 unsigned TmpReg
= Inst
.getOperand(2).getReg();
5258 ATReg
= getATReg(Inst
.getLoc());
5262 TOut
.emitRR(Inst
.getOpcode() == Mips::MULOMacro
? Mips::MULT
: Mips::DMULT
,
5263 SrcReg
, TmpReg
, IDLoc
, STI
);
5265 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5267 TOut
.emitRRI(Inst
.getOpcode() == Mips::MULOMacro
? Mips::SRA
: Mips::DSRA32
,
5268 DstReg
, DstReg
, 0x1F, IDLoc
, STI
);
5270 TOut
.emitR(Mips::MFHI
, ATReg
, IDLoc
, STI
);
5273 TOut
.emitRRI(Mips::TNE
, DstReg
, ATReg
, 6, IDLoc
, STI
);
5275 MCContext
& Context
= TOut
.getStreamer().getContext();
5276 MCSymbol
* BrTarget
= Context
.createTempSymbol();
5278 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
5280 TOut
.emitRRX(Mips::BEQ
, DstReg
, ATReg
, LabelOp
, IDLoc
, STI
);
5281 if (AssemblerOptions
.back()->isReorder())
5282 TOut
.emitNop(IDLoc
, STI
);
5283 TOut
.emitII(Mips::BREAK
, 6, 0, IDLoc
, STI
);
5285 TOut
.getStreamer().emitLabel(BrTarget
);
5287 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5292 bool MipsAsmParser::expandMulOU(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5293 const MCSubtargetInfo
*STI
) {
5294 MipsTargetStreamer
&TOut
= getTargetStreamer();
5295 unsigned ATReg
= Mips::NoRegister
;
5296 unsigned DstReg
= Inst
.getOperand(0).getReg();
5297 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5298 unsigned TmpReg
= Inst
.getOperand(2).getReg();
5300 ATReg
= getATReg(IDLoc
);
5304 TOut
.emitRR(Inst
.getOpcode() == Mips::MULOUMacro
? Mips::MULTu
: Mips::DMULTu
,
5305 SrcReg
, TmpReg
, IDLoc
, STI
);
5307 TOut
.emitR(Mips::MFHI
, ATReg
, IDLoc
, STI
);
5308 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5310 TOut
.emitRRI(Mips::TNE
, ATReg
, Mips::ZERO
, 6, IDLoc
, STI
);
5312 MCContext
& Context
= TOut
.getStreamer().getContext();
5313 MCSymbol
* BrTarget
= Context
.createTempSymbol();
5315 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
5317 TOut
.emitRRX(Mips::BEQ
, ATReg
, Mips::ZERO
, LabelOp
, IDLoc
, STI
);
5318 if (AssemblerOptions
.back()->isReorder())
5319 TOut
.emitNop(IDLoc
, STI
);
5320 TOut
.emitII(Mips::BREAK
, 6, 0, IDLoc
, STI
);
5322 TOut
.getStreamer().emitLabel(BrTarget
);
5328 bool MipsAsmParser::expandDMULMacro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5329 const MCSubtargetInfo
*STI
) {
5330 MipsTargetStreamer
&TOut
= getTargetStreamer();
5331 unsigned DstReg
= Inst
.getOperand(0).getReg();
5332 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5333 unsigned TmpReg
= Inst
.getOperand(2).getReg();
5335 TOut
.emitRR(Mips::DMULTu
, SrcReg
, TmpReg
, IDLoc
, STI
);
5336 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5341 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5342 // lw $<reg+1>>, offset+4($reg2)'
5343 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5344 // sw $<reg+1>>, offset+4($reg2)'
5346 bool MipsAsmParser::expandLoadStoreDMacro(MCInst
&Inst
, SMLoc IDLoc
,
5348 const MCSubtargetInfo
*STI
,
5353 warnIfNoMacro(IDLoc
);
5355 MipsTargetStreamer
&TOut
= getTargetStreamer();
5356 unsigned Opcode
= IsLoad
? Mips::LW
: Mips::SW
;
5357 unsigned FirstReg
= Inst
.getOperand(0).getReg();
5358 unsigned SecondReg
= nextReg(FirstReg
);
5359 unsigned BaseReg
= Inst
.getOperand(1).getReg();
5363 warnIfRegIndexIsAT(FirstReg
, IDLoc
);
5365 assert(Inst
.getOperand(2).isImm() &&
5366 "Offset for load macro is not immediate!");
5368 MCOperand
&FirstOffset
= Inst
.getOperand(2);
5369 signed NextOffset
= FirstOffset
.getImm() + 4;
5370 MCOperand SecondOffset
= MCOperand::createImm(NextOffset
);
5372 if (!isInt
<16>(FirstOffset
.getImm()) || !isInt
<16>(NextOffset
))
5375 // For loads, clobber the base register with the second load instead of the
5376 // first if the BaseReg == FirstReg.
5377 if (FirstReg
!= BaseReg
|| !IsLoad
) {
5378 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5379 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5381 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5382 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5389 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5390 // swc1 $<reg>, offset+4($reg2)'
5391 // or if little endian to 'swc1 $<reg>, offset($reg2);
5392 // swc1 $<reg+1>, offset+4($reg2)'
5394 bool MipsAsmParser::expandStoreDM1Macro(MCInst
&Inst
, SMLoc IDLoc
,
5396 const MCSubtargetInfo
*STI
) {
5400 warnIfNoMacro(IDLoc
);
5402 MipsTargetStreamer
&TOut
= getTargetStreamer();
5403 unsigned Opcode
= Mips::SWC1
;
5404 unsigned FirstReg
= Inst
.getOperand(0).getReg();
5405 unsigned SecondReg
= nextReg(FirstReg
);
5406 unsigned BaseReg
= Inst
.getOperand(1).getReg();
5410 warnIfRegIndexIsAT(FirstReg
, IDLoc
);
5412 assert(Inst
.getOperand(2).isImm() &&
5413 "Offset for macro is not immediate!");
5415 MCOperand
&FirstOffset
= Inst
.getOperand(2);
5416 signed NextOffset
= FirstOffset
.getImm() + 4;
5417 MCOperand SecondOffset
= MCOperand::createImm(NextOffset
);
5419 if (!isInt
<16>(FirstOffset
.getImm()) || !isInt
<16>(NextOffset
))
5422 if (!IsLittleEndian
)
5423 std::swap(FirstReg
, SecondReg
);
5425 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5426 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5431 bool MipsAsmParser::expandSeq(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5432 const MCSubtargetInfo
*STI
) {
5433 MipsTargetStreamer
&TOut
= getTargetStreamer();
5435 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5436 assert(Inst
.getOperand(0).isReg() &&
5437 Inst
.getOperand(1).isReg() &&
5438 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
5440 unsigned DstReg
= Inst
.getOperand(0).getReg();
5441 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5442 unsigned OpReg
= Inst
.getOperand(2).getReg();
5444 warnIfNoMacro(IDLoc
);
5446 if (SrcReg
!= Mips::ZERO
&& OpReg
!= Mips::ZERO
) {
5447 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, OpReg
, IDLoc
, STI
);
5448 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5452 unsigned Reg
= SrcReg
== Mips::ZERO
? OpReg
: SrcReg
;
5453 TOut
.emitRRI(Mips::SLTiu
, DstReg
, Reg
, 1, IDLoc
, STI
);
5457 bool MipsAsmParser::expandSeqI(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5458 const MCSubtargetInfo
*STI
) {
5459 MipsTargetStreamer
&TOut
= getTargetStreamer();
5461 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5462 assert(Inst
.getOperand(0).isReg() &&
5463 Inst
.getOperand(1).isReg() &&
5464 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
5466 unsigned DstReg
= Inst
.getOperand(0).getReg();
5467 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5468 int64_t Imm
= Inst
.getOperand(2).getImm();
5470 warnIfNoMacro(IDLoc
);
5473 TOut
.emitRRI(Mips::SLTiu
, DstReg
, SrcReg
, 1, IDLoc
, STI
);
5477 if (SrcReg
== Mips::ZERO
) {
5478 Warning(IDLoc
, "comparison is always false");
5479 TOut
.emitRRR(isGP64bit() ? Mips::DADDu
: Mips::ADDu
,
5480 DstReg
, SrcReg
, SrcReg
, IDLoc
, STI
);
5485 if (Imm
> -0x8000 && Imm
< 0) {
5487 Opc
= isGP64bit() ? Mips::DADDiu
: Mips::ADDiu
;
5492 if (!isUInt
<16>(Imm
)) {
5493 unsigned ATReg
= getATReg(IDLoc
);
5497 if (loadImmediate(Imm
, ATReg
, Mips::NoRegister
, true, isGP64bit(), IDLoc
,
5501 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, ATReg
, IDLoc
, STI
);
5502 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5506 TOut
.emitRRI(Opc
, DstReg
, SrcReg
, Imm
, IDLoc
, STI
);
5507 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5511 bool MipsAsmParser::expandSne(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5512 const MCSubtargetInfo
*STI
) {
5514 MipsTargetStreamer
&TOut
= getTargetStreamer();
5516 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5517 assert(Inst
.getOperand(0).isReg() &&
5518 Inst
.getOperand(1).isReg() &&
5519 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
5521 unsigned DstReg
= Inst
.getOperand(0).getReg();
5522 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5523 unsigned OpReg
= Inst
.getOperand(2).getReg();
5525 warnIfNoMacro(IDLoc
);
5527 if (SrcReg
!= Mips::ZERO
&& OpReg
!= Mips::ZERO
) {
5528 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, OpReg
, IDLoc
, STI
);
5529 TOut
.emitRRR(Mips::SLTu
, DstReg
, Mips::ZERO
, DstReg
, IDLoc
, STI
);
5533 unsigned Reg
= SrcReg
== Mips::ZERO
? OpReg
: SrcReg
;
5534 TOut
.emitRRR(Mips::SLTu
, DstReg
, Mips::ZERO
, Reg
, IDLoc
, STI
);
5538 bool MipsAsmParser::expandSneI(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5539 const MCSubtargetInfo
*STI
) {
5540 MipsTargetStreamer
&TOut
= getTargetStreamer();
5542 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5543 assert(Inst
.getOperand(0).isReg() &&
5544 Inst
.getOperand(1).isReg() &&
5545 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
5547 unsigned DstReg
= Inst
.getOperand(0).getReg();
5548 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5549 int64_t ImmValue
= Inst
.getOperand(2).getImm();
5551 warnIfNoMacro(IDLoc
);
5553 if (ImmValue
== 0) {
5554 TOut
.emitRRR(Mips::SLTu
, DstReg
, Mips::ZERO
, SrcReg
, IDLoc
, STI
);
5558 if (SrcReg
== Mips::ZERO
) {
5559 Warning(IDLoc
, "comparison is always true");
5560 if (loadImmediate(1, DstReg
, Mips::NoRegister
, true, false, IDLoc
, Out
,
5567 if (ImmValue
> -0x8000 && ImmValue
< 0) {
5568 ImmValue
= -ImmValue
;
5569 Opc
= isGP64bit() ? Mips::DADDiu
: Mips::ADDiu
;
5574 if (isUInt
<16>(ImmValue
)) {
5575 TOut
.emitRRI(Opc
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
5576 TOut
.emitRRR(Mips::SLTu
, DstReg
, Mips::ZERO
, DstReg
, IDLoc
, STI
);
5580 unsigned ATReg
= getATReg(IDLoc
);
5584 if (loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
5585 false, IDLoc
, Out
, STI
))
5588 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, ATReg
, IDLoc
, STI
);
5589 TOut
.emitRRR(Mips::SLTu
, DstReg
, Mips::ZERO
, DstReg
, IDLoc
, STI
);
5593 // Map the DSP accumulator and control register to the corresponding gpr
5594 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5595 // do not map the DSP registers contigously to gpr registers.
5596 static unsigned getRegisterForMxtrDSP(MCInst
&Inst
, bool IsMFDSP
) {
5597 switch (Inst
.getOpcode()) {
5600 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5610 llvm_unreachable("Unknown register for 'mttr' alias!");
5614 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5624 llvm_unreachable("Unknown register for 'mttr' alias!");
5628 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5638 llvm_unreachable("Unknown register for 'mttr' alias!");
5644 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5648 // Map the floating point register operand to the corresponding register
5650 static unsigned getRegisterForMxtrFP(MCInst
&Inst
, bool IsMFTC1
) {
5651 switch (Inst
.getOperand(IsMFTC1
? 1 : 0).getReg()) {
5652 case Mips::F0
: return Mips::ZERO
;
5653 case Mips::F1
: return Mips::AT
;
5654 case Mips::F2
: return Mips::V0
;
5655 case Mips::F3
: return Mips::V1
;
5656 case Mips::F4
: return Mips::A0
;
5657 case Mips::F5
: return Mips::A1
;
5658 case Mips::F6
: return Mips::A2
;
5659 case Mips::F7
: return Mips::A3
;
5660 case Mips::F8
: return Mips::T0
;
5661 case Mips::F9
: return Mips::T1
;
5662 case Mips::F10
: return Mips::T2
;
5663 case Mips::F11
: return Mips::T3
;
5664 case Mips::F12
: return Mips::T4
;
5665 case Mips::F13
: return Mips::T5
;
5666 case Mips::F14
: return Mips::T6
;
5667 case Mips::F15
: return Mips::T7
;
5668 case Mips::F16
: return Mips::S0
;
5669 case Mips::F17
: return Mips::S1
;
5670 case Mips::F18
: return Mips::S2
;
5671 case Mips::F19
: return Mips::S3
;
5672 case Mips::F20
: return Mips::S4
;
5673 case Mips::F21
: return Mips::S5
;
5674 case Mips::F22
: return Mips::S6
;
5675 case Mips::F23
: return Mips::S7
;
5676 case Mips::F24
: return Mips::T8
;
5677 case Mips::F25
: return Mips::T9
;
5678 case Mips::F26
: return Mips::K0
;
5679 case Mips::F27
: return Mips::K1
;
5680 case Mips::F28
: return Mips::GP
;
5681 case Mips::F29
: return Mips::SP
;
5682 case Mips::F30
: return Mips::FP
;
5683 case Mips::F31
: return Mips::RA
;
5684 default: llvm_unreachable("Unknown register for mttc1 alias!");
5688 // Map the coprocessor operand the corresponding gpr register operand.
5689 static unsigned getRegisterForMxtrC0(MCInst
&Inst
, bool IsMFTC0
) {
5690 switch (Inst
.getOperand(IsMFTC0
? 1 : 0).getReg()) {
5691 case Mips::COP00
: return Mips::ZERO
;
5692 case Mips::COP01
: return Mips::AT
;
5693 case Mips::COP02
: return Mips::V0
;
5694 case Mips::COP03
: return Mips::V1
;
5695 case Mips::COP04
: return Mips::A0
;
5696 case Mips::COP05
: return Mips::A1
;
5697 case Mips::COP06
: return Mips::A2
;
5698 case Mips::COP07
: return Mips::A3
;
5699 case Mips::COP08
: return Mips::T0
;
5700 case Mips::COP09
: return Mips::T1
;
5701 case Mips::COP010
: return Mips::T2
;
5702 case Mips::COP011
: return Mips::T3
;
5703 case Mips::COP012
: return Mips::T4
;
5704 case Mips::COP013
: return Mips::T5
;
5705 case Mips::COP014
: return Mips::T6
;
5706 case Mips::COP015
: return Mips::T7
;
5707 case Mips::COP016
: return Mips::S0
;
5708 case Mips::COP017
: return Mips::S1
;
5709 case Mips::COP018
: return Mips::S2
;
5710 case Mips::COP019
: return Mips::S3
;
5711 case Mips::COP020
: return Mips::S4
;
5712 case Mips::COP021
: return Mips::S5
;
5713 case Mips::COP022
: return Mips::S6
;
5714 case Mips::COP023
: return Mips::S7
;
5715 case Mips::COP024
: return Mips::T8
;
5716 case Mips::COP025
: return Mips::T9
;
5717 case Mips::COP026
: return Mips::K0
;
5718 case Mips::COP027
: return Mips::K1
;
5719 case Mips::COP028
: return Mips::GP
;
5720 case Mips::COP029
: return Mips::SP
;
5721 case Mips::COP030
: return Mips::FP
;
5722 case Mips::COP031
: return Mips::RA
;
5723 default: llvm_unreachable("Unknown register for mttc0 alias!");
5727 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5728 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5729 bool MipsAsmParser::expandMXTRAlias(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5730 const MCSubtargetInfo
*STI
) {
5731 MipsTargetStreamer
&TOut
= getTargetStreamer();
5736 bool IsMFTR
= false;
5737 switch (Inst
.getOpcode()) {
5743 rd
= getRegisterForMxtrC0(Inst
, IsMFTR
);
5744 sel
= Inst
.getOperand(2).getImm();
5750 rd
= Inst
.getOperand(IsMFTR
? 1 : 0).getReg();
5762 rd
= getRegisterForMxtrDSP(Inst
, IsMFTR
);
5770 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5777 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5784 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5788 MCRegister Op0
= IsMFTR
? Inst
.getOperand(0).getReg() : MCRegister(rd
);
5790 IsMFTR
? MCRegister(rd
)
5791 : (Inst
.getOpcode() != Mips::MTTDSP
? Inst
.getOperand(1).getReg()
5792 : Inst
.getOperand(0).getReg());
5794 TOut
.emitRRIII(IsMFTR
? Mips::MFTR
: Mips::MTTR
, Op0
, Op1
, u
, sel
, h
, IDLoc
,
5799 bool MipsAsmParser::expandSaaAddr(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5800 const MCSubtargetInfo
*STI
) {
5801 assert(Inst
.getNumOperands() == 3 && "expected three operands");
5802 assert(Inst
.getOperand(0).isReg() && "expected register operand kind");
5803 assert(Inst
.getOperand(1).isReg() && "expected register operand kind");
5805 warnIfNoMacro(IDLoc
);
5807 MipsTargetStreamer
&TOut
= getTargetStreamer();
5808 unsigned Opcode
= Inst
.getOpcode() == Mips::SaaAddr
? Mips::SAA
: Mips::SAAD
;
5809 unsigned RtReg
= Inst
.getOperand(0).getReg();
5810 unsigned BaseReg
= Inst
.getOperand(1).getReg();
5811 const MCOperand
&BaseOp
= Inst
.getOperand(2);
5813 if (BaseOp
.isImm()) {
5814 int64_t ImmValue
= BaseOp
.getImm();
5815 if (ImmValue
== 0) {
5816 TOut
.emitRR(Opcode
, RtReg
, BaseReg
, IDLoc
, STI
);
5821 unsigned ATReg
= getATReg(IDLoc
);
5825 if (expandLoadAddress(ATReg
, BaseReg
, BaseOp
, !isGP64bit(), IDLoc
, Out
, STI
))
5828 TOut
.emitRR(Opcode
, RtReg
, ATReg
, IDLoc
, STI
);
5833 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst
&Inst
,
5834 const OperandVector
&Operands
) {
5835 switch (Inst
.getOpcode()) {
5837 return Match_Success
;
5840 if (static_cast<MipsOperand
&>(*Operands
[1])
5841 .isValidForTie(static_cast<MipsOperand
&>(*Operands
[2])))
5842 return Match_Success
;
5843 return Match_RequiresSameSrcAndDst
;
5847 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst
&Inst
) {
5848 switch (Inst
.getOpcode()) {
5849 // As described by the MIPSR6 spec, daui must not use the zero operand for
5850 // its source operand.
5852 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
5853 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
5854 return Match_RequiresNoZeroRegister
;
5855 return Match_Success
;
5856 // As described by the Mips32r2 spec, the registers Rd and Rs for
5857 // jalr.hb must be different.
5858 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5859 // and registers Rd and Base for microMIPS lwp instruction
5861 case Mips::JALR_HB64
:
5862 case Mips::JALRC_HB_MMR6
:
5863 case Mips::JALRC_MMR6
:
5864 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(1).getReg())
5865 return Match_RequiresDifferentSrcAndDst
;
5866 return Match_Success
;
5868 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(2).getReg())
5869 return Match_RequiresDifferentSrcAndDst
;
5870 return Match_Success
;
5872 if (Inst
.getOperand(0).getImm() != 0 && !hasMips32())
5873 return Match_NonZeroOperandForSync
;
5874 return Match_Success
;
5879 if (Inst
.getOperand(2).getImm() != 0 && !hasMips32())
5880 return Match_NonZeroOperandForMTCX
;
5881 return Match_Success
;
5882 // As described the MIPSR6 spec, the compact branches that compare registers
5884 // a) Not use the zero register.
5885 // b) Not use the same register twice.
5886 // c) rs < rt for bnec, beqc.
5887 // NB: For this case, the encoding will swap the operands as their
5888 // ordering doesn't matter. GAS performs this transformation too.
5889 // Hence, that constraint does not have to be enforced.
5891 // The compact branches that branch iff the signed addition of two registers
5892 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5893 // operand swapping. They do not have restriction of using the zero register.
5894 case Mips::BLEZC
: case Mips::BLEZC_MMR6
:
5895 case Mips::BGEZC
: case Mips::BGEZC_MMR6
:
5896 case Mips::BGTZC
: case Mips::BGTZC_MMR6
:
5897 case Mips::BLTZC
: case Mips::BLTZC_MMR6
:
5898 case Mips::BEQZC
: case Mips::BEQZC_MMR6
:
5899 case Mips::BNEZC
: case Mips::BNEZC_MMR6
:
5906 if (Inst
.getOperand(0).getReg() == Mips::ZERO
||
5907 Inst
.getOperand(0).getReg() == Mips::ZERO_64
)
5908 return Match_RequiresNoZeroRegister
;
5909 return Match_Success
;
5910 case Mips::BGEC
: case Mips::BGEC_MMR6
:
5911 case Mips::BLTC
: case Mips::BLTC_MMR6
:
5912 case Mips::BGEUC
: case Mips::BGEUC_MMR6
:
5913 case Mips::BLTUC
: case Mips::BLTUC_MMR6
:
5914 case Mips::BEQC
: case Mips::BEQC_MMR6
:
5915 case Mips::BNEC
: case Mips::BNEC_MMR6
:
5922 if (Inst
.getOperand(0).getReg() == Mips::ZERO
||
5923 Inst
.getOperand(0).getReg() == Mips::ZERO_64
)
5924 return Match_RequiresNoZeroRegister
;
5925 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
5926 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
5927 return Match_RequiresNoZeroRegister
;
5928 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(1).getReg())
5929 return Match_RequiresDifferentOperands
;
5930 return Match_Success
;
5932 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5933 "Operands must be immediates for dins!");
5934 const signed Pos
= Inst
.getOperand(2).getImm();
5935 const signed Size
= Inst
.getOperand(3).getImm();
5936 if ((0 > (Pos
+ Size
)) || ((Pos
+ Size
) > 32))
5937 return Match_RequiresPosSizeRange0_32
;
5938 return Match_Success
;
5942 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5943 "Operands must be immediates for dinsm/dinsu!");
5944 const signed Pos
= Inst
.getOperand(2).getImm();
5945 const signed Size
= Inst
.getOperand(3).getImm();
5946 if ((32 >= (Pos
+ Size
)) || ((Pos
+ Size
) > 64))
5947 return Match_RequiresPosSizeRange33_64
;
5948 return Match_Success
;
5951 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5952 "Operands must be immediates for DEXTM!");
5953 const signed Pos
= Inst
.getOperand(2).getImm();
5954 const signed Size
= Inst
.getOperand(3).getImm();
5955 if ((1 > (Pos
+ Size
)) || ((Pos
+ Size
) > 63))
5956 return Match_RequiresPosSizeUImm6
;
5957 return Match_Success
;
5961 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5962 "Operands must be immediates for dextm/dextu!");
5963 const signed Pos
= Inst
.getOperand(2).getImm();
5964 const signed Size
= Inst
.getOperand(3).getImm();
5965 if ((32 > (Pos
+ Size
)) || ((Pos
+ Size
) > 64))
5966 return Match_RequiresPosSizeRange33_64
;
5967 return Match_Success
;
5969 case Mips::CRC32B
: case Mips::CRC32CB
:
5970 case Mips::CRC32H
: case Mips::CRC32CH
:
5971 case Mips::CRC32W
: case Mips::CRC32CW
:
5972 case Mips::CRC32D
: case Mips::CRC32CD
:
5973 if (Inst
.getOperand(0).getReg() != Inst
.getOperand(2).getReg())
5974 return Match_RequiresSameSrcAndDst
;
5975 return Match_Success
;
5978 uint64_t TSFlags
= MII
.get(Inst
.getOpcode()).TSFlags
;
5979 if ((TSFlags
& MipsII::HasFCCRegOperand
) &&
5980 (Inst
.getOperand(0).getReg() != Mips::FCC0
) && !hasEightFccRegisters())
5981 return Match_NoFCCRegisterForCurrentISA
;
5983 return Match_Success
;
5987 static SMLoc
RefineErrorLoc(const SMLoc Loc
, const OperandVector
&Operands
,
5988 uint64_t ErrorInfo
) {
5989 if (ErrorInfo
!= ~0ULL && ErrorInfo
< Operands
.size()) {
5990 SMLoc ErrorLoc
= Operands
[ErrorInfo
]->getStartLoc();
5991 if (ErrorLoc
== SMLoc())
5998 bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
5999 OperandVector
&Operands
,
6001 uint64_t &ErrorInfo
,
6002 bool MatchingInlineAsm
) {
6004 unsigned MatchResult
=
6005 MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
);
6007 switch (MatchResult
) {
6009 if (processInstruction(Inst
, IDLoc
, Out
, STI
))
6012 case Match_MissingFeature
:
6013 Error(IDLoc
, "instruction requires a CPU feature not currently enabled");
6015 case Match_InvalidTiedOperand
:
6016 Error(IDLoc
, "operand must match destination register");
6018 case Match_InvalidOperand
: {
6019 SMLoc ErrorLoc
= IDLoc
;
6020 if (ErrorInfo
!= ~0ULL) {
6021 if (ErrorInfo
>= Operands
.size())
6022 return Error(IDLoc
, "too few operands for instruction");
6024 ErrorLoc
= Operands
[ErrorInfo
]->getStartLoc();
6025 if (ErrorLoc
== SMLoc())
6029 return Error(ErrorLoc
, "invalid operand for instruction");
6031 case Match_NonZeroOperandForSync
:
6033 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6034 case Match_NonZeroOperandForMTCX
:
6035 return Error(IDLoc
, "selector must be zero for pre-MIPS32 ISAs");
6036 case Match_MnemonicFail
:
6037 return Error(IDLoc
, "invalid instruction");
6038 case Match_RequiresDifferentSrcAndDst
:
6039 return Error(IDLoc
, "source and destination must be different");
6040 case Match_RequiresDifferentOperands
:
6041 return Error(IDLoc
, "registers must be different");
6042 case Match_RequiresNoZeroRegister
:
6043 return Error(IDLoc
, "invalid operand ($zero) for instruction");
6044 case Match_RequiresSameSrcAndDst
:
6045 return Error(IDLoc
, "source and destination must match");
6046 case Match_NoFCCRegisterForCurrentISA
:
6047 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6048 "non-zero fcc register doesn't exist in current ISA level");
6050 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
), "expected '0'");
6052 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6053 "expected 1-bit unsigned immediate");
6055 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6056 "expected 2-bit unsigned immediate");
6058 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6059 "expected immediate in range 1 .. 4");
6061 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6062 "expected 3-bit unsigned immediate");
6064 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6065 "expected 4-bit unsigned immediate");
6067 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6068 "expected 4-bit signed immediate");
6070 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6071 "expected 5-bit unsigned immediate");
6073 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6074 "expected 5-bit signed immediate");
6076 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6077 "expected immediate in range 1 .. 32");
6078 case Match_UImm5_32
:
6079 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6080 "expected immediate in range 32 .. 63");
6081 case Match_UImm5_33
:
6082 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6083 "expected immediate in range 33 .. 64");
6084 case Match_UImm5_0_Report_UImm6
:
6085 // This is used on UImm5 operands that have a corresponding UImm5_32
6086 // operand to avoid confusing the user.
6087 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6088 "expected 6-bit unsigned immediate");
6089 case Match_UImm5_Lsl2
:
6090 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6091 "expected both 7-bit unsigned immediate and multiple of 4");
6092 case Match_UImmRange2_64
:
6093 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6094 "expected immediate in range 2 .. 64");
6096 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6097 "expected 6-bit unsigned immediate");
6098 case Match_UImm6_Lsl2
:
6099 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6100 "expected both 8-bit unsigned immediate and multiple of 4");
6102 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6103 "expected 6-bit signed immediate");
6105 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6106 "expected 7-bit unsigned immediate");
6107 case Match_UImm7_N1
:
6108 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6109 "expected immediate in range -1 .. 126");
6110 case Match_SImm7_Lsl2
:
6111 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6112 "expected both 9-bit signed immediate and multiple of 4");
6114 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6115 "expected 8-bit unsigned immediate");
6116 case Match_UImm10_0
:
6117 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6118 "expected 10-bit unsigned immediate");
6119 case Match_SImm10_0
:
6120 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6121 "expected 10-bit signed immediate");
6122 case Match_SImm11_0
:
6123 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6124 "expected 11-bit signed immediate");
6126 case Match_UImm16_Relaxed
:
6127 case Match_UImm16_AltRelaxed
:
6128 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6129 "expected 16-bit unsigned immediate");
6131 case Match_SImm16_Relaxed
:
6132 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6133 "expected 16-bit signed immediate");
6134 case Match_SImm19_Lsl2
:
6135 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6136 "expected both 19-bit signed immediate and multiple of 4");
6137 case Match_UImm20_0
:
6138 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6139 "expected 20-bit unsigned immediate");
6140 case Match_UImm26_0
:
6141 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6142 "expected 26-bit unsigned immediate");
6144 case Match_SImm32_Relaxed
:
6145 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6146 "expected 32-bit signed immediate");
6147 case Match_UImm32_Coerced
:
6148 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6149 "expected 32-bit immediate");
6150 case Match_MemSImm9
:
6151 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6152 "expected memory with 9-bit signed offset");
6153 case Match_MemSImm10
:
6154 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6155 "expected memory with 10-bit signed offset");
6156 case Match_MemSImm10Lsl1
:
6157 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6158 "expected memory with 11-bit signed offset and multiple of 2");
6159 case Match_MemSImm10Lsl2
:
6160 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6161 "expected memory with 12-bit signed offset and multiple of 4");
6162 case Match_MemSImm10Lsl3
:
6163 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6164 "expected memory with 13-bit signed offset and multiple of 8");
6165 case Match_MemSImm11
:
6166 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6167 "expected memory with 11-bit signed offset");
6168 case Match_MemSImm12
:
6169 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6170 "expected memory with 12-bit signed offset");
6171 case Match_MemSImm16
:
6172 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6173 "expected memory with 16-bit signed offset");
6174 case Match_MemSImmPtr
:
6175 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
6176 "expected memory with 32-bit signed offset");
6177 case Match_RequiresPosSizeRange0_32
: {
6178 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
6179 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
6180 return Error(ErrorStart
, "size plus position are not in the range 0 .. 32",
6181 SMRange(ErrorStart
, ErrorEnd
));
6183 case Match_RequiresPosSizeUImm6
: {
6184 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
6185 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
6186 return Error(ErrorStart
, "size plus position are not in the range 1 .. 63",
6187 SMRange(ErrorStart
, ErrorEnd
));
6189 case Match_RequiresPosSizeRange33_64
: {
6190 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
6191 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
6192 return Error(ErrorStart
, "size plus position are not in the range 33 .. 64",
6193 SMRange(ErrorStart
, ErrorEnd
));
6197 llvm_unreachable("Implement any new match types added!");
6200 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex
, SMLoc Loc
) {
6201 if (RegIndex
!= 0 && AssemblerOptions
.back()->getATRegIndex() == RegIndex
)
6202 Warning(Loc
, "used $at (currently $" + Twine(RegIndex
) +
6203 ") without \".set noat\"");
6206 void MipsAsmParser::warnIfNoMacro(SMLoc Loc
) {
6207 if (!AssemblerOptions
.back()->isMacro())
6208 Warning(Loc
, "macro instruction expanded into multiple instructions");
6211 void MipsAsmParser::ConvertXWPOperands(MCInst
&Inst
,
6212 const OperandVector
&Operands
) {
6214 (Inst
.getOpcode() == Mips::LWP_MM
|| Inst
.getOpcode() == Mips::SWP_MM
) &&
6215 "Unexpected instruction!");
6216 ((MipsOperand
&)*Operands
[1]).addGPR32ZeroAsmRegOperands(Inst
, 1);
6217 int NextReg
= nextReg(((MipsOperand
&)*Operands
[1]).getGPR32Reg());
6218 Inst
.addOperand(MCOperand::createReg(NextReg
));
6219 ((MipsOperand
&)*Operands
[2]).addMemOperands(Inst
, 2);
6223 MipsAsmParser::printWarningWithFixIt(const Twine
&Msg
, const Twine
&FixMsg
,
6224 SMRange Range
, bool ShowColors
) {
6225 getSourceManager().PrintMessage(Range
.Start
, SourceMgr::DK_Warning
, Msg
,
6226 Range
, SMFixIt(Range
, FixMsg
),
6230 int MipsAsmParser::matchCPURegisterName(StringRef Name
) {
6233 CC
= StringSwitch
<unsigned>(Name
)
6235 .Cases("at", "AT", 1)
6269 if (!(isABI_N32() || isABI_N64()))
6272 if (12 <= CC
&& CC
<= 15) {
6273 // Name is one of t4-t7
6274 AsmToken RegTok
= getLexer().peekTok();
6275 SMRange RegRange
= RegTok
.getLocRange();
6277 StringRef FixedName
= StringSwitch
<StringRef
>(Name
)
6283 assert(FixedName
!= "" && "Register name is not one of t4-t7.");
6285 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6286 "Did you mean $" + FixedName
+ "?", RegRange
);
6289 // Although SGI documentation just cuts out t0-t3 for n32/n64,
6290 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
6291 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
6292 if (8 <= CC
&& CC
<= 11)
6296 CC
= StringSwitch
<unsigned>(Name
)
6308 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name
) {
6311 CC
= StringSwitch
<unsigned>(Name
)
6312 .Case("hwr_cpunum", 0)
6313 .Case("hwr_synci_step", 1)
6315 .Case("hwr_ccres", 3)
6316 .Case("hwr_ulr", 29)
6322 int MipsAsmParser::matchFPURegisterName(StringRef Name
) {
6323 if (Name
[0] == 'f') {
6324 StringRef NumString
= Name
.substr(1);
6326 if (NumString
.getAsInteger(10, IntVal
))
6327 return -1; // This is not an integer.
6328 if (IntVal
> 31) // Maximum index for fpu register.
6335 int MipsAsmParser::matchFCCRegisterName(StringRef Name
) {
6336 if (Name
.starts_with("fcc")) {
6337 StringRef NumString
= Name
.substr(3);
6339 if (NumString
.getAsInteger(10, IntVal
))
6340 return -1; // This is not an integer.
6341 if (IntVal
> 7) // There are only 8 fcc registers.
6348 int MipsAsmParser::matchACRegisterName(StringRef Name
) {
6349 if (Name
.starts_with("ac")) {
6350 StringRef NumString
= Name
.substr(2);
6352 if (NumString
.getAsInteger(10, IntVal
))
6353 return -1; // This is not an integer.
6354 if (IntVal
> 3) // There are only 3 acc registers.
6361 int MipsAsmParser::matchMSA128RegisterName(StringRef Name
) {
6364 if (Name
.front() != 'w' || Name
.drop_front(1).getAsInteger(10, IntVal
))
6373 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name
) {
6376 CC
= StringSwitch
<unsigned>(Name
)
6379 .Case("msaaccess", 2)
6381 .Case("msamodify", 4)
6382 .Case("msarequest", 5)
6384 .Case("msaunmap", 7)
6390 bool MipsAsmParser::canUseATReg() {
6391 return AssemblerOptions
.back()->getATRegIndex() != 0;
6394 unsigned MipsAsmParser::getATReg(SMLoc Loc
) {
6395 unsigned ATIndex
= AssemblerOptions
.back()->getATRegIndex();
6397 reportParseError(Loc
,
6398 "pseudo-instruction requires $at, which is not available");
6401 unsigned AT
= getReg(
6402 (isGP64bit()) ? Mips::GPR64RegClassID
: Mips::GPR32RegClassID
, ATIndex
);
6406 unsigned MipsAsmParser::getReg(int RC
, int RegNo
) {
6407 return *(getContext().getRegisterInfo()->getRegClass(RC
).begin() + RegNo
);
6410 bool MipsAsmParser::parseOperand(OperandVector
&Operands
, StringRef Mnemonic
) {
6411 MCAsmParser
&Parser
= getParser();
6412 LLVM_DEBUG(dbgs() << "parseOperand\n");
6414 // Check if the current operand has a custom associated parser, if so, try to
6415 // custom parse the operand, or fallback to the general approach.
6416 // Setting the third parameter to true tells the parser to keep parsing even
6417 // if the operands are not supported with the current feature set. In this
6418 // case, the instruction matcher will output a "instruction requires a CPU
6419 // feature not currently enabled" error. If this were false, the parser would
6420 // stop here and output a less useful "invalid operand" error.
6421 ParseStatus Res
= MatchOperandParserImpl(Operands
, Mnemonic
, true);
6422 if (Res
.isSuccess())
6424 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6425 // there was a match, but an error occurred, in which case, just return that
6426 // the operand parsing failed.
6427 if (Res
.isFailure())
6430 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6432 switch (getLexer().getKind()) {
6433 case AsmToken::Dollar
: {
6434 // Parse the register.
6435 SMLoc S
= Parser
.getTok().getLoc();
6437 // Almost all registers have been parsed by custom parsers. There is only
6438 // one exception to this. $zero (and it's alias $0) will reach this point
6439 // for div, divu, and similar instructions because it is not an operand
6440 // to the instruction definition but an explicit register. Special case
6441 // this situation for now.
6442 if (!parseAnyRegister(Operands
).isNoMatch())
6445 // Maybe it is a symbol reference.
6446 StringRef Identifier
;
6447 if (Parser
.parseIdentifier(Identifier
))
6450 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6451 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
6452 // Otherwise create a symbol reference.
6453 const MCExpr
*SymRef
=
6454 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
6456 Operands
.push_back(MipsOperand::CreateImm(SymRef
, S
, E
, *this));
6460 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6463 SMLoc S
= Parser
.getTok().getLoc(); // Start location of the operand.
6464 if (getParser().parseExpression(Expr
))
6467 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6469 Operands
.push_back(MipsOperand::CreateImm(Expr
, S
, E
, *this));
6472 } // switch(getLexer().getKind())
6476 bool MipsAsmParser::parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
6478 return !tryParseRegister(Reg
, StartLoc
, EndLoc
).isSuccess();
6481 ParseStatus
MipsAsmParser::tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
6483 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Operands
;
6484 ParseStatus Res
= parseAnyRegister(Operands
);
6485 if (Res
.isSuccess()) {
6486 assert(Operands
.size() == 1);
6487 MipsOperand
&Operand
= static_cast<MipsOperand
&>(*Operands
.front());
6488 StartLoc
= Operand
.getStartLoc();
6489 EndLoc
= Operand
.getEndLoc();
6491 // AFAIK, we only support numeric registers and named GPR's in CFI
6493 // Don't worry about eating tokens before failing. Using an unrecognised
6494 // register is a parse error.
6495 if (Operand
.isGPRAsmReg()) {
6496 // Resolve to GPR32 or GPR64 appropriately.
6497 Reg
= isGP64bit() ? Operand
.getGPR64Reg() : Operand
.getGPR32Reg();
6500 return (Reg
== (unsigned)-1) ? ParseStatus::NoMatch
: ParseStatus::Success
;
6503 assert(Operands
.size() == 0);
6504 return (Reg
== (unsigned)-1) ? ParseStatus::NoMatch
: ParseStatus::Success
;
6507 bool MipsAsmParser::parseMemOffset(const MCExpr
*&Res
, bool isParenExpr
) {
6511 return getParser().parseParenExprOfDepth(0, Res
, S
);
6512 return getParser().parseExpression(Res
);
6515 ParseStatus
MipsAsmParser::parseMemOperand(OperandVector
&Operands
) {
6516 MCAsmParser
&Parser
= getParser();
6517 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6518 const MCExpr
*IdVal
= nullptr;
6520 bool isParenExpr
= false;
6521 ParseStatus Res
= ParseStatus::NoMatch
;
6522 // First operand is the offset.
6523 S
= Parser
.getTok().getLoc();
6525 if (getLexer().getKind() == AsmToken::LParen
) {
6530 if (getLexer().getKind() != AsmToken::Dollar
) {
6531 if (parseMemOffset(IdVal
, isParenExpr
))
6532 return ParseStatus::Failure
;
6534 const AsmToken
&Tok
= Parser
.getTok(); // Get the next token.
6535 if (Tok
.isNot(AsmToken::LParen
)) {
6536 MipsOperand
&Mnemonic
= static_cast<MipsOperand
&>(*Operands
[0]);
6537 if (Mnemonic
.getToken() == "la" || Mnemonic
.getToken() == "dla") {
6539 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6540 Operands
.push_back(MipsOperand::CreateImm(IdVal
, S
, E
, *this));
6541 return ParseStatus::Success
;
6543 if (Tok
.is(AsmToken::EndOfStatement
)) {
6545 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6547 // Zero register assumed, add a memory operand with ZERO as its base.
6548 // "Base" will be managed by k_Memory.
6549 auto Base
= MipsOperand::createGPRReg(
6550 0, "0", getContext().getRegisterInfo(), S
, E
, *this);
6552 MipsOperand::CreateMem(std::move(Base
), IdVal
, S
, E
, *this));
6553 return ParseStatus::Success
;
6555 MCBinaryExpr::Opcode Opcode
;
6556 // GAS and LLVM treat comparison operators different. GAS will generate -1
6557 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6558 // highly unlikely to be found in a memory offset expression, we don't
6560 switch (Tok
.getKind()) {
6561 case AsmToken::Plus
:
6562 Opcode
= MCBinaryExpr::Add
;
6565 case AsmToken::Minus
:
6566 Opcode
= MCBinaryExpr::Sub
;
6569 case AsmToken::Star
:
6570 Opcode
= MCBinaryExpr::Mul
;
6573 case AsmToken::Pipe
:
6574 Opcode
= MCBinaryExpr::Or
;
6578 Opcode
= MCBinaryExpr::And
;
6581 case AsmToken::LessLess
:
6582 Opcode
= MCBinaryExpr::Shl
;
6585 case AsmToken::GreaterGreater
:
6586 Opcode
= MCBinaryExpr::LShr
;
6589 case AsmToken::Caret
:
6590 Opcode
= MCBinaryExpr::Xor
;
6593 case AsmToken::Slash
:
6594 Opcode
= MCBinaryExpr::Div
;
6597 case AsmToken::Percent
:
6598 Opcode
= MCBinaryExpr::Mod
;
6602 return Error(Parser
.getTok().getLoc(), "'(' or expression expected");
6604 const MCExpr
* NextExpr
;
6605 if (getParser().parseExpression(NextExpr
))
6606 return ParseStatus::Failure
;
6607 IdVal
= MCBinaryExpr::create(Opcode
, IdVal
, NextExpr
, getContext());
6610 Parser
.Lex(); // Eat the '(' token.
6613 Res
= parseAnyRegister(Operands
);
6614 if (!Res
.isSuccess())
6617 if (Parser
.getTok().isNot(AsmToken::RParen
))
6618 return Error(Parser
.getTok().getLoc(), "')' expected");
6620 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6622 Parser
.Lex(); // Eat the ')' token.
6625 IdVal
= MCConstantExpr::create(0, getContext());
6627 // Replace the register operand with the memory operand.
6628 std::unique_ptr
<MipsOperand
> op(
6629 static_cast<MipsOperand
*>(Operands
.back().release()));
6630 // Remove the register from the operands.
6631 // "op" will be managed by k_Memory.
6632 Operands
.pop_back();
6633 // Add the memory operand.
6634 if (const MCBinaryExpr
*BE
= dyn_cast
<MCBinaryExpr
>(IdVal
)) {
6636 if (IdVal
->evaluateAsAbsolute(Imm
))
6637 IdVal
= MCConstantExpr::create(Imm
, getContext());
6638 else if (BE
->getLHS()->getKind() != MCExpr::SymbolRef
)
6639 IdVal
= MCBinaryExpr::create(BE
->getOpcode(), BE
->getRHS(), BE
->getLHS(),
6643 Operands
.push_back(MipsOperand::CreateMem(std::move(op
), IdVal
, S
, E
, *this));
6644 return ParseStatus::Success
;
6647 bool MipsAsmParser::searchSymbolAlias(OperandVector
&Operands
) {
6648 MCAsmParser
&Parser
= getParser();
6649 MCSymbol
*Sym
= getContext().lookupSymbol(Parser
.getTok().getIdentifier());
6653 SMLoc S
= Parser
.getTok().getLoc();
6654 if (Sym
->isVariable()) {
6655 const MCExpr
*Expr
= Sym
->getVariableValue();
6656 if (Expr
->getKind() == MCExpr::SymbolRef
) {
6657 const MCSymbolRefExpr
*Ref
= static_cast<const MCSymbolRefExpr
*>(Expr
);
6658 StringRef DefSymbol
= Ref
->getSymbol().getName();
6659 if (DefSymbol
.starts_with("$")) {
6661 matchAnyRegisterNameWithoutDollar(Operands
, DefSymbol
.substr(1), S
);
6662 if (Res
.isSuccess()) {
6666 if (Res
.isFailure())
6667 llvm_unreachable("Should never fail");
6670 } else if (Sym
->isUnset()) {
6671 // If symbol is unset, it might be created in the `parseSetAssignment`
6672 // routine as an alias for a numeric register name.
6673 // Lookup in the aliases list.
6674 auto Entry
= RegisterSets
.find(Sym
->getName());
6675 if (Entry
!= RegisterSets
.end()) {
6677 matchAnyRegisterWithoutDollar(Operands
, Entry
->getValue(), S
);
6678 if (Res
.isSuccess()) {
6688 ParseStatus
MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6689 OperandVector
&Operands
, StringRef Identifier
, SMLoc S
) {
6690 int Index
= matchCPURegisterName(Identifier
);
6692 Operands
.push_back(MipsOperand::createGPRReg(
6693 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6694 getLexer().getLoc(), *this));
6695 return ParseStatus::Success
;
6698 Index
= matchHWRegsRegisterName(Identifier
);
6700 Operands
.push_back(MipsOperand::createHWRegsReg(
6701 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6702 getLexer().getLoc(), *this));
6703 return ParseStatus::Success
;
6706 Index
= matchFPURegisterName(Identifier
);
6708 Operands
.push_back(MipsOperand::createFGRReg(
6709 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6710 getLexer().getLoc(), *this));
6711 return ParseStatus::Success
;
6714 Index
= matchFCCRegisterName(Identifier
);
6716 Operands
.push_back(MipsOperand::createFCCReg(
6717 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6718 getLexer().getLoc(), *this));
6719 return ParseStatus::Success
;
6722 Index
= matchACRegisterName(Identifier
);
6724 Operands
.push_back(MipsOperand::createACCReg(
6725 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6726 getLexer().getLoc(), *this));
6727 return ParseStatus::Success
;
6730 Index
= matchMSA128RegisterName(Identifier
);
6732 Operands
.push_back(MipsOperand::createMSA128Reg(
6733 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6734 getLexer().getLoc(), *this));
6735 return ParseStatus::Success
;
6738 Index
= matchMSA128CtrlRegisterName(Identifier
);
6740 Operands
.push_back(MipsOperand::createMSACtrlReg(
6741 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6742 getLexer().getLoc(), *this));
6743 return ParseStatus::Success
;
6746 return ParseStatus::NoMatch
;
6750 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector
&Operands
,
6751 const AsmToken
&Token
, SMLoc S
) {
6752 if (Token
.is(AsmToken::Identifier
)) {
6753 LLVM_DEBUG(dbgs() << ".. identifier\n");
6754 StringRef Identifier
= Token
.getIdentifier();
6755 return matchAnyRegisterNameWithoutDollar(Operands
, Identifier
, S
);
6757 if (Token
.is(AsmToken::Integer
)) {
6758 LLVM_DEBUG(dbgs() << ".. integer\n");
6759 int64_t RegNum
= Token
.getIntVal();
6760 if (RegNum
< 0 || RegNum
> 31) {
6761 // Show the error, but treat invalid register
6762 // number as a normal one to continue parsing
6763 // and catch other possible errors.
6764 Error(getLexer().getLoc(), "invalid register number");
6766 Operands
.push_back(MipsOperand::createNumericReg(
6767 RegNum
, Token
.getString(), getContext().getRegisterInfo(), S
,
6768 Token
.getLoc(), *this));
6769 return ParseStatus::Success
;
6772 LLVM_DEBUG(dbgs() << Token
.getKind() << "\n");
6774 return ParseStatus::NoMatch
;
6778 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector
&Operands
, SMLoc S
) {
6779 auto Token
= getLexer().peekTok(false);
6780 return matchAnyRegisterWithoutDollar(Operands
, Token
, S
);
6783 ParseStatus
MipsAsmParser::parseAnyRegister(OperandVector
&Operands
) {
6784 MCAsmParser
&Parser
= getParser();
6785 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6787 auto Token
= Parser
.getTok();
6789 SMLoc S
= Token
.getLoc();
6791 if (Token
.isNot(AsmToken::Dollar
)) {
6792 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6793 if (Token
.is(AsmToken::Identifier
)) {
6794 if (searchSymbolAlias(Operands
))
6795 return ParseStatus::Success
;
6797 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6798 return ParseStatus::NoMatch
;
6800 LLVM_DEBUG(dbgs() << ".. $\n");
6802 ParseStatus Res
= matchAnyRegisterWithoutDollar(Operands
, S
);
6803 if (Res
.isSuccess()) {
6805 Parser
.Lex(); // identifier
6810 ParseStatus
MipsAsmParser::parseJumpTarget(OperandVector
&Operands
) {
6811 MCAsmParser
&Parser
= getParser();
6812 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6814 SMLoc S
= getLexer().getLoc();
6816 // Registers are a valid target and have priority over symbols.
6817 ParseStatus Res
= parseAnyRegister(Operands
);
6818 if (!Res
.isNoMatch())
6821 // Integers and expressions are acceptable
6822 const MCExpr
*Expr
= nullptr;
6823 if (Parser
.parseExpression(Expr
)) {
6824 // We have no way of knowing if a symbol was consumed so we must ParseFail
6825 return ParseStatus::Failure
;
6828 MipsOperand::CreateImm(Expr
, S
, getLexer().getLoc(), *this));
6829 return ParseStatus::Success
;
6832 ParseStatus
MipsAsmParser::parseInvNum(OperandVector
&Operands
) {
6833 MCAsmParser
&Parser
= getParser();
6834 const MCExpr
*IdVal
;
6835 // If the first token is '$' we may have register operand. We have to reject
6836 // cases where it is not a register. Complicating the matter is that
6837 // register names are not reserved across all ABIs.
6838 // Peek past the dollar to see if it's a register name for this ABI.
6839 SMLoc S
= Parser
.getTok().getLoc();
6840 if (Parser
.getTok().is(AsmToken::Dollar
)) {
6841 return matchCPURegisterName(Parser
.getLexer().peekTok().getString()) == -1
6842 ? ParseStatus::Failure
6843 : ParseStatus::NoMatch
;
6845 if (getParser().parseExpression(IdVal
))
6846 return ParseStatus::Failure
;
6847 const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(IdVal
);
6849 return ParseStatus::NoMatch
;
6850 int64_t Val
= MCE
->getValue();
6851 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6852 Operands
.push_back(MipsOperand::CreateImm(
6853 MCConstantExpr::create(0 - Val
, getContext()), S
, E
, *this));
6854 return ParseStatus::Success
;
6857 ParseStatus
MipsAsmParser::parseRegisterList(OperandVector
&Operands
) {
6858 MCAsmParser
&Parser
= getParser();
6859 SmallVector
<unsigned, 10> Regs
;
6861 unsigned PrevReg
= Mips::NoRegister
;
6862 bool RegRange
= false;
6863 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 8> TmpOperands
;
6865 if (Parser
.getTok().isNot(AsmToken::Dollar
))
6866 return ParseStatus::Failure
;
6868 SMLoc S
= Parser
.getTok().getLoc();
6869 while (parseAnyRegister(TmpOperands
).isSuccess()) {
6870 SMLoc E
= getLexer().getLoc();
6871 MipsOperand
&Reg
= static_cast<MipsOperand
&>(*TmpOperands
.back());
6872 RegNo
= isGP64bit() ? Reg
.getGPR64Reg() : Reg
.getGPR32Reg();
6874 // Remove last register operand because registers from register range
6875 // should be inserted first.
6876 if ((isGP64bit() && RegNo
== Mips::RA_64
) ||
6877 (!isGP64bit() && RegNo
== Mips::RA
)) {
6878 Regs
.push_back(RegNo
);
6880 unsigned TmpReg
= PrevReg
+ 1;
6881 while (TmpReg
<= RegNo
) {
6882 if ((((TmpReg
< Mips::S0
) || (TmpReg
> Mips::S7
)) && !isGP64bit()) ||
6883 (((TmpReg
< Mips::S0_64
) || (TmpReg
> Mips::S7_64
)) &&
6885 return Error(E
, "invalid register operand");
6888 Regs
.push_back(TmpReg
++);
6894 if ((PrevReg
== Mips::NoRegister
) &&
6895 ((isGP64bit() && (RegNo
!= Mips::S0_64
) && (RegNo
!= Mips::RA_64
)) ||
6896 (!isGP64bit() && (RegNo
!= Mips::S0
) && (RegNo
!= Mips::RA
))))
6897 return Error(E
, "$16 or $31 expected");
6898 if (!(((RegNo
== Mips::FP
|| RegNo
== Mips::RA
||
6899 (RegNo
>= Mips::S0
&& RegNo
<= Mips::S7
)) &&
6901 ((RegNo
== Mips::FP_64
|| RegNo
== Mips::RA_64
||
6902 (RegNo
>= Mips::S0_64
&& RegNo
<= Mips::S7_64
)) &&
6904 return Error(E
, "invalid register operand");
6905 if ((PrevReg
!= Mips::NoRegister
) && (RegNo
!= PrevReg
+ 1) &&
6906 ((RegNo
!= Mips::FP
&& RegNo
!= Mips::RA
&& !isGP64bit()) ||
6907 (RegNo
!= Mips::FP_64
&& RegNo
!= Mips::RA_64
&& isGP64bit())))
6908 return Error(E
, "consecutive register numbers expected");
6910 Regs
.push_back(RegNo
);
6913 if (Parser
.getTok().is(AsmToken::Minus
))
6916 if (!Parser
.getTok().isNot(AsmToken::Minus
) &&
6917 !Parser
.getTok().isNot(AsmToken::Comma
))
6918 return Error(E
, "',' or '-' expected");
6920 Lex(); // Consume comma or minus
6921 if (Parser
.getTok().isNot(AsmToken::Dollar
))
6927 SMLoc E
= Parser
.getTok().getLoc();
6928 Operands
.push_back(MipsOperand::CreateRegList(Regs
, S
, E
, *this));
6929 parseMemOperand(Operands
);
6930 return ParseStatus::Success
;
6933 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6935 /// ::= '(', register, ')'
6936 /// handle it before we iterate so we don't get tripped up by the lack of
6938 bool MipsAsmParser::parseParenSuffix(StringRef Name
, OperandVector
&Operands
) {
6939 MCAsmParser
&Parser
= getParser();
6940 if (getLexer().is(AsmToken::LParen
)) {
6942 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6944 if (parseOperand(Operands
, Name
)) {
6945 SMLoc Loc
= getLexer().getLoc();
6946 return Error(Loc
, "unexpected token in argument list");
6948 if (Parser
.getTok().isNot(AsmToken::RParen
)) {
6949 SMLoc Loc
= getLexer().getLoc();
6950 return Error(Loc
, "unexpected token, expected ')'");
6953 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6959 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6960 /// either one of these.
6961 /// ::= '[', register, ']'
6962 /// ::= '[', integer, ']'
6963 /// handle it before we iterate so we don't get tripped up by the lack of
6965 bool MipsAsmParser::parseBracketSuffix(StringRef Name
,
6966 OperandVector
&Operands
) {
6967 MCAsmParser
&Parser
= getParser();
6968 if (getLexer().is(AsmToken::LBrac
)) {
6970 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6972 if (parseOperand(Operands
, Name
)) {
6973 SMLoc Loc
= getLexer().getLoc();
6974 return Error(Loc
, "unexpected token in argument list");
6976 if (Parser
.getTok().isNot(AsmToken::RBrac
)) {
6977 SMLoc Loc
= getLexer().getLoc();
6978 return Error(Loc
, "unexpected token, expected ']'");
6981 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6987 static std::string
MipsMnemonicSpellCheck(StringRef S
, const FeatureBitset
&FBS
,
6988 unsigned VariantID
= 0);
6990 bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand
&Op1
,
6991 const MCParsedAsmOperand
&Op2
) const {
6992 // This target-overriden function exists to maintain current behaviour for
6994 // dahi $3, $3, 0x5678
6995 // as tested in test/MC/Mips/mips64r6/valid.s.
6996 // FIXME: Should this test actually fail with an error? If so, then remove
6997 // this overloaded method.
6998 if (!Op1
.isReg() || !Op2
.isReg())
7000 return Op1
.getReg() == Op2
.getReg();
7003 bool MipsAsmParser::parseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
7004 SMLoc NameLoc
, OperandVector
&Operands
) {
7005 MCAsmParser
&Parser
= getParser();
7006 LLVM_DEBUG(dbgs() << "parseInstruction\n");
7008 // We have reached first instruction, module directive are now forbidden.
7009 getTargetStreamer().forbidModuleDirective();
7011 // Check if we have valid mnemonic
7012 if (!mnemonicIsValid(Name
, 0)) {
7013 FeatureBitset FBS
= ComputeAvailableFeatures(getSTI().getFeatureBits());
7014 std::string Suggestion
= MipsMnemonicSpellCheck(Name
, FBS
);
7015 return Error(NameLoc
, "unknown instruction" + Suggestion
);
7017 // First operand in MCInst is instruction mnemonic.
7018 Operands
.push_back(MipsOperand::CreateToken(Name
, NameLoc
, *this));
7020 // Read the remaining operands.
7021 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7022 // Read the first operand.
7023 if (parseOperand(Operands
, Name
)) {
7024 SMLoc Loc
= getLexer().getLoc();
7025 return Error(Loc
, "unexpected token in argument list");
7027 if (getLexer().is(AsmToken::LBrac
) && parseBracketSuffix(Name
, Operands
))
7029 // AFAIK, parenthesis suffixes are never on the first operand
7031 while (getLexer().is(AsmToken::Comma
)) {
7032 Parser
.Lex(); // Eat the comma.
7033 // Parse and remember the operand.
7034 if (parseOperand(Operands
, Name
)) {
7035 SMLoc Loc
= getLexer().getLoc();
7036 return Error(Loc
, "unexpected token in argument list");
7038 // Parse bracket and parenthesis suffixes before we iterate
7039 if (getLexer().is(AsmToken::LBrac
)) {
7040 if (parseBracketSuffix(Name
, Operands
))
7042 } else if (getLexer().is(AsmToken::LParen
) &&
7043 parseParenSuffix(Name
, Operands
))
7047 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7048 SMLoc Loc
= getLexer().getLoc();
7049 return Error(Loc
, "unexpected token in argument list");
7051 Parser
.Lex(); // Consume the EndOfStatement.
7055 // FIXME: Given that these have the same name, these should both be
7056 // consistent on affecting the Parser.
7057 bool MipsAsmParser::reportParseError(const Twine
&ErrorMsg
) {
7058 SMLoc Loc
= getLexer().getLoc();
7059 return Error(Loc
, ErrorMsg
);
7062 bool MipsAsmParser::reportParseError(SMLoc Loc
, const Twine
&ErrorMsg
) {
7063 return Error(Loc
, ErrorMsg
);
7066 bool MipsAsmParser::parseSetNoAtDirective() {
7067 MCAsmParser
&Parser
= getParser();
7068 // Line should look like: ".set noat".
7070 // Set the $at register to $0.
7071 AssemblerOptions
.back()->setATRegIndex(0);
7073 Parser
.Lex(); // Eat "noat".
7075 // If this is not the end of the statement, report an error.
7076 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7077 reportParseError("unexpected token, expected end of statement");
7081 getTargetStreamer().emitDirectiveSetNoAt();
7082 Parser
.Lex(); // Consume the EndOfStatement.
7086 bool MipsAsmParser::parseSetAtDirective() {
7087 // Line can be: ".set at", which sets $at to $1
7088 // or ".set at=$reg", which sets $at to $reg.
7089 MCAsmParser
&Parser
= getParser();
7090 Parser
.Lex(); // Eat "at".
7092 if (getLexer().is(AsmToken::EndOfStatement
)) {
7093 // No register was specified, so we set $at to $1.
7094 AssemblerOptions
.back()->setATRegIndex(1);
7096 getTargetStreamer().emitDirectiveSetAt();
7097 Parser
.Lex(); // Consume the EndOfStatement.
7101 if (getLexer().isNot(AsmToken::Equal
)) {
7102 reportParseError("unexpected token, expected equals sign");
7105 Parser
.Lex(); // Eat "=".
7107 if (getLexer().isNot(AsmToken::Dollar
)) {
7108 if (getLexer().is(AsmToken::EndOfStatement
)) {
7109 reportParseError("no register specified");
7112 reportParseError("unexpected token, expected dollar sign '$'");
7116 Parser
.Lex(); // Eat "$".
7118 // Find out what "reg" is.
7120 const AsmToken
&Reg
= Parser
.getTok();
7121 if (Reg
.is(AsmToken::Identifier
)) {
7122 AtRegNo
= matchCPURegisterName(Reg
.getIdentifier());
7123 } else if (Reg
.is(AsmToken::Integer
)) {
7124 AtRegNo
= Reg
.getIntVal();
7126 reportParseError("unexpected token, expected identifier or integer");
7130 // Check if $reg is a valid register. If it is, set $at to $reg.
7131 if (!AssemblerOptions
.back()->setATRegIndex(AtRegNo
)) {
7132 reportParseError("invalid register");
7135 Parser
.Lex(); // Eat "reg".
7137 // If this is not the end of the statement, report an error.
7138 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7139 reportParseError("unexpected token, expected end of statement");
7143 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo
);
7145 Parser
.Lex(); // Consume the EndOfStatement.
7149 bool MipsAsmParser::parseSetReorderDirective() {
7150 MCAsmParser
&Parser
= getParser();
7152 // If this is not the end of the statement, report an error.
7153 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7154 reportParseError("unexpected token, expected end of statement");
7157 AssemblerOptions
.back()->setReorder();
7158 getTargetStreamer().emitDirectiveSetReorder();
7159 Parser
.Lex(); // Consume the EndOfStatement.
7163 bool MipsAsmParser::parseSetNoReorderDirective() {
7164 MCAsmParser
&Parser
= getParser();
7166 // If this is not the end of the statement, report an error.
7167 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7168 reportParseError("unexpected token, expected end of statement");
7171 AssemblerOptions
.back()->setNoReorder();
7172 getTargetStreamer().emitDirectiveSetNoReorder();
7173 Parser
.Lex(); // Consume the EndOfStatement.
7177 bool MipsAsmParser::parseSetMacroDirective() {
7178 MCAsmParser
&Parser
= getParser();
7180 // If this is not the end of the statement, report an error.
7181 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7182 reportParseError("unexpected token, expected end of statement");
7185 AssemblerOptions
.back()->setMacro();
7186 getTargetStreamer().emitDirectiveSetMacro();
7187 Parser
.Lex(); // Consume the EndOfStatement.
7191 bool MipsAsmParser::parseSetNoMacroDirective() {
7192 MCAsmParser
&Parser
= getParser();
7194 // If this is not the end of the statement, report an error.
7195 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7196 reportParseError("unexpected token, expected end of statement");
7199 if (AssemblerOptions
.back()->isReorder()) {
7200 reportParseError("`noreorder' must be set before `nomacro'");
7203 AssemblerOptions
.back()->setNoMacro();
7204 getTargetStreamer().emitDirectiveSetNoMacro();
7205 Parser
.Lex(); // Consume the EndOfStatement.
7209 bool MipsAsmParser::parseSetMsaDirective() {
7210 MCAsmParser
&Parser
= getParser();
7213 // If this is not the end of the statement, report an error.
7214 if (getLexer().isNot(AsmToken::EndOfStatement
))
7215 return reportParseError("unexpected token, expected end of statement");
7217 setFeatureBits(Mips::FeatureMSA
, "msa");
7218 getTargetStreamer().emitDirectiveSetMsa();
7222 bool MipsAsmParser::parseSetNoMsaDirective() {
7223 MCAsmParser
&Parser
= getParser();
7226 // If this is not the end of the statement, report an error.
7227 if (getLexer().isNot(AsmToken::EndOfStatement
))
7228 return reportParseError("unexpected token, expected end of statement");
7230 clearFeatureBits(Mips::FeatureMSA
, "msa");
7231 getTargetStreamer().emitDirectiveSetNoMsa();
7235 bool MipsAsmParser::parseSetNoDspDirective() {
7236 MCAsmParser
&Parser
= getParser();
7237 Parser
.Lex(); // Eat "nodsp".
7239 // If this is not the end of the statement, report an error.
7240 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7241 reportParseError("unexpected token, expected end of statement");
7245 clearFeatureBits(Mips::FeatureDSP
, "dsp");
7246 getTargetStreamer().emitDirectiveSetNoDsp();
7250 bool MipsAsmParser::parseSetNoMips3DDirective() {
7251 MCAsmParser
&Parser
= getParser();
7252 Parser
.Lex(); // Eat "nomips3d".
7254 // If this is not the end of the statement, report an error.
7255 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7256 reportParseError("unexpected token, expected end of statement");
7260 clearFeatureBits(Mips::FeatureMips3D
, "mips3d");
7261 getTargetStreamer().emitDirectiveSetNoMips3D();
7265 bool MipsAsmParser::parseSetMips16Directive() {
7266 MCAsmParser
&Parser
= getParser();
7267 Parser
.Lex(); // Eat "mips16".
7269 // If this is not the end of the statement, report an error.
7270 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7271 reportParseError("unexpected token, expected end of statement");
7275 setFeatureBits(Mips::FeatureMips16
, "mips16");
7276 getTargetStreamer().emitDirectiveSetMips16();
7277 Parser
.Lex(); // Consume the EndOfStatement.
7281 bool MipsAsmParser::parseSetNoMips16Directive() {
7282 MCAsmParser
&Parser
= getParser();
7283 Parser
.Lex(); // Eat "nomips16".
7285 // If this is not the end of the statement, report an error.
7286 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7287 reportParseError("unexpected token, expected end of statement");
7291 clearFeatureBits(Mips::FeatureMips16
, "mips16");
7292 getTargetStreamer().emitDirectiveSetNoMips16();
7293 Parser
.Lex(); // Consume the EndOfStatement.
7297 bool MipsAsmParser::parseSetFpDirective() {
7298 MCAsmParser
&Parser
= getParser();
7299 MipsABIFlagsSection::FpABIKind FpAbiVal
;
7300 // Line can be: .set fp=32
7303 Parser
.Lex(); // Eat fp token
7304 AsmToken Tok
= Parser
.getTok();
7305 if (Tok
.isNot(AsmToken::Equal
)) {
7306 reportParseError("unexpected token, expected equals sign '='");
7309 Parser
.Lex(); // Eat '=' token.
7310 Tok
= Parser
.getTok();
7312 if (!parseFpABIValue(FpAbiVal
, ".set"))
7315 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7316 reportParseError("unexpected token, expected end of statement");
7319 getTargetStreamer().emitDirectiveSetFp(FpAbiVal
);
7320 Parser
.Lex(); // Consume the EndOfStatement.
7324 bool MipsAsmParser::parseSetOddSPRegDirective() {
7325 MCAsmParser
&Parser
= getParser();
7327 Parser
.Lex(); // Eat "oddspreg".
7328 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7329 reportParseError("unexpected token, expected end of statement");
7333 clearFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
7334 getTargetStreamer().emitDirectiveSetOddSPReg();
7338 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7339 MCAsmParser
&Parser
= getParser();
7341 Parser
.Lex(); // Eat "nooddspreg".
7342 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7343 reportParseError("unexpected token, expected end of statement");
7347 setFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
7348 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7352 bool MipsAsmParser::parseSetMtDirective() {
7353 MCAsmParser
&Parser
= getParser();
7354 Parser
.Lex(); // Eat "mt".
7356 // If this is not the end of the statement, report an error.
7357 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7358 reportParseError("unexpected token, expected end of statement");
7362 setFeatureBits(Mips::FeatureMT
, "mt");
7363 getTargetStreamer().emitDirectiveSetMt();
7364 Parser
.Lex(); // Consume the EndOfStatement.
7368 bool MipsAsmParser::parseSetNoMtDirective() {
7369 MCAsmParser
&Parser
= getParser();
7370 Parser
.Lex(); // Eat "nomt".
7372 // If this is not the end of the statement, report an error.
7373 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7374 reportParseError("unexpected token, expected end of statement");
7378 clearFeatureBits(Mips::FeatureMT
, "mt");
7380 getTargetStreamer().emitDirectiveSetNoMt();
7381 Parser
.Lex(); // Consume the EndOfStatement.
7385 bool MipsAsmParser::parseSetNoCRCDirective() {
7386 MCAsmParser
&Parser
= getParser();
7387 Parser
.Lex(); // Eat "nocrc".
7389 // If this is not the end of the statement, report an error.
7390 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7391 reportParseError("unexpected token, expected end of statement");
7395 clearFeatureBits(Mips::FeatureCRC
, "crc");
7397 getTargetStreamer().emitDirectiveSetNoCRC();
7398 Parser
.Lex(); // Consume the EndOfStatement.
7402 bool MipsAsmParser::parseSetNoVirtDirective() {
7403 MCAsmParser
&Parser
= getParser();
7404 Parser
.Lex(); // Eat "novirt".
7406 // If this is not the end of the statement, report an error.
7407 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7408 reportParseError("unexpected token, expected end of statement");
7412 clearFeatureBits(Mips::FeatureVirt
, "virt");
7414 getTargetStreamer().emitDirectiveSetNoVirt();
7415 Parser
.Lex(); // Consume the EndOfStatement.
7419 bool MipsAsmParser::parseSetNoGINVDirective() {
7420 MCAsmParser
&Parser
= getParser();
7421 Parser
.Lex(); // Eat "noginv".
7423 // If this is not the end of the statement, report an error.
7424 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7425 reportParseError("unexpected token, expected end of statement");
7429 clearFeatureBits(Mips::FeatureGINV
, "ginv");
7431 getTargetStreamer().emitDirectiveSetNoGINV();
7432 Parser
.Lex(); // Consume the EndOfStatement.
7436 bool MipsAsmParser::parseSetPopDirective() {
7437 MCAsmParser
&Parser
= getParser();
7438 SMLoc Loc
= getLexer().getLoc();
7441 if (getLexer().isNot(AsmToken::EndOfStatement
))
7442 return reportParseError("unexpected token, expected end of statement");
7444 // Always keep an element on the options "stack" to prevent the user
7445 // from changing the initial options. This is how we remember them.
7446 if (AssemblerOptions
.size() == 2)
7447 return reportParseError(Loc
, ".set pop with no .set push");
7449 MCSubtargetInfo
&STI
= copySTI();
7450 AssemblerOptions
.pop_back();
7451 setAvailableFeatures(
7452 ComputeAvailableFeatures(AssemblerOptions
.back()->getFeatures()));
7453 STI
.setFeatureBits(AssemblerOptions
.back()->getFeatures());
7455 getTargetStreamer().emitDirectiveSetPop();
7459 bool MipsAsmParser::parseSetPushDirective() {
7460 MCAsmParser
&Parser
= getParser();
7462 if (getLexer().isNot(AsmToken::EndOfStatement
))
7463 return reportParseError("unexpected token, expected end of statement");
7465 // Create a copy of the current assembler options environment and push it.
7466 AssemblerOptions
.push_back(
7467 std::make_unique
<MipsAssemblerOptions
>(AssemblerOptions
.back().get()));
7469 getTargetStreamer().emitDirectiveSetPush();
7473 bool MipsAsmParser::parseSetSoftFloatDirective() {
7474 MCAsmParser
&Parser
= getParser();
7476 if (getLexer().isNot(AsmToken::EndOfStatement
))
7477 return reportParseError("unexpected token, expected end of statement");
7479 setFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7480 getTargetStreamer().emitDirectiveSetSoftFloat();
7484 bool MipsAsmParser::parseSetHardFloatDirective() {
7485 MCAsmParser
&Parser
= getParser();
7487 if (getLexer().isNot(AsmToken::EndOfStatement
))
7488 return reportParseError("unexpected token, expected end of statement");
7490 clearFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7491 getTargetStreamer().emitDirectiveSetHardFloat();
7495 bool MipsAsmParser::parseSetAssignment() {
7497 MCAsmParser
&Parser
= getParser();
7499 if (Parser
.parseIdentifier(Name
))
7500 return reportParseError("expected identifier after .set");
7502 if (getLexer().isNot(AsmToken::Comma
))
7503 return reportParseError("unexpected token, expected comma");
7506 if (getLexer().is(AsmToken::Dollar
) &&
7507 getLexer().peekTok().is(AsmToken::Integer
)) {
7508 // Parse assignment of a numeric register:
7510 Parser
.Lex(); // Eat $.
7511 RegisterSets
[Name
] = Parser
.getTok();
7512 Parser
.Lex(); // Eat identifier.
7513 getContext().getOrCreateSymbol(Name
);
7518 const MCExpr
*Value
;
7519 if (MCParserUtils::parseAssignmentExpression(Name
, /* allow_redef */ true,
7520 Parser
, Sym
, Value
))
7522 Sym
->setVariableValue(Value
);
7527 bool MipsAsmParser::parseSetMips0Directive() {
7528 MCAsmParser
&Parser
= getParser();
7530 if (getLexer().isNot(AsmToken::EndOfStatement
))
7531 return reportParseError("unexpected token, expected end of statement");
7533 // Reset assembler options to their initial values.
7534 MCSubtargetInfo
&STI
= copySTI();
7535 setAvailableFeatures(
7536 ComputeAvailableFeatures(AssemblerOptions
.front()->getFeatures()));
7537 STI
.setFeatureBits(AssemblerOptions
.front()->getFeatures());
7538 AssemblerOptions
.back()->setFeatures(AssemblerOptions
.front()->getFeatures());
7540 getTargetStreamer().emitDirectiveSetMips0();
7544 bool MipsAsmParser::parseSetArchDirective() {
7545 MCAsmParser
&Parser
= getParser();
7547 if (getLexer().isNot(AsmToken::Equal
))
7548 return reportParseError("unexpected token, expected equals sign");
7551 StringRef Arch
= getParser().parseStringToEndOfStatement().trim();
7553 return reportParseError("expected arch identifier");
7555 StringRef ArchFeatureName
=
7556 StringSwitch
<StringRef
>(Arch
)
7557 .Case("mips1", "mips1")
7558 .Case("mips2", "mips2")
7559 .Case("mips3", "mips3")
7560 .Case("mips4", "mips4")
7561 .Case("mips5", "mips5")
7562 .Case("mips32", "mips32")
7563 .Case("mips32r2", "mips32r2")
7564 .Case("mips32r3", "mips32r3")
7565 .Case("mips32r5", "mips32r5")
7566 .Case("mips32r6", "mips32r6")
7567 .Case("mips64", "mips64")
7568 .Case("mips64r2", "mips64r2")
7569 .Case("mips64r3", "mips64r3")
7570 .Case("mips64r5", "mips64r5")
7571 .Case("mips64r6", "mips64r6")
7572 .Case("octeon", "cnmips")
7573 .Case("octeon+", "cnmipsp")
7574 .Case("r4000", "mips3") // This is an implementation of Mips3.
7577 if (ArchFeatureName
.empty())
7578 return reportParseError("unsupported architecture");
7580 if (ArchFeatureName
== "mips64r6" && inMicroMipsMode())
7581 return reportParseError("mips64r6 does not support microMIPS");
7583 selectArch(ArchFeatureName
);
7584 getTargetStreamer().emitDirectiveSetArch(Arch
);
7588 bool MipsAsmParser::parseSetFeature(uint64_t Feature
) {
7589 MCAsmParser
&Parser
= getParser();
7591 if (getLexer().isNot(AsmToken::EndOfStatement
))
7592 return reportParseError("unexpected token, expected end of statement");
7596 llvm_unreachable("Unimplemented feature");
7597 case Mips::FeatureMips3D
:
7598 setFeatureBits(Mips::FeatureMips3D
, "mips3d");
7599 getTargetStreamer().emitDirectiveSetMips3D();
7601 case Mips::FeatureDSP
:
7602 setFeatureBits(Mips::FeatureDSP
, "dsp");
7603 getTargetStreamer().emitDirectiveSetDsp();
7605 case Mips::FeatureDSPR2
:
7606 setFeatureBits(Mips::FeatureDSPR2
, "dspr2");
7607 getTargetStreamer().emitDirectiveSetDspr2();
7609 case Mips::FeatureMicroMips
:
7610 setFeatureBits(Mips::FeatureMicroMips
, "micromips");
7611 getTargetStreamer().emitDirectiveSetMicroMips();
7613 case Mips::FeatureMips1
:
7614 selectArch("mips1");
7615 getTargetStreamer().emitDirectiveSetMips1();
7617 case Mips::FeatureMips2
:
7618 selectArch("mips2");
7619 getTargetStreamer().emitDirectiveSetMips2();
7621 case Mips::FeatureMips3
:
7622 selectArch("mips3");
7623 getTargetStreamer().emitDirectiveSetMips3();
7625 case Mips::FeatureMips4
:
7626 selectArch("mips4");
7627 getTargetStreamer().emitDirectiveSetMips4();
7629 case Mips::FeatureMips5
:
7630 selectArch("mips5");
7631 getTargetStreamer().emitDirectiveSetMips5();
7633 case Mips::FeatureMips32
:
7634 selectArch("mips32");
7635 getTargetStreamer().emitDirectiveSetMips32();
7637 case Mips::FeatureMips32r2
:
7638 selectArch("mips32r2");
7639 getTargetStreamer().emitDirectiveSetMips32R2();
7641 case Mips::FeatureMips32r3
:
7642 selectArch("mips32r3");
7643 getTargetStreamer().emitDirectiveSetMips32R3();
7645 case Mips::FeatureMips32r5
:
7646 selectArch("mips32r5");
7647 getTargetStreamer().emitDirectiveSetMips32R5();
7649 case Mips::FeatureMips32r6
:
7650 selectArch("mips32r6");
7651 getTargetStreamer().emitDirectiveSetMips32R6();
7653 case Mips::FeatureMips64
:
7654 selectArch("mips64");
7655 getTargetStreamer().emitDirectiveSetMips64();
7657 case Mips::FeatureMips64r2
:
7658 selectArch("mips64r2");
7659 getTargetStreamer().emitDirectiveSetMips64R2();
7661 case Mips::FeatureMips64r3
:
7662 selectArch("mips64r3");
7663 getTargetStreamer().emitDirectiveSetMips64R3();
7665 case Mips::FeatureMips64r5
:
7666 selectArch("mips64r5");
7667 getTargetStreamer().emitDirectiveSetMips64R5();
7669 case Mips::FeatureMips64r6
:
7670 selectArch("mips64r6");
7671 getTargetStreamer().emitDirectiveSetMips64R6();
7673 case Mips::FeatureCRC
:
7674 setFeatureBits(Mips::FeatureCRC
, "crc");
7675 getTargetStreamer().emitDirectiveSetCRC();
7677 case Mips::FeatureVirt
:
7678 setFeatureBits(Mips::FeatureVirt
, "virt");
7679 getTargetStreamer().emitDirectiveSetVirt();
7681 case Mips::FeatureGINV
:
7682 setFeatureBits(Mips::FeatureGINV
, "ginv");
7683 getTargetStreamer().emitDirectiveSetGINV();
7689 bool MipsAsmParser::eatComma(StringRef ErrorStr
) {
7690 MCAsmParser
&Parser
= getParser();
7691 if (getLexer().isNot(AsmToken::Comma
)) {
7692 SMLoc Loc
= getLexer().getLoc();
7693 return Error(Loc
, ErrorStr
);
7696 Parser
.Lex(); // Eat the comma.
7700 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7701 // In this class, it is only used for .cprestore.
7702 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7703 // MipsTargetELFStreamer and MipsAsmParser.
7704 bool MipsAsmParser::isPicAndNotNxxAbi() {
7705 return inPicMode() && !(isABI_N32() || isABI_N64());
7708 bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc
) {
7709 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Reg
;
7710 ParseStatus Res
= parseAnyRegister(Reg
);
7711 if (Res
.isNoMatch() || Res
.isFailure()) {
7712 reportParseError("expected register");
7716 MipsOperand
&RegOpnd
= static_cast<MipsOperand
&>(*Reg
[0]);
7717 if (!RegOpnd
.isGPRAsmReg()) {
7718 reportParseError(RegOpnd
.getStartLoc(), "invalid register");
7722 // If this is not the end of the statement, report an error.
7723 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7724 reportParseError("unexpected token, expected end of statement");
7727 getParser().Lex(); // Consume the EndOfStatement.
7729 getTargetStreamer().emitDirectiveCpAdd(RegOpnd
.getGPR32Reg());
7733 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc
) {
7734 if (AssemblerOptions
.back()->isReorder())
7735 Warning(Loc
, ".cpload should be inside a noreorder section");
7737 if (inMips16Mode()) {
7738 reportParseError(".cpload is not supported in Mips16 mode");
7742 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Reg
;
7743 ParseStatus Res
= parseAnyRegister(Reg
);
7744 if (Res
.isNoMatch() || Res
.isFailure()) {
7745 reportParseError("expected register containing function address");
7749 MipsOperand
&RegOpnd
= static_cast<MipsOperand
&>(*Reg
[0]);
7750 if (!RegOpnd
.isGPRAsmReg()) {
7751 reportParseError(RegOpnd
.getStartLoc(), "invalid register");
7755 // If this is not the end of the statement, report an error.
7756 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7757 reportParseError("unexpected token, expected end of statement");
7761 getTargetStreamer().emitDirectiveCpLoad(RegOpnd
.getGPR32Reg());
7765 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc
) {
7766 if (!isABI_N32() && !isABI_N64()) {
7767 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7771 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Reg
;
7772 ParseStatus Res
= parseAnyRegister(Reg
);
7773 if (Res
.isNoMatch() || Res
.isFailure()) {
7774 reportParseError("expected register containing global pointer");
7778 MipsOperand
&RegOpnd
= static_cast<MipsOperand
&>(*Reg
[0]);
7779 if (!RegOpnd
.isGPRAsmReg()) {
7780 reportParseError(RegOpnd
.getStartLoc(), "invalid register");
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");
7789 getParser().Lex(); // Consume the EndOfStatement.
7791 unsigned NewReg
= RegOpnd
.getGPR32Reg();
7795 getTargetStreamer().emitDirectiveCpLocal(NewReg
);
7799 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc
) {
7800 MCAsmParser
&Parser
= getParser();
7802 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7803 // is used in non-PIC mode.
7805 if (inMips16Mode()) {
7806 reportParseError(".cprestore is not supported in Mips16 mode");
7810 // Get the stack offset value.
7811 const MCExpr
*StackOffset
;
7812 int64_t StackOffsetVal
;
7813 if (Parser
.parseExpression(StackOffset
)) {
7814 reportParseError("expected stack offset value");
7818 if (!StackOffset
->evaluateAsAbsolute(StackOffsetVal
)) {
7819 reportParseError("stack offset is not an absolute expression");
7823 if (StackOffsetVal
< 0) {
7824 Warning(Loc
, ".cprestore with negative stack offset has no effect");
7825 IsCpRestoreSet
= false;
7827 IsCpRestoreSet
= true;
7828 CpRestoreOffset
= StackOffsetVal
;
7831 // If this is not the end of the statement, report an error.
7832 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7833 reportParseError("unexpected token, expected end of statement");
7837 if (!getTargetStreamer().emitDirectiveCpRestore(
7838 CpRestoreOffset
, [&]() { return getATReg(Loc
); }, Loc
, STI
))
7840 Parser
.Lex(); // Consume the EndOfStatement.
7844 bool MipsAsmParser::parseDirectiveCPSetup() {
7845 MCAsmParser
&Parser
= getParser();
7848 bool SaveIsReg
= true;
7850 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> TmpReg
;
7851 ParseStatus Res
= parseAnyRegister(TmpReg
);
7852 if (Res
.isNoMatch()) {
7853 reportParseError("expected register containing function address");
7857 MipsOperand
&FuncRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
7858 if (!FuncRegOpnd
.isGPRAsmReg()) {
7859 reportParseError(FuncRegOpnd
.getStartLoc(), "invalid register");
7863 FuncReg
= FuncRegOpnd
.getGPR32Reg();
7866 if (!eatComma("unexpected token, expected comma"))
7869 Res
= parseAnyRegister(TmpReg
);
7870 if (Res
.isNoMatch()) {
7871 const MCExpr
*OffsetExpr
;
7873 SMLoc ExprLoc
= getLexer().getLoc();
7875 if (Parser
.parseExpression(OffsetExpr
) ||
7876 !OffsetExpr
->evaluateAsAbsolute(OffsetVal
)) {
7877 reportParseError(ExprLoc
, "expected save register or stack offset");
7884 MipsOperand
&SaveOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
7885 if (!SaveOpnd
.isGPRAsmReg()) {
7886 reportParseError(SaveOpnd
.getStartLoc(), "invalid register");
7889 Save
= SaveOpnd
.getGPR32Reg();
7892 if (!eatComma("unexpected token, expected comma"))
7896 if (Parser
.parseExpression(Expr
)) {
7897 reportParseError("expected expression");
7901 if (Expr
->getKind() != MCExpr::SymbolRef
) {
7902 reportParseError("expected symbol");
7905 const MCSymbolRefExpr
*Ref
= static_cast<const MCSymbolRefExpr
*>(Expr
);
7907 CpSaveLocation
= Save
;
7908 CpSaveLocationIsRegister
= SaveIsReg
;
7910 getTargetStreamer().emitDirectiveCpsetup(FuncReg
, Save
, Ref
->getSymbol(),
7915 bool MipsAsmParser::parseDirectiveCPReturn() {
7916 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation
,
7917 CpSaveLocationIsRegister
);
7921 bool MipsAsmParser::parseDirectiveNaN() {
7922 MCAsmParser
&Parser
= getParser();
7923 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7924 const AsmToken
&Tok
= Parser
.getTok();
7926 if (Tok
.getString() == "2008") {
7928 getTargetStreamer().emitDirectiveNaN2008();
7930 } else if (Tok
.getString() == "legacy") {
7932 getTargetStreamer().emitDirectiveNaNLegacy();
7936 // If we don't recognize the option passed to the .nan
7937 // directive (e.g. no option or unknown option), emit an error.
7938 reportParseError("invalid option in .nan directive");
7942 bool MipsAsmParser::parseDirectiveSet() {
7943 const AsmToken
&Tok
= getParser().getTok();
7944 StringRef IdVal
= Tok
.getString();
7945 SMLoc Loc
= Tok
.getLoc();
7947 if (IdVal
== "noat")
7948 return parseSetNoAtDirective();
7950 return parseSetAtDirective();
7951 if (IdVal
== "arch")
7952 return parseSetArchDirective();
7953 if (IdVal
== "bopt") {
7954 Warning(Loc
, "'bopt' feature is unsupported");
7958 if (IdVal
== "nobopt") {
7959 // We're already running in nobopt mode, so nothing to do.
7964 return parseSetFpDirective();
7965 if (IdVal
== "oddspreg")
7966 return parseSetOddSPRegDirective();
7967 if (IdVal
== "nooddspreg")
7968 return parseSetNoOddSPRegDirective();
7970 return parseSetPopDirective();
7971 if (IdVal
== "push")
7972 return parseSetPushDirective();
7973 if (IdVal
== "reorder")
7974 return parseSetReorderDirective();
7975 if (IdVal
== "noreorder")
7976 return parseSetNoReorderDirective();
7977 if (IdVal
== "macro")
7978 return parseSetMacroDirective();
7979 if (IdVal
== "nomacro")
7980 return parseSetNoMacroDirective();
7981 if (IdVal
== "mips16")
7982 return parseSetMips16Directive();
7983 if (IdVal
== "nomips16")
7984 return parseSetNoMips16Directive();
7985 if (IdVal
== "nomicromips") {
7986 clearFeatureBits(Mips::FeatureMicroMips
, "micromips");
7987 getTargetStreamer().emitDirectiveSetNoMicroMips();
7988 getParser().eatToEndOfStatement();
7991 if (IdVal
== "micromips") {
7992 if (hasMips64r6()) {
7993 Error(Loc
, ".set micromips directive is not supported with MIPS64R6");
7996 return parseSetFeature(Mips::FeatureMicroMips
);
7998 if (IdVal
== "mips0")
7999 return parseSetMips0Directive();
8000 if (IdVal
== "mips1")
8001 return parseSetFeature(Mips::FeatureMips1
);
8002 if (IdVal
== "mips2")
8003 return parseSetFeature(Mips::FeatureMips2
);
8004 if (IdVal
== "mips3")
8005 return parseSetFeature(Mips::FeatureMips3
);
8006 if (IdVal
== "mips4")
8007 return parseSetFeature(Mips::FeatureMips4
);
8008 if (IdVal
== "mips5")
8009 return parseSetFeature(Mips::FeatureMips5
);
8010 if (IdVal
== "mips32")
8011 return parseSetFeature(Mips::FeatureMips32
);
8012 if (IdVal
== "mips32r2")
8013 return parseSetFeature(Mips::FeatureMips32r2
);
8014 if (IdVal
== "mips32r3")
8015 return parseSetFeature(Mips::FeatureMips32r3
);
8016 if (IdVal
== "mips32r5")
8017 return parseSetFeature(Mips::FeatureMips32r5
);
8018 if (IdVal
== "mips32r6")
8019 return parseSetFeature(Mips::FeatureMips32r6
);
8020 if (IdVal
== "mips64")
8021 return parseSetFeature(Mips::FeatureMips64
);
8022 if (IdVal
== "mips64r2")
8023 return parseSetFeature(Mips::FeatureMips64r2
);
8024 if (IdVal
== "mips64r3")
8025 return parseSetFeature(Mips::FeatureMips64r3
);
8026 if (IdVal
== "mips64r5")
8027 return parseSetFeature(Mips::FeatureMips64r5
);
8028 if (IdVal
== "mips64r6") {
8029 if (inMicroMipsMode()) {
8030 Error(Loc
, "MIPS64R6 is not supported with microMIPS");
8033 return parseSetFeature(Mips::FeatureMips64r6
);
8036 return parseSetFeature(Mips::FeatureDSP
);
8037 if (IdVal
== "dspr2")
8038 return parseSetFeature(Mips::FeatureDSPR2
);
8039 if (IdVal
== "nodsp")
8040 return parseSetNoDspDirective();
8041 if (IdVal
== "mips3d")
8042 return parseSetFeature(Mips::FeatureMips3D
);
8043 if (IdVal
== "nomips3d")
8044 return parseSetNoMips3DDirective();
8046 return parseSetMsaDirective();
8047 if (IdVal
== "nomsa")
8048 return parseSetNoMsaDirective();
8050 return parseSetMtDirective();
8051 if (IdVal
== "nomt")
8052 return parseSetNoMtDirective();
8053 if (IdVal
== "softfloat")
8054 return parseSetSoftFloatDirective();
8055 if (IdVal
== "hardfloat")
8056 return parseSetHardFloatDirective();
8058 return parseSetFeature(Mips::FeatureCRC
);
8059 if (IdVal
== "nocrc")
8060 return parseSetNoCRCDirective();
8061 if (IdVal
== "virt")
8062 return parseSetFeature(Mips::FeatureVirt
);
8063 if (IdVal
== "novirt")
8064 return parseSetNoVirtDirective();
8065 if (IdVal
== "ginv")
8066 return parseSetFeature(Mips::FeatureGINV
);
8067 if (IdVal
== "noginv")
8068 return parseSetNoGINVDirective();
8070 // It is just an identifier, look for an assignment.
8071 return parseSetAssignment();
8074 /// parseDirectiveGpWord
8075 /// ::= .gpword local_sym
8076 bool MipsAsmParser::parseDirectiveGpWord() {
8077 MCAsmParser
&Parser
= getParser();
8078 const MCExpr
*Value
;
8079 // EmitGPRel32Value requires an expression, so we are using base class
8080 // method to evaluate the expression.
8081 if (getParser().parseExpression(Value
))
8083 getParser().getStreamer().emitGPRel32Value(Value
);
8085 if (getLexer().isNot(AsmToken::EndOfStatement
))
8086 return Error(getLexer().getLoc(),
8087 "unexpected token, expected end of statement");
8088 Parser
.Lex(); // Eat EndOfStatement token.
8092 /// parseDirectiveGpDWord
8093 /// ::= .gpdword local_sym
8094 bool MipsAsmParser::parseDirectiveGpDWord() {
8095 MCAsmParser
&Parser
= getParser();
8096 const MCExpr
*Value
;
8097 // EmitGPRel64Value requires an expression, so we are using base class
8098 // method to evaluate the expression.
8099 if (getParser().parseExpression(Value
))
8101 getParser().getStreamer().emitGPRel64Value(Value
);
8103 if (getLexer().isNot(AsmToken::EndOfStatement
))
8104 return Error(getLexer().getLoc(),
8105 "unexpected token, expected end of statement");
8106 Parser
.Lex(); // Eat EndOfStatement token.
8110 /// parseDirectiveDtpRelWord
8111 /// ::= .dtprelword tls_sym
8112 bool MipsAsmParser::parseDirectiveDtpRelWord() {
8113 MCAsmParser
&Parser
= getParser();
8114 const MCExpr
*Value
;
8115 // EmitDTPRel32Value requires an expression, so we are using base class
8116 // method to evaluate the expression.
8117 if (getParser().parseExpression(Value
))
8119 getParser().getStreamer().emitDTPRel32Value(Value
);
8121 if (getLexer().isNot(AsmToken::EndOfStatement
))
8122 return Error(getLexer().getLoc(),
8123 "unexpected token, expected end of statement");
8124 Parser
.Lex(); // Eat EndOfStatement token.
8128 /// parseDirectiveDtpRelDWord
8129 /// ::= .dtpreldword tls_sym
8130 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8131 MCAsmParser
&Parser
= getParser();
8132 const MCExpr
*Value
;
8133 // EmitDTPRel64Value requires an expression, so we are using base class
8134 // method to evaluate the expression.
8135 if (getParser().parseExpression(Value
))
8137 getParser().getStreamer().emitDTPRel64Value(Value
);
8139 if (getLexer().isNot(AsmToken::EndOfStatement
))
8140 return Error(getLexer().getLoc(),
8141 "unexpected token, expected end of statement");
8142 Parser
.Lex(); // Eat EndOfStatement token.
8146 /// parseDirectiveTpRelWord
8147 /// ::= .tprelword tls_sym
8148 bool MipsAsmParser::parseDirectiveTpRelWord() {
8149 MCAsmParser
&Parser
= getParser();
8150 const MCExpr
*Value
;
8151 // EmitTPRel32Value requires an expression, so we are using base class
8152 // method to evaluate the expression.
8153 if (getParser().parseExpression(Value
))
8155 getParser().getStreamer().emitTPRel32Value(Value
);
8157 if (getLexer().isNot(AsmToken::EndOfStatement
))
8158 return Error(getLexer().getLoc(),
8159 "unexpected token, expected end of statement");
8160 Parser
.Lex(); // Eat EndOfStatement token.
8164 /// parseDirectiveTpRelDWord
8165 /// ::= .tpreldword tls_sym
8166 bool MipsAsmParser::parseDirectiveTpRelDWord() {
8167 MCAsmParser
&Parser
= getParser();
8168 const MCExpr
*Value
;
8169 // EmitTPRel64Value requires an expression, so we are using base class
8170 // method to evaluate the expression.
8171 if (getParser().parseExpression(Value
))
8173 getParser().getStreamer().emitTPRel64Value(Value
);
8175 if (getLexer().isNot(AsmToken::EndOfStatement
))
8176 return Error(getLexer().getLoc(),
8177 "unexpected token, expected end of statement");
8178 Parser
.Lex(); // Eat EndOfStatement token.
8182 bool MipsAsmParser::parseDirectiveOption() {
8183 MCAsmParser
&Parser
= getParser();
8184 // Get the option token.
8185 AsmToken Tok
= Parser
.getTok();
8186 // At the moment only identifiers are supported.
8187 if (Tok
.isNot(AsmToken::Identifier
)) {
8188 return Error(Parser
.getTok().getLoc(),
8189 "unexpected token, expected identifier");
8192 StringRef Option
= Tok
.getIdentifier();
8194 if (Option
== "pic0") {
8195 // MipsAsmParser needs to know if the current PIC mode changes.
8196 IsPicEnabled
= false;
8198 getTargetStreamer().emitDirectiveOptionPic0();
8200 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
8201 return Error(Parser
.getTok().getLoc(),
8202 "unexpected token, expected end of statement");
8207 if (Option
== "pic2") {
8208 // MipsAsmParser needs to know if the current PIC mode changes.
8209 IsPicEnabled
= true;
8211 getTargetStreamer().emitDirectiveOptionPic2();
8213 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
8214 return Error(Parser
.getTok().getLoc(),
8215 "unexpected token, expected end of statement");
8221 Warning(Parser
.getTok().getLoc(),
8222 "unknown option, expected 'pic0' or 'pic2'");
8223 Parser
.eatToEndOfStatement();
8227 /// parseInsnDirective
8229 bool MipsAsmParser::parseInsnDirective() {
8230 // If this is not the end of the statement, report an error.
8231 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8232 reportParseError("unexpected token, expected end of statement");
8236 // The actual label marking happens in
8237 // MipsELFStreamer::createPendingLabelRelocs().
8238 getTargetStreamer().emitDirectiveInsn();
8240 getParser().Lex(); // Eat EndOfStatement token.
8244 /// parseRSectionDirective
8246 bool MipsAsmParser::parseRSectionDirective(StringRef Section
) {
8247 // If this is not the end of the statement, report an error.
8248 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8249 reportParseError("unexpected token, expected end of statement");
8253 MCSection
*ELFSection
= getContext().getELFSection(
8254 Section
, ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
8255 getParser().getStreamer().switchSection(ELFSection
);
8257 getParser().Lex(); // Eat EndOfStatement token.
8261 /// parseSSectionDirective
8264 bool MipsAsmParser::parseSSectionDirective(StringRef Section
, unsigned Type
) {
8265 // If this is not the end of the statement, report an error.
8266 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8267 reportParseError("unexpected token, expected end of statement");
8271 MCSection
*ELFSection
= getContext().getELFSection(
8272 Section
, Type
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
| ELF::SHF_MIPS_GPREL
);
8273 getParser().getStreamer().switchSection(ELFSection
);
8275 getParser().Lex(); // Eat EndOfStatement token.
8279 /// parseDirectiveModule
8280 /// ::= .module oddspreg
8281 /// ::= .module nooddspreg
8282 /// ::= .module fp=value
8283 /// ::= .module softfloat
8284 /// ::= .module hardfloat
8287 /// ::= .module nocrc
8288 /// ::= .module virt
8289 /// ::= .module novirt
8290 /// ::= .module ginv
8291 /// ::= .module noginv
8292 bool MipsAsmParser::parseDirectiveModule() {
8293 MCAsmParser
&Parser
= getParser();
8294 MCAsmLexer
&Lexer
= getLexer();
8295 SMLoc L
= Lexer
.getLoc();
8297 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8298 // TODO : get a better message.
8299 reportParseError(".module directive must appear before any code");
8304 if (Parser
.parseIdentifier(Option
)) {
8305 reportParseError("expected .module option identifier");
8309 if (Option
== "oddspreg") {
8310 clearModuleFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
8312 // Synchronize the abiflags information with the FeatureBits information we
8314 getTargetStreamer().updateABIInfo(*this);
8316 // If printing assembly, use the recently updated abiflags information.
8317 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8318 // emitted at the end).
8319 getTargetStreamer().emitDirectiveModuleOddSPReg();
8321 // If this is not the end of the statement, report an error.
8322 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8323 reportParseError("unexpected token, expected end of statement");
8327 return false; // parseDirectiveModule has finished successfully.
8328 } else if (Option
== "nooddspreg") {
8330 return Error(L
, "'.module nooddspreg' requires the O32 ABI");
8333 setModuleFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
8335 // Synchronize the abiflags information with the FeatureBits information we
8337 getTargetStreamer().updateABIInfo(*this);
8339 // If printing assembly, use the recently updated abiflags information.
8340 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8341 // emitted at the end).
8342 getTargetStreamer().emitDirectiveModuleOddSPReg();
8344 // If this is not the end of the statement, report an error.
8345 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8346 reportParseError("unexpected token, expected end of statement");
8350 return false; // parseDirectiveModule has finished successfully.
8351 } else if (Option
== "fp") {
8352 return parseDirectiveModuleFP();
8353 } else if (Option
== "softfloat") {
8354 setModuleFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
8356 // Synchronize the ABI Flags information with the FeatureBits information we
8358 getTargetStreamer().updateABIInfo(*this);
8360 // If printing assembly, use the recently updated ABI Flags information.
8361 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8363 getTargetStreamer().emitDirectiveModuleSoftFloat();
8365 // If this is not the end of the statement, report an error.
8366 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8367 reportParseError("unexpected token, expected end of statement");
8371 return false; // parseDirectiveModule has finished successfully.
8372 } else if (Option
== "hardfloat") {
8373 clearModuleFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
8375 // Synchronize the ABI Flags information with the FeatureBits information we
8377 getTargetStreamer().updateABIInfo(*this);
8379 // If printing assembly, use the recently updated ABI Flags information.
8380 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8382 getTargetStreamer().emitDirectiveModuleHardFloat();
8384 // If this is not the end of the statement, report an error.
8385 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8386 reportParseError("unexpected token, expected end of statement");
8390 return false; // parseDirectiveModule has finished successfully.
8391 } else if (Option
== "mt") {
8392 setModuleFeatureBits(Mips::FeatureMT
, "mt");
8394 // Synchronize the ABI Flags information with the FeatureBits information we
8396 getTargetStreamer().updateABIInfo(*this);
8398 // If printing assembly, use the recently updated ABI Flags information.
8399 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8401 getTargetStreamer().emitDirectiveModuleMT();
8403 // If this is not the end of the statement, report an error.
8404 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8405 reportParseError("unexpected token, expected end of statement");
8409 return false; // parseDirectiveModule has finished successfully.
8410 } else if (Option
== "crc") {
8411 setModuleFeatureBits(Mips::FeatureCRC
, "crc");
8413 // Synchronize the ABI Flags information with the FeatureBits information we
8415 getTargetStreamer().updateABIInfo(*this);
8417 // If printing assembly, use the recently updated ABI Flags information.
8418 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8420 getTargetStreamer().emitDirectiveModuleCRC();
8422 // If this is not the end of the statement, report an error.
8423 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8424 reportParseError("unexpected token, expected end of statement");
8428 return false; // parseDirectiveModule has finished successfully.
8429 } else if (Option
== "nocrc") {
8430 clearModuleFeatureBits(Mips::FeatureCRC
, "crc");
8432 // Synchronize the ABI Flags information with the FeatureBits information we
8434 getTargetStreamer().updateABIInfo(*this);
8436 // If printing assembly, use the recently updated ABI Flags information.
8437 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8439 getTargetStreamer().emitDirectiveModuleNoCRC();
8441 // If this is not the end of the statement, report an error.
8442 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8443 reportParseError("unexpected token, expected end of statement");
8447 return false; // parseDirectiveModule has finished successfully.
8448 } else if (Option
== "virt") {
8449 setModuleFeatureBits(Mips::FeatureVirt
, "virt");
8451 // Synchronize the ABI Flags information with the FeatureBits information we
8453 getTargetStreamer().updateABIInfo(*this);
8455 // If printing assembly, use the recently updated ABI Flags information.
8456 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8458 getTargetStreamer().emitDirectiveModuleVirt();
8460 // If this is not the end of the statement, report an error.
8461 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8462 reportParseError("unexpected token, expected end of statement");
8466 return false; // parseDirectiveModule has finished successfully.
8467 } else if (Option
== "novirt") {
8468 clearModuleFeatureBits(Mips::FeatureVirt
, "virt");
8470 // Synchronize the ABI Flags information with the FeatureBits information we
8472 getTargetStreamer().updateABIInfo(*this);
8474 // If printing assembly, use the recently updated ABI Flags information.
8475 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8477 getTargetStreamer().emitDirectiveModuleNoVirt();
8479 // If this is not the end of the statement, report an error.
8480 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8481 reportParseError("unexpected token, expected end of statement");
8485 return false; // parseDirectiveModule has finished successfully.
8486 } else if (Option
== "ginv") {
8487 setModuleFeatureBits(Mips::FeatureGINV
, "ginv");
8489 // Synchronize the ABI Flags information with the FeatureBits information we
8491 getTargetStreamer().updateABIInfo(*this);
8493 // If printing assembly, use the recently updated ABI Flags information.
8494 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8496 getTargetStreamer().emitDirectiveModuleGINV();
8498 // If this is not the end of the statement, report an error.
8499 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8500 reportParseError("unexpected token, expected end of statement");
8504 return false; // parseDirectiveModule has finished successfully.
8505 } else if (Option
== "noginv") {
8506 clearModuleFeatureBits(Mips::FeatureGINV
, "ginv");
8508 // Synchronize the ABI Flags information with the FeatureBits information we
8510 getTargetStreamer().updateABIInfo(*this);
8512 // If printing assembly, use the recently updated ABI Flags information.
8513 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8515 getTargetStreamer().emitDirectiveModuleNoGINV();
8517 // If this is not the end of the statement, report an error.
8518 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8519 reportParseError("unexpected token, expected end of statement");
8523 return false; // parseDirectiveModule has finished successfully.
8525 return Error(L
, "'" + Twine(Option
) + "' is not a valid .module option.");
8529 /// parseDirectiveModuleFP
8533 bool MipsAsmParser::parseDirectiveModuleFP() {
8534 MCAsmParser
&Parser
= getParser();
8535 MCAsmLexer
&Lexer
= getLexer();
8537 if (Lexer
.isNot(AsmToken::Equal
)) {
8538 reportParseError("unexpected token, expected equals sign '='");
8541 Parser
.Lex(); // Eat '=' token.
8543 MipsABIFlagsSection::FpABIKind FpABI
;
8544 if (!parseFpABIValue(FpABI
, ".module"))
8547 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8548 reportParseError("unexpected token, expected end of statement");
8552 // Synchronize the abiflags information with the FeatureBits information we
8554 getTargetStreamer().updateABIInfo(*this);
8556 // If printing assembly, use the recently updated abiflags information.
8557 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8558 // emitted at the end).
8559 getTargetStreamer().emitDirectiveModuleFP();
8561 Parser
.Lex(); // Consume the EndOfStatement.
8565 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind
&FpABI
,
8566 StringRef Directive
) {
8567 MCAsmParser
&Parser
= getParser();
8568 MCAsmLexer
&Lexer
= getLexer();
8569 bool ModuleLevelOptions
= Directive
== ".module";
8571 if (Lexer
.is(AsmToken::Identifier
)) {
8572 StringRef Value
= Parser
.getTok().getString();
8575 if (Value
!= "xx") {
8576 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8581 reportParseError("'" + Directive
+ " fp=xx' requires the O32 ABI");
8585 FpABI
= MipsABIFlagsSection::FpABIKind::XX
;
8586 if (ModuleLevelOptions
) {
8587 setModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8588 clearModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8590 setFeatureBits(Mips::FeatureFPXX
, "fpxx");
8591 clearFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8596 if (Lexer
.is(AsmToken::Integer
)) {
8597 unsigned Value
= Parser
.getTok().getIntVal();
8600 if (Value
!= 32 && Value
!= 64) {
8601 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8607 reportParseError("'" + Directive
+ " fp=32' requires the O32 ABI");
8611 FpABI
= MipsABIFlagsSection::FpABIKind::S32
;
8612 if (ModuleLevelOptions
) {
8613 clearModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8614 clearModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8616 clearFeatureBits(Mips::FeatureFPXX
, "fpxx");
8617 clearFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8620 FpABI
= MipsABIFlagsSection::FpABIKind::S64
;
8621 if (ModuleLevelOptions
) {
8622 clearModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8623 setModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8625 clearFeatureBits(Mips::FeatureFPXX
, "fpxx");
8626 setFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8636 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID
) {
8637 // This returns false if this function recognizes the directive
8638 // regardless of whether it is successfully handles or reports an
8639 // error. Otherwise it returns true to give the generic parser a
8640 // chance at recognizing it.
8642 MCAsmParser
&Parser
= getParser();
8643 StringRef IDVal
= DirectiveID
.getString();
8645 if (IDVal
== ".cpadd") {
8646 parseDirectiveCpAdd(DirectiveID
.getLoc());
8649 if (IDVal
== ".cpload") {
8650 parseDirectiveCpLoad(DirectiveID
.getLoc());
8653 if (IDVal
== ".cprestore") {
8654 parseDirectiveCpRestore(DirectiveID
.getLoc());
8657 if (IDVal
== ".cplocal") {
8658 parseDirectiveCpLocal(DirectiveID
.getLoc());
8661 if (IDVal
== ".ent") {
8662 StringRef SymbolName
;
8664 if (Parser
.parseIdentifier(SymbolName
)) {
8665 reportParseError("expected identifier after .ent");
8669 // There's an undocumented extension that allows an integer to
8670 // follow the name of the procedure which AFAICS is ignored by GAS.
8671 // Example: .ent foo,2
8672 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8673 if (getLexer().isNot(AsmToken::Comma
)) {
8674 // Even though we accept this undocumented extension for compatibility
8675 // reasons, the additional integer argument does not actually change
8676 // the behaviour of the '.ent' directive, so we would like to discourage
8677 // its use. We do this by not referring to the extended version in
8678 // error messages which are not directly related to its use.
8679 reportParseError("unexpected token, expected end of statement");
8682 Parser
.Lex(); // Eat the comma.
8683 const MCExpr
*DummyNumber
;
8684 int64_t DummyNumberVal
;
8685 // If the user was explicitly trying to use the extended version,
8686 // we still give helpful extension-related error messages.
8687 if (Parser
.parseExpression(DummyNumber
)) {
8688 reportParseError("expected number after comma");
8691 if (!DummyNumber
->evaluateAsAbsolute(DummyNumberVal
)) {
8692 reportParseError("expected an absolute expression after comma");
8697 // If this is not the end of the statement, report an error.
8698 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8699 reportParseError("unexpected token, expected end of statement");
8703 MCSymbol
*Sym
= getContext().getOrCreateSymbol(SymbolName
);
8705 getTargetStreamer().emitDirectiveEnt(*Sym
);
8707 IsCpRestoreSet
= false;
8711 if (IDVal
== ".end") {
8712 StringRef SymbolName
;
8714 if (Parser
.parseIdentifier(SymbolName
)) {
8715 reportParseError("expected identifier after .end");
8719 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8720 reportParseError("unexpected token, expected end of statement");
8724 if (CurrentFn
== nullptr) {
8725 reportParseError(".end used without .ent");
8729 if ((SymbolName
!= CurrentFn
->getName())) {
8730 reportParseError(".end symbol does not match .ent symbol");
8734 getTargetStreamer().emitDirectiveEnd(SymbolName
);
8735 CurrentFn
= nullptr;
8736 IsCpRestoreSet
= false;
8740 if (IDVal
== ".frame") {
8741 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8742 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> TmpReg
;
8743 ParseStatus Res
= parseAnyRegister(TmpReg
);
8744 if (Res
.isNoMatch() || Res
.isFailure()) {
8745 reportParseError("expected stack register");
8749 MipsOperand
&StackRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
8750 if (!StackRegOpnd
.isGPRAsmReg()) {
8751 reportParseError(StackRegOpnd
.getStartLoc(),
8752 "expected general purpose register");
8755 unsigned StackReg
= StackRegOpnd
.getGPR32Reg();
8757 if (Parser
.getTok().is(AsmToken::Comma
))
8760 reportParseError("unexpected token, expected comma");
8764 // Parse the frame size.
8765 const MCExpr
*FrameSize
;
8766 int64_t FrameSizeVal
;
8768 if (Parser
.parseExpression(FrameSize
)) {
8769 reportParseError("expected frame size value");
8773 if (!FrameSize
->evaluateAsAbsolute(FrameSizeVal
)) {
8774 reportParseError("frame size not an absolute expression");
8778 if (Parser
.getTok().is(AsmToken::Comma
))
8781 reportParseError("unexpected token, expected comma");
8785 // Parse the return register.
8787 Res
= parseAnyRegister(TmpReg
);
8788 if (Res
.isNoMatch() || Res
.isFailure()) {
8789 reportParseError("expected return register");
8793 MipsOperand
&ReturnRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
8794 if (!ReturnRegOpnd
.isGPRAsmReg()) {
8795 reportParseError(ReturnRegOpnd
.getStartLoc(),
8796 "expected general purpose register");
8800 // If this is not the end of the statement, report an error.
8801 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8802 reportParseError("unexpected token, expected end of statement");
8806 getTargetStreamer().emitFrame(StackReg
, FrameSizeVal
,
8807 ReturnRegOpnd
.getGPR32Reg());
8808 IsCpRestoreSet
= false;
8812 if (IDVal
== ".set") {
8813 parseDirectiveSet();
8817 if (IDVal
== ".mask" || IDVal
== ".fmask") {
8818 // .mask bitmask, frame_offset
8819 // bitmask: One bit for each register used.
8820 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8821 // first register is expected to be saved.
8823 // .mask 0x80000000, -4
8824 // .fmask 0x80000000, -4
8827 // Parse the bitmask
8828 const MCExpr
*BitMask
;
8831 if (Parser
.parseExpression(BitMask
)) {
8832 reportParseError("expected bitmask value");
8836 if (!BitMask
->evaluateAsAbsolute(BitMaskVal
)) {
8837 reportParseError("bitmask not an absolute expression");
8841 if (Parser
.getTok().is(AsmToken::Comma
))
8844 reportParseError("unexpected token, expected comma");
8848 // Parse the frame_offset
8849 const MCExpr
*FrameOffset
;
8850 int64_t FrameOffsetVal
;
8852 if (Parser
.parseExpression(FrameOffset
)) {
8853 reportParseError("expected frame offset value");
8857 if (!FrameOffset
->evaluateAsAbsolute(FrameOffsetVal
)) {
8858 reportParseError("frame offset not an absolute expression");
8862 // If this is not the end of the statement, report an error.
8863 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8864 reportParseError("unexpected token, expected end of statement");
8868 if (IDVal
== ".mask")
8869 getTargetStreamer().emitMask(BitMaskVal
, FrameOffsetVal
);
8871 getTargetStreamer().emitFMask(BitMaskVal
, FrameOffsetVal
);
8875 if (IDVal
== ".nan")
8876 return parseDirectiveNaN();
8878 if (IDVal
== ".gpword") {
8879 parseDirectiveGpWord();
8883 if (IDVal
== ".gpdword") {
8884 parseDirectiveGpDWord();
8888 if (IDVal
== ".dtprelword") {
8889 parseDirectiveDtpRelWord();
8893 if (IDVal
== ".dtpreldword") {
8894 parseDirectiveDtpRelDWord();
8898 if (IDVal
== ".tprelword") {
8899 parseDirectiveTpRelWord();
8903 if (IDVal
== ".tpreldword") {
8904 parseDirectiveTpRelDWord();
8908 if (IDVal
== ".option") {
8909 parseDirectiveOption();
8913 if (IDVal
== ".abicalls") {
8914 getTargetStreamer().emitDirectiveAbiCalls();
8915 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
8916 Error(Parser
.getTok().getLoc(),
8917 "unexpected token, expected end of statement");
8922 if (IDVal
== ".cpsetup") {
8923 parseDirectiveCPSetup();
8926 if (IDVal
== ".cpreturn") {
8927 parseDirectiveCPReturn();
8930 if (IDVal
== ".module") {
8931 parseDirectiveModule();
8934 if (IDVal
== ".llvm_internal_mips_reallow_module_directive") {
8935 parseInternalDirectiveReallowModule();
8938 if (IDVal
== ".insn") {
8939 parseInsnDirective();
8942 if (IDVal
== ".rdata") {
8943 parseRSectionDirective(".rodata");
8946 if (IDVal
== ".sbss") {
8947 parseSSectionDirective(IDVal
, ELF::SHT_NOBITS
);
8950 if (IDVal
== ".sdata") {
8951 parseSSectionDirective(IDVal
, ELF::SHT_PROGBITS
);
8958 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8959 // If this is not the end of the statement, report an error.
8960 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8961 reportParseError("unexpected token, expected end of statement");
8965 getTargetStreamer().reallowModuleDirective();
8967 getParser().Lex(); // Eat EndOfStatement token.
8971 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeMipsAsmParser() {
8972 RegisterMCAsmParser
<MipsAsmParser
> X(getTheMipsTarget());
8973 RegisterMCAsmParser
<MipsAsmParser
> Y(getTheMipselTarget());
8974 RegisterMCAsmParser
<MipsAsmParser
> A(getTheMips64Target());
8975 RegisterMCAsmParser
<MipsAsmParser
> B(getTheMips64elTarget());
8978 #define GET_REGISTER_MATCHER
8979 #define GET_MATCHER_IMPLEMENTATION
8980 #define GET_MNEMONIC_SPELL_CHECKER
8981 #include "MipsGenAsmMatcher.inc"
8983 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic
, unsigned VariantID
) {
8984 // Find the appropriate table for this asm variant.
8985 const MatchEntry
*Start
, *End
;
8986 switch (VariantID
) {
8987 default: llvm_unreachable("invalid variant!");
8988 case 0: Start
= std::begin(MatchTable0
); End
= std::end(MatchTable0
); break;
8990 // Search the table.
8991 auto MnemonicRange
= std::equal_range(Start
, End
, Mnemonic
, LessOpcode());
8992 return MnemonicRange
.first
!= MnemonicRange
.second
;