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/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCAsmParser.h"
31 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
32 #include "llvm/MC/MCParser/MCAsmParserUtils.h"
33 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
35 #include "llvm/MC/MCSectionELF.h"
36 #include "llvm/MC/MCStreamer.h"
37 #include "llvm/MC/MCSubtargetInfo.h"
38 #include "llvm/MC/MCSymbol.h"
39 #include "llvm/MC/MCSymbolELF.h"
40 #include "llvm/MC/MCValue.h"
41 #include "llvm/MC/SubtargetFeature.h"
42 #include "llvm/Support/Alignment.h"
43 #include "llvm/Support/Casting.h"
44 #include "llvm/Support/CommandLine.h"
45 #include "llvm/Support/Compiler.h"
46 #include "llvm/Support/Debug.h"
47 #include "llvm/Support/ErrorHandling.h"
48 #include "llvm/Support/MathExtras.h"
49 #include "llvm/Support/SMLoc.h"
50 #include "llvm/Support/SourceMgr.h"
51 #include "llvm/Support/TargetRegistry.h"
52 #include "llvm/Support/raw_ostream.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::FeatureFP64Bit
, Mips::FeatureGP64Bit
, Mips::FeatureNaN2008
134 class MipsAsmParser
: public MCTargetAsmParser
{
135 MipsTargetStreamer
&getTargetStreamer() {
136 MCTargetStreamer
&TS
= *getParser().getStreamer().getTargetStreamer();
137 return static_cast<MipsTargetStreamer
&>(TS
);
141 SmallVector
<std::unique_ptr
<MipsAssemblerOptions
>, 2> AssemblerOptions
;
142 MCSymbol
*CurrentFn
; // Pointer to the function being parsed. It may be a
143 // nullptr, which indicates that no function is currently
144 // selected. This usually happens after an '.end func'
151 unsigned CpSaveLocation
;
152 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
153 bool CpSaveLocationIsRegister
;
155 // Map of register aliases created via the .set directive.
156 StringMap
<AsmToken
> RegisterSets
;
158 // Print a warning along with its fix-it message at the given range.
159 void printWarningWithFixIt(const Twine
&Msg
, const Twine
&FixMsg
,
160 SMRange Range
, bool ShowColors
= true);
162 void ConvertXWPOperands(MCInst
&Inst
, const OperandVector
&Operands
);
164 #define GET_ASSEMBLER_HEADER
165 #include "MipsGenAsmMatcher.inc"
168 checkEarlyTargetMatchPredicate(MCInst
&Inst
,
169 const OperandVector
&Operands
) override
;
170 unsigned checkTargetMatchPredicate(MCInst
&Inst
) override
;
172 bool MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
173 OperandVector
&Operands
, MCStreamer
&Out
,
175 bool MatchingInlineAsm
) override
;
177 /// Parse a register as used in CFI directives
178 bool ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
180 bool parseParenSuffix(StringRef Name
, OperandVector
&Operands
);
182 bool parseBracketSuffix(StringRef Name
, OperandVector
&Operands
);
184 bool mnemonicIsValid(StringRef Mnemonic
, unsigned VariantID
);
186 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
187 SMLoc NameLoc
, OperandVector
&Operands
) override
;
189 bool ParseDirective(AsmToken DirectiveID
) override
;
191 OperandMatchResultTy
parseMemOperand(OperandVector
&Operands
);
193 matchAnyRegisterNameWithoutDollar(OperandVector
&Operands
,
194 StringRef Identifier
, SMLoc S
);
195 OperandMatchResultTy
matchAnyRegisterWithoutDollar(OperandVector
&Operands
,
196 const AsmToken
&Token
,
198 OperandMatchResultTy
matchAnyRegisterWithoutDollar(OperandVector
&Operands
,
200 OperandMatchResultTy
parseAnyRegister(OperandVector
&Operands
);
201 OperandMatchResultTy
parseImm(OperandVector
&Operands
);
202 OperandMatchResultTy
parseJumpTarget(OperandVector
&Operands
);
203 OperandMatchResultTy
parseInvNum(OperandVector
&Operands
);
204 OperandMatchResultTy
parseRegisterList(OperandVector
&Operands
);
206 bool searchSymbolAlias(OperandVector
&Operands
);
208 bool parseOperand(OperandVector
&, StringRef Mnemonic
);
210 enum MacroExpanderResultTy
{
216 // Expands assembly pseudo instructions.
217 MacroExpanderResultTy
tryExpandInstruction(MCInst
&Inst
, SMLoc IDLoc
,
219 const MCSubtargetInfo
*STI
);
221 bool expandJalWithRegs(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
222 const MCSubtargetInfo
*STI
);
224 bool loadImmediate(int64_t ImmValue
, unsigned DstReg
, unsigned SrcReg
,
225 bool Is32BitImm
, bool IsAddress
, SMLoc IDLoc
,
226 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
228 bool loadAndAddSymbolAddress(const MCExpr
*SymExpr
, unsigned DstReg
,
229 unsigned SrcReg
, bool Is32BitSym
, SMLoc IDLoc
,
230 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
232 bool emitPartialAddress(MipsTargetStreamer
&TOut
, SMLoc IDLoc
, MCSymbol
*Sym
);
234 bool expandLoadImm(MCInst
&Inst
, bool Is32BitImm
, SMLoc IDLoc
,
235 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
237 bool expandLoadSingleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
238 const MCSubtargetInfo
*STI
);
239 bool expandLoadSingleImmToFPR(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
240 const MCSubtargetInfo
*STI
);
241 bool expandLoadDoubleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
242 const MCSubtargetInfo
*STI
);
243 bool expandLoadDoubleImmToFPR(MCInst
&Inst
, bool Is64FPU
, SMLoc IDLoc
,
244 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
246 bool expandLoadAddress(unsigned DstReg
, unsigned BaseReg
,
247 const MCOperand
&Offset
, bool Is32BitAddress
,
248 SMLoc IDLoc
, MCStreamer
&Out
,
249 const MCSubtargetInfo
*STI
);
251 bool expandUncondBranchMMPseudo(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
252 const MCSubtargetInfo
*STI
);
254 void expandMemInst(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
255 const MCSubtargetInfo
*STI
, bool IsLoad
);
257 bool expandLoadStoreMultiple(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
258 const MCSubtargetInfo
*STI
);
260 bool expandAliasImmediate(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
261 const MCSubtargetInfo
*STI
);
263 bool expandBranchImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
264 const MCSubtargetInfo
*STI
);
266 bool expandCondBranches(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
267 const MCSubtargetInfo
*STI
);
269 bool expandDivRem(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
270 const MCSubtargetInfo
*STI
, const bool IsMips64
,
273 bool expandTrunc(MCInst
&Inst
, bool IsDouble
, bool Is64FPU
, SMLoc IDLoc
,
274 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
276 bool expandUlh(MCInst
&Inst
, bool Signed
, SMLoc IDLoc
, MCStreamer
&Out
,
277 const MCSubtargetInfo
*STI
);
279 bool expandUsh(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
280 const MCSubtargetInfo
*STI
);
282 bool expandUxw(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
283 const MCSubtargetInfo
*STI
);
285 bool expandSge(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
286 const MCSubtargetInfo
*STI
);
288 bool expandSgeImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
289 const MCSubtargetInfo
*STI
);
291 bool expandSgtImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
292 const MCSubtargetInfo
*STI
);
294 bool expandRotation(MCInst
&Inst
, SMLoc IDLoc
,
295 MCStreamer
&Out
, const MCSubtargetInfo
*STI
);
296 bool expandRotationImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
297 const MCSubtargetInfo
*STI
);
298 bool expandDRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
299 const MCSubtargetInfo
*STI
);
300 bool expandDRotationImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
301 const MCSubtargetInfo
*STI
);
303 bool expandAbs(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
304 const MCSubtargetInfo
*STI
);
306 bool expandMulImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
307 const MCSubtargetInfo
*STI
);
309 bool expandMulO(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
310 const MCSubtargetInfo
*STI
);
312 bool expandMulOU(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
313 const MCSubtargetInfo
*STI
);
315 bool expandDMULMacro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
316 const MCSubtargetInfo
*STI
);
318 bool expandLoadStoreDMacro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
319 const MCSubtargetInfo
*STI
, bool IsLoad
);
321 bool expandStoreDM1Macro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
322 const MCSubtargetInfo
*STI
);
324 bool expandSeq(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
325 const MCSubtargetInfo
*STI
);
327 bool expandSeqI(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
328 const MCSubtargetInfo
*STI
);
330 bool expandMXTRAlias(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
331 const MCSubtargetInfo
*STI
);
333 bool reportParseError(Twine ErrorMsg
);
334 bool reportParseError(SMLoc Loc
, Twine ErrorMsg
);
336 bool parseMemOffset(const MCExpr
*&Res
, bool isParenExpr
);
338 bool isEvaluated(const MCExpr
*Expr
);
339 bool parseSetMips0Directive();
340 bool parseSetArchDirective();
341 bool parseSetFeature(uint64_t Feature
);
342 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
343 bool parseDirectiveCpLoad(SMLoc Loc
);
344 bool parseDirectiveCpLocal(SMLoc Loc
);
345 bool parseDirectiveCpRestore(SMLoc Loc
);
346 bool parseDirectiveCPSetup();
347 bool parseDirectiveCPReturn();
348 bool parseDirectiveNaN();
349 bool parseDirectiveSet();
350 bool parseDirectiveOption();
351 bool parseInsnDirective();
352 bool parseRSectionDirective(StringRef Section
);
353 bool parseSSectionDirective(StringRef Section
, unsigned Type
);
355 bool parseSetAtDirective();
356 bool parseSetNoAtDirective();
357 bool parseSetMacroDirective();
358 bool parseSetNoMacroDirective();
359 bool parseSetMsaDirective();
360 bool parseSetNoMsaDirective();
361 bool parseSetNoDspDirective();
362 bool parseSetReorderDirective();
363 bool parseSetNoReorderDirective();
364 bool parseSetMips16Directive();
365 bool parseSetNoMips16Directive();
366 bool parseSetFpDirective();
367 bool parseSetOddSPRegDirective();
368 bool parseSetNoOddSPRegDirective();
369 bool parseSetPopDirective();
370 bool parseSetPushDirective();
371 bool parseSetSoftFloatDirective();
372 bool parseSetHardFloatDirective();
373 bool parseSetMtDirective();
374 bool parseSetNoMtDirective();
375 bool parseSetNoCRCDirective();
376 bool parseSetNoVirtDirective();
377 bool parseSetNoGINVDirective();
379 bool parseSetAssignment();
381 bool parseDirectiveGpWord();
382 bool parseDirectiveGpDWord();
383 bool parseDirectiveDtpRelWord();
384 bool parseDirectiveDtpRelDWord();
385 bool parseDirectiveTpRelWord();
386 bool parseDirectiveTpRelDWord();
387 bool parseDirectiveModule();
388 bool parseDirectiveModuleFP();
389 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind
&FpABI
,
390 StringRef Directive
);
392 bool parseInternalDirectiveReallowModule();
394 bool eatComma(StringRef ErrorStr
);
396 int matchCPURegisterName(StringRef Symbol
);
398 int matchHWRegsRegisterName(StringRef Symbol
);
400 int matchFPURegisterName(StringRef Name
);
402 int matchFCCRegisterName(StringRef Name
);
404 int matchACRegisterName(StringRef Name
);
406 int matchMSA128RegisterName(StringRef Name
);
408 int matchMSA128CtrlRegisterName(StringRef Name
);
410 unsigned getReg(int RC
, int RegNo
);
412 /// Returns the internal register number for the current AT. Also checks if
413 /// the current AT is unavailable (set to $0) and gives an error if it is.
414 /// This should be used in pseudo-instruction expansions which need AT.
415 unsigned getATReg(SMLoc Loc
);
419 bool processInstruction(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
420 const MCSubtargetInfo
*STI
);
422 // Helper function that checks if the value of a vector index is within the
423 // boundaries of accepted values for each RegisterKind
424 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
425 bool validateMSAIndex(int Val
, int RegKind
);
427 // Selects a new architecture by updating the FeatureBits with the necessary
428 // info including implied dependencies.
429 // Internally, it clears all the feature bits related to *any* architecture
430 // and selects the new one using the ToggleFeature functionality of the
431 // MCSubtargetInfo object that handles implied dependencies. The reason we
432 // clear all the arch related bits manually is because ToggleFeature only
433 // clears the features that imply the feature being cleared and not the
434 // features implied by the feature being cleared. This is easier to see
436 // --------------------------------------------------
437 // | Feature | Implies |
438 // | -------------------------------------------------|
439 // | FeatureMips1 | None |
440 // | FeatureMips2 | FeatureMips1 |
441 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
442 // | FeatureMips4 | FeatureMips3 |
444 // --------------------------------------------------
446 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
447 // FeatureMipsGP64 | FeatureMips1)
448 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
449 void selectArch(StringRef ArchFeature
) {
450 MCSubtargetInfo
&STI
= copySTI();
451 FeatureBitset FeatureBits
= STI
.getFeatureBits();
452 FeatureBits
&= ~MipsAssemblerOptions::AllArchRelatedMask
;
453 STI
.setFeatureBits(FeatureBits
);
454 setAvailableFeatures(
455 ComputeAvailableFeatures(STI
.ToggleFeature(ArchFeature
)));
456 AssemblerOptions
.back()->setFeatures(STI
.getFeatureBits());
459 void setFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
460 if (!(getSTI().getFeatureBits()[Feature
])) {
461 MCSubtargetInfo
&STI
= copySTI();
462 setAvailableFeatures(
463 ComputeAvailableFeatures(STI
.ToggleFeature(FeatureString
)));
464 AssemblerOptions
.back()->setFeatures(STI
.getFeatureBits());
468 void clearFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
469 if (getSTI().getFeatureBits()[Feature
]) {
470 MCSubtargetInfo
&STI
= copySTI();
471 setAvailableFeatures(
472 ComputeAvailableFeatures(STI
.ToggleFeature(FeatureString
)));
473 AssemblerOptions
.back()->setFeatures(STI
.getFeatureBits());
477 void setModuleFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
478 setFeatureBits(Feature
, FeatureString
);
479 AssemblerOptions
.front()->setFeatures(getSTI().getFeatureBits());
482 void clearModuleFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
483 clearFeatureBits(Feature
, FeatureString
);
484 AssemblerOptions
.front()->setFeatures(getSTI().getFeatureBits());
488 enum MipsMatchResultTy
{
489 Match_RequiresDifferentSrcAndDst
= FIRST_TARGET_MATCH_RESULT_TY
,
490 Match_RequiresDifferentOperands
,
491 Match_RequiresNoZeroRegister
,
492 Match_RequiresSameSrcAndDst
,
493 Match_NoFCCRegisterForCurrentISA
,
494 Match_NonZeroOperandForSync
,
495 Match_NonZeroOperandForMTCX
,
496 Match_RequiresPosSizeRange0_32
,
497 Match_RequiresPosSizeRange33_64
,
498 Match_RequiresPosSizeUImm6
,
499 #define GET_OPERAND_DIAGNOSTIC_TYPES
500 #include "MipsGenAsmMatcher.inc"
501 #undef GET_OPERAND_DIAGNOSTIC_TYPES
504 MipsAsmParser(const MCSubtargetInfo
&sti
, MCAsmParser
&parser
,
505 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
506 : MCTargetAsmParser(Options
, sti
, MII
),
507 ABI(MipsABIInfo::computeTargetABI(Triple(sti
.getTargetTriple()),
508 sti
.getCPU(), Options
)) {
509 MCAsmParserExtension::Initialize(parser
);
511 parser
.addAliasForDirective(".asciiz", ".asciz");
512 parser
.addAliasForDirective(".hword", ".2byte");
513 parser
.addAliasForDirective(".word", ".4byte");
514 parser
.addAliasForDirective(".dword", ".8byte");
516 // Initialize the set of available features.
517 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
519 // Remember the initial assembler options. The user can not modify these.
520 AssemblerOptions
.push_back(
521 std::make_unique
<MipsAssemblerOptions
>(getSTI().getFeatureBits()));
523 // Create an assembler options environment for the user to modify.
524 AssemblerOptions
.push_back(
525 std::make_unique
<MipsAssemblerOptions
>(getSTI().getFeatureBits()));
527 getTargetStreamer().updateABIInfo(*this);
529 if (!isABI_O32() && !useOddSPReg() != 0)
530 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
534 IsPicEnabled
= getContext().getObjectFileInfo()->isPositionIndependent();
536 IsCpRestoreSet
= false;
537 CpRestoreOffset
= -1;
538 GPReg
= ABI
.GetGlobalPtr();
540 const Triple
&TheTriple
= sti
.getTargetTriple();
541 IsLittleEndian
= TheTriple
.isLittleEndian();
543 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
544 report_fatal_error("microMIPS64R6 is not supported", false);
546 if (!isABI_O32() && inMicroMipsMode())
547 report_fatal_error("microMIPS64 is not supported", false);
550 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
551 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
553 bool isGP64bit() const {
554 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit
];
557 bool isFP64bit() const {
558 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit
];
561 const MipsABIInfo
&getABI() const { return ABI
; }
562 bool isABI_N32() const { return ABI
.IsN32(); }
563 bool isABI_N64() const { return ABI
.IsN64(); }
564 bool isABI_O32() const { return ABI
.IsO32(); }
565 bool isABI_FPXX() const {
566 return getSTI().getFeatureBits()[Mips::FeatureFPXX
];
569 bool useOddSPReg() const {
570 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg
]);
573 bool inMicroMipsMode() const {
574 return getSTI().getFeatureBits()[Mips::FeatureMicroMips
];
577 bool hasMips1() const {
578 return getSTI().getFeatureBits()[Mips::FeatureMips1
];
581 bool hasMips2() const {
582 return getSTI().getFeatureBits()[Mips::FeatureMips2
];
585 bool hasMips3() const {
586 return getSTI().getFeatureBits()[Mips::FeatureMips3
];
589 bool hasMips4() const {
590 return getSTI().getFeatureBits()[Mips::FeatureMips4
];
593 bool hasMips5() const {
594 return getSTI().getFeatureBits()[Mips::FeatureMips5
];
597 bool hasMips32() const {
598 return getSTI().getFeatureBits()[Mips::FeatureMips32
];
601 bool hasMips64() const {
602 return getSTI().getFeatureBits()[Mips::FeatureMips64
];
605 bool hasMips32r2() const {
606 return getSTI().getFeatureBits()[Mips::FeatureMips32r2
];
609 bool hasMips64r2() const {
610 return getSTI().getFeatureBits()[Mips::FeatureMips64r2
];
613 bool hasMips32r3() const {
614 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3
]);
617 bool hasMips64r3() const {
618 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3
]);
621 bool hasMips32r5() const {
622 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5
]);
625 bool hasMips64r5() const {
626 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5
]);
629 bool hasMips32r6() const {
630 return getSTI().getFeatureBits()[Mips::FeatureMips32r6
];
633 bool hasMips64r6() const {
634 return getSTI().getFeatureBits()[Mips::FeatureMips64r6
];
637 bool hasDSP() const {
638 return getSTI().getFeatureBits()[Mips::FeatureDSP
];
641 bool hasDSPR2() const {
642 return getSTI().getFeatureBits()[Mips::FeatureDSPR2
];
645 bool hasDSPR3() const {
646 return getSTI().getFeatureBits()[Mips::FeatureDSPR3
];
649 bool hasMSA() const {
650 return getSTI().getFeatureBits()[Mips::FeatureMSA
];
653 bool hasCnMips() const {
654 return (getSTI().getFeatureBits()[Mips::FeatureCnMips
]);
661 bool inMips16Mode() const {
662 return getSTI().getFeatureBits()[Mips::FeatureMips16
];
665 bool useTraps() const {
666 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV
];
669 bool useSoftFloat() const {
670 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat
];
673 return getSTI().getFeatureBits()[Mips::FeatureMT
];
676 bool hasCRC() const {
677 return getSTI().getFeatureBits()[Mips::FeatureCRC
];
680 bool hasVirt() const {
681 return getSTI().getFeatureBits()[Mips::FeatureVirt
];
684 bool hasGINV() const {
685 return getSTI().getFeatureBits()[Mips::FeatureGINV
];
688 /// Warn if RegIndex is the same as the current AT.
689 void warnIfRegIndexIsAT(unsigned RegIndex
, SMLoc Loc
);
691 void warnIfNoMacro(SMLoc Loc
);
693 bool isLittle() const { return IsLittleEndian
; }
695 const MCExpr
*createTargetUnaryExpr(const MCExpr
*E
,
696 AsmToken::TokenKind OperatorToken
,
697 MCContext
&Ctx
) override
{
698 switch(OperatorToken
) {
700 llvm_unreachable("Unknown token");
702 case AsmToken::PercentCall16
:
703 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL
, E
, Ctx
);
704 case AsmToken::PercentCall_Hi
:
705 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16
, E
, Ctx
);
706 case AsmToken::PercentCall_Lo
:
707 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16
, E
, Ctx
);
708 case AsmToken::PercentDtprel_Hi
:
709 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI
, E
, Ctx
);
710 case AsmToken::PercentDtprel_Lo
:
711 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO
, E
, Ctx
);
712 case AsmToken::PercentGot
:
713 return MipsMCExpr::create(MipsMCExpr::MEK_GOT
, E
, Ctx
);
714 case AsmToken::PercentGot_Disp
:
715 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP
, E
, Ctx
);
716 case AsmToken::PercentGot_Hi
:
717 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16
, E
, Ctx
);
718 case AsmToken::PercentGot_Lo
:
719 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16
, E
, Ctx
);
720 case AsmToken::PercentGot_Ofst
:
721 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST
, E
, Ctx
);
722 case AsmToken::PercentGot_Page
:
723 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE
, E
, Ctx
);
724 case AsmToken::PercentGottprel
:
725 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL
, E
, Ctx
);
726 case AsmToken::PercentGp_Rel
:
727 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL
, E
, Ctx
);
728 case AsmToken::PercentHi
:
729 return MipsMCExpr::create(MipsMCExpr::MEK_HI
, E
, Ctx
);
730 case AsmToken::PercentHigher
:
731 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER
, E
, Ctx
);
732 case AsmToken::PercentHighest
:
733 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST
, E
, Ctx
);
734 case AsmToken::PercentLo
:
735 return MipsMCExpr::create(MipsMCExpr::MEK_LO
, E
, Ctx
);
736 case AsmToken::PercentNeg
:
737 return MipsMCExpr::create(MipsMCExpr::MEK_NEG
, E
, Ctx
);
738 case AsmToken::PercentPcrel_Hi
:
739 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16
, E
, Ctx
);
740 case AsmToken::PercentPcrel_Lo
:
741 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16
, E
, Ctx
);
742 case AsmToken::PercentTlsgd
:
743 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD
, E
, Ctx
);
744 case AsmToken::PercentTlsldm
:
745 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM
, E
, Ctx
);
746 case AsmToken::PercentTprel_Hi
:
747 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI
, E
, Ctx
);
748 case AsmToken::PercentTprel_Lo
:
749 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO
, E
, Ctx
);
754 /// MipsOperand - Instances of this class represent a parsed Mips machine
756 class MipsOperand
: public MCParsedAsmOperand
{
758 /// Broad categories of register classes
759 /// The exact class is finalized by the render method.
761 RegKind_GPR
= 1, /// GPR32 and GPR64 (depending on isGP64bit())
762 RegKind_FGR
= 2, /// FGR32, FGR64, AFGR64 (depending on context and
764 RegKind_FCC
= 4, /// FCC
765 RegKind_MSA128
= 8, /// MSA128[BHWD] (makes no difference which)
766 RegKind_MSACtrl
= 16, /// MSA control registers
767 RegKind_COP2
= 32, /// COP2
768 RegKind_ACC
= 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
770 RegKind_CCR
= 128, /// CCR
771 RegKind_HWRegs
= 256, /// HWRegs
772 RegKind_COP3
= 512, /// COP3
773 RegKind_COP0
= 1024, /// COP0
774 /// Potentially any (e.g. $1)
775 RegKind_Numeric
= RegKind_GPR
| RegKind_FGR
| RegKind_FCC
| RegKind_MSA128
|
776 RegKind_MSACtrl
| RegKind_COP2
| RegKind_ACC
|
777 RegKind_CCR
| RegKind_HWRegs
| RegKind_COP3
| RegKind_COP0
782 k_Immediate
, /// An immediate (possibly involving symbol references)
783 k_Memory
, /// Base + Offset Memory Address
784 k_RegisterIndex
, /// A register index in one or more RegKind.
785 k_Token
, /// A simple token
786 k_RegList
, /// A physical register list
790 MipsOperand(KindTy K
, MipsAsmParser
&Parser
)
791 : MCParsedAsmOperand(), Kind(K
), AsmParser(Parser
) {}
793 ~MipsOperand() override
{
802 case k_RegisterIndex
:
809 /// For diagnostics, and checking the assembler temporary
810 MipsAsmParser
&AsmParser
;
818 unsigned Index
; /// Index into the register class
819 RegKind Kind
; /// Bitfield of the kinds it could possibly be
820 struct Token Tok
; /// The input token this operand originated from.
821 const MCRegisterInfo
*RegInfo
;
834 SmallVector
<unsigned, 10> *List
;
839 struct RegIdxOp RegIdx
;
842 struct RegListOp RegList
;
845 SMLoc StartLoc
, EndLoc
;
847 /// Internal constructor for register kinds
848 static std::unique_ptr
<MipsOperand
> CreateReg(unsigned Index
, StringRef Str
,
850 const MCRegisterInfo
*RegInfo
,
852 MipsAsmParser
&Parser
) {
853 auto Op
= std::make_unique
<MipsOperand
>(k_RegisterIndex
, Parser
);
854 Op
->RegIdx
.Index
= Index
;
855 Op
->RegIdx
.RegInfo
= RegInfo
;
856 Op
->RegIdx
.Kind
= RegKind
;
857 Op
->RegIdx
.Tok
.Data
= Str
.data();
858 Op
->RegIdx
.Tok
.Length
= Str
.size();
865 /// Coerce the register to GPR32 and return the real register for the current
867 unsigned getGPR32Reg() const {
868 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_GPR
) && "Invalid access!");
869 AsmParser
.warnIfRegIndexIsAT(RegIdx
.Index
, StartLoc
);
870 unsigned ClassID
= Mips::GPR32RegClassID
;
871 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
874 /// Coerce the register to GPR32 and return the real register for the current
876 unsigned getGPRMM16Reg() const {
877 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_GPR
) && "Invalid access!");
878 unsigned ClassID
= Mips::GPR32RegClassID
;
879 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
882 /// Coerce the register to GPR64 and return the real register for the current
884 unsigned getGPR64Reg() const {
885 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_GPR
) && "Invalid access!");
886 unsigned ClassID
= Mips::GPR64RegClassID
;
887 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
891 /// Coerce the register to AFGR64 and return the real register for the current
893 unsigned getAFGR64Reg() const {
894 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FGR
) && "Invalid access!");
895 if (RegIdx
.Index
% 2 != 0)
896 AsmParser
.Warning(StartLoc
, "Float register should be even.");
897 return RegIdx
.RegInfo
->getRegClass(Mips::AFGR64RegClassID
)
898 .getRegister(RegIdx
.Index
/ 2);
901 /// Coerce the register to FGR64 and return the real register for the current
903 unsigned getFGR64Reg() const {
904 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FGR
) && "Invalid access!");
905 return RegIdx
.RegInfo
->getRegClass(Mips::FGR64RegClassID
)
906 .getRegister(RegIdx
.Index
);
909 /// Coerce the register to FGR32 and return the real register for the current
911 unsigned getFGR32Reg() const {
912 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FGR
) && "Invalid access!");
913 return RegIdx
.RegInfo
->getRegClass(Mips::FGR32RegClassID
)
914 .getRegister(RegIdx
.Index
);
917 /// Coerce the register to FCC and return the real register for the current
919 unsigned getFCCReg() const {
920 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_FCC
) && "Invalid access!");
921 return RegIdx
.RegInfo
->getRegClass(Mips::FCCRegClassID
)
922 .getRegister(RegIdx
.Index
);
925 /// Coerce the register to MSA128 and return the real register for the current
927 unsigned getMSA128Reg() const {
928 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_MSA128
) && "Invalid access!");
929 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
931 unsigned ClassID
= Mips::MSA128BRegClassID
;
932 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
935 /// Coerce the register to MSACtrl and return the real register for the
937 unsigned getMSACtrlReg() const {
938 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_MSACtrl
) && "Invalid access!");
939 unsigned ClassID
= Mips::MSACtrlRegClassID
;
940 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
943 /// Coerce the register to COP0 and return the real register for the
945 unsigned getCOP0Reg() const {
946 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_COP0
) && "Invalid access!");
947 unsigned ClassID
= Mips::COP0RegClassID
;
948 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
951 /// Coerce the register to COP2 and return the real register for the
953 unsigned getCOP2Reg() const {
954 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_COP2
) && "Invalid access!");
955 unsigned ClassID
= Mips::COP2RegClassID
;
956 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
959 /// Coerce the register to COP3 and return the real register for the
961 unsigned getCOP3Reg() const {
962 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_COP3
) && "Invalid access!");
963 unsigned ClassID
= Mips::COP3RegClassID
;
964 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
967 /// Coerce the register to ACC64DSP and return the real register for the
969 unsigned getACC64DSPReg() const {
970 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_ACC
) && "Invalid access!");
971 unsigned ClassID
= Mips::ACC64DSPRegClassID
;
972 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
975 /// Coerce the register to HI32DSP and return the real register for the
977 unsigned getHI32DSPReg() const {
978 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_ACC
) && "Invalid access!");
979 unsigned ClassID
= Mips::HI32DSPRegClassID
;
980 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
983 /// Coerce the register to LO32DSP and return the real register for the
985 unsigned getLO32DSPReg() const {
986 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_ACC
) && "Invalid access!");
987 unsigned ClassID
= Mips::LO32DSPRegClassID
;
988 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
991 /// Coerce the register to CCR and return the real register for the
993 unsigned getCCRReg() const {
994 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_CCR
) && "Invalid access!");
995 unsigned ClassID
= Mips::CCRRegClassID
;
996 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
999 /// Coerce the register to HWRegs and return the real register for the
1001 unsigned getHWRegsReg() const {
1002 assert(isRegIdx() && (RegIdx
.Kind
& RegKind_HWRegs
) && "Invalid access!");
1003 unsigned ClassID
= Mips::HWRegsRegClassID
;
1004 return RegIdx
.RegInfo
->getRegClass(ClassID
).getRegister(RegIdx
.Index
);
1008 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
1009 // Add as immediate when possible. Null MCExpr = 0.
1011 Inst
.addOperand(MCOperand::createImm(0));
1012 else if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Expr
))
1013 Inst
.addOperand(MCOperand::createImm(CE
->getValue()));
1015 Inst
.addOperand(MCOperand::createExpr(Expr
));
1018 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
1019 llvm_unreachable("Use a custom parser instead");
1022 /// Render the operand to an MCInst as a GPR32
1023 /// Asserts if the wrong number of operands are requested, or the operand
1024 /// is not a k_RegisterIndex compatible with RegKind_GPR
1025 void addGPR32ZeroAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1026 assert(N
== 1 && "Invalid number of operands!");
1027 Inst
.addOperand(MCOperand::createReg(getGPR32Reg()));
1030 void addGPR32NonZeroAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1031 assert(N
== 1 && "Invalid number of operands!");
1032 Inst
.addOperand(MCOperand::createReg(getGPR32Reg()));
1035 void addGPR32AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1036 assert(N
== 1 && "Invalid number of operands!");
1037 Inst
.addOperand(MCOperand::createReg(getGPR32Reg()));
1040 void addGPRMM16AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1041 assert(N
== 1 && "Invalid number of operands!");
1042 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1045 void addGPRMM16AsmRegZeroOperands(MCInst
&Inst
, unsigned N
) const {
1046 assert(N
== 1 && "Invalid number of operands!");
1047 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1050 void addGPRMM16AsmRegMovePOperands(MCInst
&Inst
, unsigned N
) const {
1051 assert(N
== 1 && "Invalid number of operands!");
1052 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1055 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst
&Inst
, unsigned N
) const {
1056 assert(N
== 1 && "Invalid number of operands!");
1057 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1060 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst
&Inst
,
1062 assert(N
== 1 && "Invalid number of operands!");
1063 Inst
.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1066 /// Render the operand to an MCInst as a GPR64
1067 /// Asserts if the wrong number of operands are requested, or the operand
1068 /// is not a k_RegisterIndex compatible with RegKind_GPR
1069 void addGPR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1070 assert(N
== 1 && "Invalid number of operands!");
1071 Inst
.addOperand(MCOperand::createReg(getGPR64Reg()));
1074 void addAFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1075 assert(N
== 1 && "Invalid number of operands!");
1076 Inst
.addOperand(MCOperand::createReg(getAFGR64Reg()));
1079 void addStrictlyAFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1080 assert(N
== 1 && "Invalid number of operands!");
1081 Inst
.addOperand(MCOperand::createReg(getAFGR64Reg()));
1084 void addStrictlyFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1085 assert(N
== 1 && "Invalid number of operands!");
1086 Inst
.addOperand(MCOperand::createReg(getFGR64Reg()));
1089 void addFGR64AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1090 assert(N
== 1 && "Invalid number of operands!");
1091 Inst
.addOperand(MCOperand::createReg(getFGR64Reg()));
1094 void addFGR32AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1095 assert(N
== 1 && "Invalid number of operands!");
1096 Inst
.addOperand(MCOperand::createReg(getFGR32Reg()));
1097 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1098 // FIXME: This should propagate failure up to parseStatement.
1099 if (!AsmParser
.useOddSPReg() && RegIdx
.Index
& 1)
1100 AsmParser
.getParser().printError(
1101 StartLoc
, "-mno-odd-spreg prohibits the use of odd FPU "
1105 void addStrictlyFGR32AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1106 assert(N
== 1 && "Invalid number of operands!");
1107 Inst
.addOperand(MCOperand::createReg(getFGR32Reg()));
1108 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1109 if (!AsmParser
.useOddSPReg() && RegIdx
.Index
& 1)
1110 AsmParser
.Error(StartLoc
, "-mno-odd-spreg prohibits the use of odd FPU "
1114 void addFCCAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1115 assert(N
== 1 && "Invalid number of operands!");
1116 Inst
.addOperand(MCOperand::createReg(getFCCReg()));
1119 void addMSA128AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1120 assert(N
== 1 && "Invalid number of operands!");
1121 Inst
.addOperand(MCOperand::createReg(getMSA128Reg()));
1124 void addMSACtrlAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1125 assert(N
== 1 && "Invalid number of operands!");
1126 Inst
.addOperand(MCOperand::createReg(getMSACtrlReg()));
1129 void addCOP0AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1130 assert(N
== 1 && "Invalid number of operands!");
1131 Inst
.addOperand(MCOperand::createReg(getCOP0Reg()));
1134 void addCOP2AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1135 assert(N
== 1 && "Invalid number of operands!");
1136 Inst
.addOperand(MCOperand::createReg(getCOP2Reg()));
1139 void addCOP3AsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1140 assert(N
== 1 && "Invalid number of operands!");
1141 Inst
.addOperand(MCOperand::createReg(getCOP3Reg()));
1144 void addACC64DSPAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1145 assert(N
== 1 && "Invalid number of operands!");
1146 Inst
.addOperand(MCOperand::createReg(getACC64DSPReg()));
1149 void addHI32DSPAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1150 assert(N
== 1 && "Invalid number of operands!");
1151 Inst
.addOperand(MCOperand::createReg(getHI32DSPReg()));
1154 void addLO32DSPAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1155 assert(N
== 1 && "Invalid number of operands!");
1156 Inst
.addOperand(MCOperand::createReg(getLO32DSPReg()));
1159 void addCCRAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1160 assert(N
== 1 && "Invalid number of operands!");
1161 Inst
.addOperand(MCOperand::createReg(getCCRReg()));
1164 void addHWRegsAsmRegOperands(MCInst
&Inst
, unsigned N
) const {
1165 assert(N
== 1 && "Invalid number of operands!");
1166 Inst
.addOperand(MCOperand::createReg(getHWRegsReg()));
1169 template <unsigned Bits
, int Offset
= 0, int AdjustOffset
= 0>
1170 void addConstantUImmOperands(MCInst
&Inst
, unsigned N
) const {
1171 assert(N
== 1 && "Invalid number of operands!");
1172 uint64_t Imm
= getConstantImm() - Offset
;
1173 Imm
&= (1ULL << Bits
) - 1;
1175 Imm
+= AdjustOffset
;
1176 Inst
.addOperand(MCOperand::createImm(Imm
));
1179 template <unsigned Bits
>
1180 void addSImmOperands(MCInst
&Inst
, unsigned N
) const {
1181 if (isImm() && !isConstantImm()) {
1182 addExpr(Inst
, getImm());
1185 addConstantSImmOperands
<Bits
, 0, 0>(Inst
, N
);
1188 template <unsigned Bits
>
1189 void addUImmOperands(MCInst
&Inst
, unsigned N
) const {
1190 if (isImm() && !isConstantImm()) {
1191 addExpr(Inst
, getImm());
1194 addConstantUImmOperands
<Bits
, 0, 0>(Inst
, N
);
1197 template <unsigned Bits
, int Offset
= 0, int AdjustOffset
= 0>
1198 void addConstantSImmOperands(MCInst
&Inst
, unsigned N
) const {
1199 assert(N
== 1 && "Invalid number of operands!");
1200 int64_t Imm
= getConstantImm() - Offset
;
1201 Imm
= SignExtend64
<Bits
>(Imm
);
1203 Imm
+= AdjustOffset
;
1204 Inst
.addOperand(MCOperand::createImm(Imm
));
1207 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
1208 assert(N
== 1 && "Invalid number of operands!");
1209 const MCExpr
*Expr
= getImm();
1210 addExpr(Inst
, Expr
);
1213 void addMemOperands(MCInst
&Inst
, unsigned N
) const {
1214 assert(N
== 2 && "Invalid number of operands!");
1216 Inst
.addOperand(MCOperand::createReg(AsmParser
.getABI().ArePtrs64bit()
1217 ? getMemBase()->getGPR64Reg()
1218 : getMemBase()->getGPR32Reg()));
1220 const MCExpr
*Expr
= getMemOff();
1221 addExpr(Inst
, Expr
);
1224 void addMicroMipsMemOperands(MCInst
&Inst
, unsigned N
) const {
1225 assert(N
== 2 && "Invalid number of operands!");
1227 Inst
.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1229 const MCExpr
*Expr
= getMemOff();
1230 addExpr(Inst
, Expr
);
1233 void addRegListOperands(MCInst
&Inst
, unsigned N
) const {
1234 assert(N
== 1 && "Invalid number of operands!");
1236 for (auto RegNo
: getRegList())
1237 Inst
.addOperand(MCOperand::createReg(RegNo
));
1240 bool isReg() const override
{
1241 // As a special case until we sort out the definition of div/divu, accept
1242 // $0/$zero here so that MCK_ZERO works correctly.
1243 return isGPRAsmReg() && RegIdx
.Index
== 0;
1246 bool isRegIdx() const { return Kind
== k_RegisterIndex
; }
1247 bool isImm() const override
{ return Kind
== k_Immediate
; }
1249 bool isConstantImm() const {
1251 return isImm() && getImm()->evaluateAsAbsolute(Res
);
1254 bool isConstantImmz() const {
1255 return isConstantImm() && getConstantImm() == 0;
1258 template <unsigned Bits
, int Offset
= 0> bool isConstantUImm() const {
1259 return isConstantImm() && isUInt
<Bits
>(getConstantImm() - Offset
);
1262 template <unsigned Bits
> bool isSImm() const {
1263 return isConstantImm() ? isInt
<Bits
>(getConstantImm()) : isImm();
1266 template <unsigned Bits
> bool isUImm() const {
1267 return isConstantImm() ? isUInt
<Bits
>(getConstantImm()) : isImm();
1270 template <unsigned Bits
> bool isAnyImm() const {
1271 return isConstantImm() ? (isInt
<Bits
>(getConstantImm()) ||
1272 isUInt
<Bits
>(getConstantImm()))
1276 template <unsigned Bits
, int Offset
= 0> bool isConstantSImm() const {
1277 return isConstantImm() && isInt
<Bits
>(getConstantImm() - Offset
);
1280 template <unsigned Bottom
, unsigned Top
> bool isConstantUImmRange() const {
1281 return isConstantImm() && getConstantImm() >= Bottom
&&
1282 getConstantImm() <= Top
;
1285 bool isToken() const override
{
1286 // Note: It's not possible to pretend that other operand kinds are tokens.
1287 // The matcher emitter checks tokens first.
1288 return Kind
== k_Token
;
1291 bool isMem() const override
{ return Kind
== k_Memory
; }
1293 bool isConstantMemOff() const {
1294 return isMem() && isa
<MCConstantExpr
>(getMemOff());
1297 // Allow relocation operators.
1298 // FIXME: This predicate and others need to look through binary expressions
1299 // and determine whether a Value is a constant or not.
1300 template <unsigned Bits
, unsigned ShiftAmount
= 0>
1301 bool isMemWithSimmOffset() const {
1304 if (!getMemBase()->isGPRAsmReg())
1306 if (isa
<MCTargetExpr
>(getMemOff()) ||
1307 (isConstantMemOff() &&
1308 isShiftedInt
<Bits
, ShiftAmount
>(getConstantMemOff())))
1311 bool IsReloc
= getMemOff()->evaluateAsRelocatable(Res
, nullptr, nullptr);
1312 return IsReloc
&& isShiftedInt
<Bits
, ShiftAmount
>(Res
.getConstant());
1315 bool isMemWithPtrSizeOffset() const {
1318 if (!getMemBase()->isGPRAsmReg())
1320 const unsigned PtrBits
= AsmParser
.getABI().ArePtrs64bit() ? 64 : 32;
1321 if (isa
<MCTargetExpr
>(getMemOff()) ||
1322 (isConstantMemOff() && isIntN(PtrBits
, getConstantMemOff())))
1325 bool IsReloc
= getMemOff()->evaluateAsRelocatable(Res
, nullptr, nullptr);
1326 return IsReloc
&& isIntN(PtrBits
, Res
.getConstant());
1329 bool isMemWithGRPMM16Base() const {
1330 return isMem() && getMemBase()->isMM16AsmReg();
1333 template <unsigned Bits
> bool isMemWithUimmOffsetSP() const {
1334 return isMem() && isConstantMemOff() && isUInt
<Bits
>(getConstantMemOff())
1335 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP
);
1338 template <unsigned Bits
> bool isMemWithUimmWordAlignedOffsetSP() const {
1339 return isMem() && isConstantMemOff() && isUInt
<Bits
>(getConstantMemOff())
1340 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1341 && (getMemBase()->getGPR32Reg() == Mips::SP
);
1344 template <unsigned Bits
> bool isMemWithSimmWordAlignedOffsetGP() const {
1345 return isMem() && isConstantMemOff() && isInt
<Bits
>(getConstantMemOff())
1346 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1347 && (getMemBase()->getGPR32Reg() == Mips::GP
);
1350 template <unsigned Bits
, unsigned ShiftLeftAmount
>
1351 bool isScaledUImm() const {
1352 return isConstantImm() &&
1353 isShiftedUInt
<Bits
, ShiftLeftAmount
>(getConstantImm());
1356 template <unsigned Bits
, unsigned ShiftLeftAmount
>
1357 bool isScaledSImm() const {
1358 if (isConstantImm() &&
1359 isShiftedInt
<Bits
, ShiftLeftAmount
>(getConstantImm()))
1361 // Operand can also be a symbol or symbol plus
1362 // offset in case of relocations.
1363 if (Kind
!= k_Immediate
)
1366 bool Success
= getImm()->evaluateAsRelocatable(Res
, nullptr, nullptr);
1367 return Success
&& isShiftedInt
<Bits
, ShiftLeftAmount
>(Res
.getConstant());
1370 bool isRegList16() const {
1374 int Size
= RegList
.List
->size();
1375 if (Size
< 2 || Size
> 5)
1378 unsigned R0
= RegList
.List
->front();
1379 unsigned R1
= RegList
.List
->back();
1380 if (!((R0
== Mips::S0
&& R1
== Mips::RA
) ||
1381 (R0
== Mips::S0_64
&& R1
== Mips::RA_64
)))
1384 int PrevReg
= *RegList
.List
->begin();
1385 for (int i
= 1; i
< Size
- 1; i
++) {
1386 int Reg
= (*(RegList
.List
))[i
];
1387 if ( Reg
!= PrevReg
+ 1)
1395 bool isInvNum() const { return Kind
== k_Immediate
; }
1397 bool isLSAImm() const {
1398 if (!isConstantImm())
1400 int64_t Val
= getConstantImm();
1401 return 1 <= Val
&& Val
<= 4;
1404 bool isRegList() const { return Kind
== k_RegList
; }
1406 StringRef
getToken() const {
1407 assert(Kind
== k_Token
&& "Invalid access!");
1408 return StringRef(Tok
.Data
, Tok
.Length
);
1411 unsigned getReg() const override
{
1412 // As a special case until we sort out the definition of div/divu, accept
1413 // $0/$zero here so that MCK_ZERO works correctly.
1414 if (Kind
== k_RegisterIndex
&& RegIdx
.Index
== 0 &&
1415 RegIdx
.Kind
& RegKind_GPR
)
1416 return getGPR32Reg(); // FIXME: GPR64 too
1418 llvm_unreachable("Invalid access!");
1422 const MCExpr
*getImm() const {
1423 assert((Kind
== k_Immediate
) && "Invalid access!");
1427 int64_t getConstantImm() const {
1428 const MCExpr
*Val
= getImm();
1430 (void)Val
->evaluateAsAbsolute(Value
);
1434 MipsOperand
*getMemBase() const {
1435 assert((Kind
== k_Memory
) && "Invalid access!");
1439 const MCExpr
*getMemOff() const {
1440 assert((Kind
== k_Memory
) && "Invalid access!");
1444 int64_t getConstantMemOff() const {
1445 return static_cast<const MCConstantExpr
*>(getMemOff())->getValue();
1448 const SmallVectorImpl
<unsigned> &getRegList() const {
1449 assert((Kind
== k_RegList
) && "Invalid access!");
1450 return *(RegList
.List
);
1453 static std::unique_ptr
<MipsOperand
> CreateToken(StringRef Str
, SMLoc S
,
1454 MipsAsmParser
&Parser
) {
1455 auto Op
= std::make_unique
<MipsOperand
>(k_Token
, Parser
);
1456 Op
->Tok
.Data
= Str
.data();
1457 Op
->Tok
.Length
= Str
.size();
1463 /// Create a numeric register (e.g. $1). The exact register remains
1464 /// unresolved until an instruction successfully matches
1465 static std::unique_ptr
<MipsOperand
>
1466 createNumericReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1467 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1468 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index
<< ", ...)\n");
1469 return CreateReg(Index
, Str
, RegKind_Numeric
, RegInfo
, S
, E
, Parser
);
1472 /// Create a register that is definitely a GPR.
1473 /// This is typically only used for named registers such as $gp.
1474 static std::unique_ptr
<MipsOperand
>
1475 createGPRReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1476 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1477 return CreateReg(Index
, Str
, RegKind_GPR
, RegInfo
, S
, E
, Parser
);
1480 /// Create a register that is definitely a FGR.
1481 /// This is typically only used for named registers such as $f0.
1482 static std::unique_ptr
<MipsOperand
>
1483 createFGRReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1484 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1485 return CreateReg(Index
, Str
, RegKind_FGR
, RegInfo
, S
, E
, Parser
);
1488 /// Create a register that is definitely a HWReg.
1489 /// This is typically only used for named registers such as $hwr_cpunum.
1490 static std::unique_ptr
<MipsOperand
>
1491 createHWRegsReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1492 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1493 return CreateReg(Index
, Str
, RegKind_HWRegs
, RegInfo
, S
, E
, Parser
);
1496 /// Create a register that is definitely an FCC.
1497 /// This is typically only used for named registers such as $fcc0.
1498 static std::unique_ptr
<MipsOperand
>
1499 createFCCReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1500 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1501 return CreateReg(Index
, Str
, RegKind_FCC
, RegInfo
, S
, E
, Parser
);
1504 /// Create a register that is definitely an ACC.
1505 /// This is typically only used for named registers such as $ac0.
1506 static std::unique_ptr
<MipsOperand
>
1507 createACCReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1508 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1509 return CreateReg(Index
, Str
, RegKind_ACC
, RegInfo
, S
, E
, Parser
);
1512 /// Create a register that is definitely an MSA128.
1513 /// This is typically only used for named registers such as $w0.
1514 static std::unique_ptr
<MipsOperand
>
1515 createMSA128Reg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1516 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1517 return CreateReg(Index
, Str
, RegKind_MSA128
, RegInfo
, S
, E
, Parser
);
1520 /// Create a register that is definitely an MSACtrl.
1521 /// This is typically only used for named registers such as $msaaccess.
1522 static std::unique_ptr
<MipsOperand
>
1523 createMSACtrlReg(unsigned Index
, StringRef Str
, const MCRegisterInfo
*RegInfo
,
1524 SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1525 return CreateReg(Index
, Str
, RegKind_MSACtrl
, RegInfo
, S
, E
, Parser
);
1528 static std::unique_ptr
<MipsOperand
>
1529 CreateImm(const MCExpr
*Val
, SMLoc S
, SMLoc E
, MipsAsmParser
&Parser
) {
1530 auto Op
= std::make_unique
<MipsOperand
>(k_Immediate
, Parser
);
1537 static std::unique_ptr
<MipsOperand
>
1538 CreateMem(std::unique_ptr
<MipsOperand
> Base
, const MCExpr
*Off
, SMLoc S
,
1539 SMLoc E
, MipsAsmParser
&Parser
) {
1540 auto Op
= std::make_unique
<MipsOperand
>(k_Memory
, Parser
);
1541 Op
->Mem
.Base
= Base
.release();
1548 static std::unique_ptr
<MipsOperand
>
1549 CreateRegList(SmallVectorImpl
<unsigned> &Regs
, SMLoc StartLoc
, SMLoc EndLoc
,
1550 MipsAsmParser
&Parser
) {
1551 assert(Regs
.size() > 0 && "Empty list not allowed");
1553 auto Op
= std::make_unique
<MipsOperand
>(k_RegList
, Parser
);
1554 Op
->RegList
.List
= new SmallVector
<unsigned, 10>(Regs
.begin(), Regs
.end());
1555 Op
->StartLoc
= StartLoc
;
1556 Op
->EndLoc
= EndLoc
;
1560 bool isGPRZeroAsmReg() const {
1561 return isRegIdx() && RegIdx
.Kind
& RegKind_GPR
&& RegIdx
.Index
== 0;
1564 bool isGPRNonZeroAsmReg() const {
1565 return isRegIdx() && RegIdx
.Kind
& RegKind_GPR
&& RegIdx
.Index
> 0 &&
1569 bool isGPRAsmReg() const {
1570 return isRegIdx() && RegIdx
.Kind
& RegKind_GPR
&& RegIdx
.Index
<= 31;
1573 bool isMM16AsmReg() const {
1574 if (!(isRegIdx() && RegIdx
.Kind
))
1576 return ((RegIdx
.Index
>= 2 && RegIdx
.Index
<= 7)
1577 || RegIdx
.Index
== 16 || RegIdx
.Index
== 17);
1580 bool isMM16AsmRegZero() const {
1581 if (!(isRegIdx() && RegIdx
.Kind
))
1583 return (RegIdx
.Index
== 0 ||
1584 (RegIdx
.Index
>= 2 && RegIdx
.Index
<= 7) ||
1585 RegIdx
.Index
== 17);
1588 bool isMM16AsmRegMoveP() const {
1589 if (!(isRegIdx() && RegIdx
.Kind
))
1591 return (RegIdx
.Index
== 0 || (RegIdx
.Index
>= 2 && RegIdx
.Index
<= 3) ||
1592 (RegIdx
.Index
>= 16 && RegIdx
.Index
<= 20));
1595 bool isMM16AsmRegMovePPairFirst() const {
1596 if (!(isRegIdx() && RegIdx
.Kind
))
1598 return RegIdx
.Index
>= 4 && RegIdx
.Index
<= 6;
1601 bool isMM16AsmRegMovePPairSecond() const {
1602 if (!(isRegIdx() && RegIdx
.Kind
))
1604 return (RegIdx
.Index
== 21 || RegIdx
.Index
== 22 ||
1605 (RegIdx
.Index
>= 5 && RegIdx
.Index
<= 7));
1608 bool isFGRAsmReg() const {
1609 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1610 return isRegIdx() && RegIdx
.Kind
& RegKind_FGR
&& RegIdx
.Index
<= 31;
1613 bool isStrictlyFGRAsmReg() const {
1614 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1615 return isRegIdx() && RegIdx
.Kind
== RegKind_FGR
&& RegIdx
.Index
<= 31;
1618 bool isHWRegsAsmReg() const {
1619 return isRegIdx() && RegIdx
.Kind
& RegKind_HWRegs
&& RegIdx
.Index
<= 31;
1622 bool isCCRAsmReg() const {
1623 return isRegIdx() && RegIdx
.Kind
& RegKind_CCR
&& RegIdx
.Index
<= 31;
1626 bool isFCCAsmReg() const {
1627 if (!(isRegIdx() && RegIdx
.Kind
& RegKind_FCC
))
1629 return RegIdx
.Index
<= 7;
1632 bool isACCAsmReg() const {
1633 return isRegIdx() && RegIdx
.Kind
& RegKind_ACC
&& RegIdx
.Index
<= 3;
1636 bool isCOP0AsmReg() const {
1637 return isRegIdx() && RegIdx
.Kind
& RegKind_COP0
&& RegIdx
.Index
<= 31;
1640 bool isCOP2AsmReg() const {
1641 return isRegIdx() && RegIdx
.Kind
& RegKind_COP2
&& RegIdx
.Index
<= 31;
1644 bool isCOP3AsmReg() const {
1645 return isRegIdx() && RegIdx
.Kind
& RegKind_COP3
&& RegIdx
.Index
<= 31;
1648 bool isMSA128AsmReg() const {
1649 return isRegIdx() && RegIdx
.Kind
& RegKind_MSA128
&& RegIdx
.Index
<= 31;
1652 bool isMSACtrlAsmReg() const {
1653 return isRegIdx() && RegIdx
.Kind
& RegKind_MSACtrl
&& RegIdx
.Index
<= 7;
1656 /// getStartLoc - Get the location of the first token of this operand.
1657 SMLoc
getStartLoc() const override
{ return StartLoc
; }
1658 /// getEndLoc - Get the location of the last token of this operand.
1659 SMLoc
getEndLoc() const override
{ return EndLoc
; }
1661 void print(raw_ostream
&OS
) const override
{
1670 Mem
.Base
->print(OS
);
1675 case k_RegisterIndex
:
1676 OS
<< "RegIdx<" << RegIdx
.Index
<< ":" << RegIdx
.Kind
<< ", "
1677 << StringRef(RegIdx
.Tok
.Data
, RegIdx
.Tok
.Length
) << ">";
1684 for (auto Reg
: (*RegList
.List
))
1691 bool isValidForTie(const MipsOperand
&Other
) const {
1692 if (Kind
!= Other
.Kind
)
1697 llvm_unreachable("Unexpected kind");
1699 case k_RegisterIndex
: {
1700 StringRef
Token(RegIdx
.Tok
.Data
, RegIdx
.Tok
.Length
);
1701 StringRef
OtherToken(Other
.RegIdx
.Tok
.Data
, Other
.RegIdx
.Tok
.Length
);
1702 return Token
== OtherToken
;
1706 }; // class MipsOperand
1708 } // end anonymous namespace
1712 extern const MCInstrDesc MipsInsts
[];
1714 } // end namespace llvm
1716 static const MCInstrDesc
&getInstDesc(unsigned Opcode
) {
1717 return MipsInsts
[Opcode
];
1720 static bool hasShortDelaySlot(MCInst
&Inst
) {
1721 switch (Inst
.getOpcode()) {
1728 case Mips::JRC16_MM
:
1730 case Mips::JALRS_MM
:
1731 case Mips::JALRS16_MM
:
1732 case Mips::BGEZALS_MM
:
1733 case Mips::BLTZALS_MM
:
1736 return !Inst
.getOperand(0).isReg();
1742 static const MCSymbol
*getSingleMCSymbol(const MCExpr
*Expr
) {
1743 if (const MCSymbolRefExpr
*SRExpr
= dyn_cast
<MCSymbolRefExpr
>(Expr
)) {
1744 return &SRExpr
->getSymbol();
1747 if (const MCBinaryExpr
*BExpr
= dyn_cast
<MCBinaryExpr
>(Expr
)) {
1748 const MCSymbol
*LHSSym
= getSingleMCSymbol(BExpr
->getLHS());
1749 const MCSymbol
*RHSSym
= getSingleMCSymbol(BExpr
->getRHS());
1760 if (const MCUnaryExpr
*UExpr
= dyn_cast
<MCUnaryExpr
>(Expr
))
1761 return getSingleMCSymbol(UExpr
->getSubExpr());
1766 static unsigned countMCSymbolRefExpr(const MCExpr
*Expr
) {
1767 if (isa
<MCSymbolRefExpr
>(Expr
))
1770 if (const MCBinaryExpr
*BExpr
= dyn_cast
<MCBinaryExpr
>(Expr
))
1771 return countMCSymbolRefExpr(BExpr
->getLHS()) +
1772 countMCSymbolRefExpr(BExpr
->getRHS());
1774 if (const MCUnaryExpr
*UExpr
= dyn_cast
<MCUnaryExpr
>(Expr
))
1775 return countMCSymbolRefExpr(UExpr
->getSubExpr());
1780 bool MipsAsmParser::processInstruction(MCInst
&Inst
, SMLoc IDLoc
,
1782 const MCSubtargetInfo
*STI
) {
1783 MipsTargetStreamer
&TOut
= getTargetStreamer();
1784 const MCInstrDesc
&MCID
= getInstDesc(Inst
.getOpcode());
1785 bool ExpandedJalSym
= false;
1789 if (MCID
.isBranch() || MCID
.isCall()) {
1790 const unsigned Opcode
= Inst
.getOpcode();
1800 assert(hasCnMips() && "instruction only valid for octeon cpus");
1807 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
1808 Offset
= Inst
.getOperand(2);
1809 if (!Offset
.isImm())
1810 break; // We'll deal with this situation later on when applying fixups.
1811 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset
.getImm()))
1812 return Error(IDLoc
, "branch target out of range");
1813 if (offsetToAlignment(Offset
.getImm(),
1814 (inMicroMipsMode() ? Align(2) : Align(4))))
1815 return Error(IDLoc
, "branch to misaligned address");
1829 case Mips::BGEZAL_MM
:
1830 case Mips::BLTZAL_MM
:
1833 case Mips::BC1EQZC_MMR6
:
1834 case Mips::BC1NEZC_MMR6
:
1835 case Mips::BC2EQZC_MMR6
:
1836 case Mips::BC2NEZC_MMR6
:
1837 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1838 Offset
= Inst
.getOperand(1);
1839 if (!Offset
.isImm())
1840 break; // We'll deal with this situation later on when applying fixups.
1841 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset
.getImm()))
1842 return Error(IDLoc
, "branch target out of range");
1843 if (offsetToAlignment(Offset
.getImm(),
1844 (inMicroMipsMode() ? Align(2) : Align(4))))
1845 return Error(IDLoc
, "branch to misaligned address");
1847 case Mips::BGEC
: case Mips::BGEC_MMR6
:
1848 case Mips::BLTC
: case Mips::BLTC_MMR6
:
1849 case Mips::BGEUC
: case Mips::BGEUC_MMR6
:
1850 case Mips::BLTUC
: case Mips::BLTUC_MMR6
:
1851 case Mips::BEQC
: case Mips::BEQC_MMR6
:
1852 case Mips::BNEC
: case Mips::BNEC_MMR6
:
1853 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
1854 Offset
= Inst
.getOperand(2);
1855 if (!Offset
.isImm())
1856 break; // We'll deal with this situation later on when applying fixups.
1857 if (!isIntN(18, Offset
.getImm()))
1858 return Error(IDLoc
, "branch target out of range");
1859 if (offsetToAlignment(Offset
.getImm(), Align(4)))
1860 return Error(IDLoc
, "branch to misaligned address");
1862 case Mips::BLEZC
: case Mips::BLEZC_MMR6
:
1863 case Mips::BGEZC
: case Mips::BGEZC_MMR6
:
1864 case Mips::BGTZC
: case Mips::BGTZC_MMR6
:
1865 case Mips::BLTZC
: case Mips::BLTZC_MMR6
:
1866 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1867 Offset
= Inst
.getOperand(1);
1868 if (!Offset
.isImm())
1869 break; // We'll deal with this situation later on when applying fixups.
1870 if (!isIntN(18, Offset
.getImm()))
1871 return Error(IDLoc
, "branch target out of range");
1872 if (offsetToAlignment(Offset
.getImm(), Align(4)))
1873 return Error(IDLoc
, "branch to misaligned address");
1875 case Mips::BEQZC
: case Mips::BEQZC_MMR6
:
1876 case Mips::BNEZC
: case Mips::BNEZC_MMR6
:
1877 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1878 Offset
= Inst
.getOperand(1);
1879 if (!Offset
.isImm())
1880 break; // We'll deal with this situation later on when applying fixups.
1881 if (!isIntN(23, Offset
.getImm()))
1882 return Error(IDLoc
, "branch target out of range");
1883 if (offsetToAlignment(Offset
.getImm(), Align(4)))
1884 return Error(IDLoc
, "branch to misaligned address");
1886 case Mips::BEQZ16_MM
:
1887 case Mips::BEQZC16_MMR6
:
1888 case Mips::BNEZ16_MM
:
1889 case Mips::BNEZC16_MMR6
:
1890 assert(MCID
.getNumOperands() == 2 && "unexpected number of operands");
1891 Offset
= Inst
.getOperand(1);
1892 if (!Offset
.isImm())
1893 break; // We'll deal with this situation later on when applying fixups.
1894 if (!isInt
<8>(Offset
.getImm()))
1895 return Error(IDLoc
, "branch target out of range");
1896 if (offsetToAlignment(Offset
.getImm(), Align(2)))
1897 return Error(IDLoc
, "branch to misaligned address");
1902 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1903 // We still accept it but it is a normal nop.
1904 if (hasMips32r6() && Inst
.getOpcode() == Mips::SSNOP
) {
1905 std::string ISA
= hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1906 Warning(IDLoc
, "ssnop is deprecated for " + ISA
+ " and is equivalent to a "
1911 const unsigned Opcode
= Inst
.getOpcode();
1923 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
1924 // The offset is handled above
1925 Opnd
= Inst
.getOperand(1);
1927 return Error(IDLoc
, "expected immediate operand kind");
1928 Imm
= Opnd
.getImm();
1929 if (Imm
< 0 || Imm
> (Opcode
== Mips::BBIT0
||
1930 Opcode
== Mips::BBIT1
? 63 : 31))
1931 return Error(IDLoc
, "immediate operand value out of range");
1933 Inst
.setOpcode(Opcode
== Mips::BBIT0
? Mips::BBIT032
1935 Inst
.getOperand(1).setImm(Imm
- 32);
1941 assert(MCID
.getNumOperands() == 3 && "unexpected number of operands");
1942 Opnd
= Inst
.getOperand(2);
1944 return Error(IDLoc
, "expected immediate operand kind");
1945 Imm
= Opnd
.getImm();
1946 if (!isInt
<10>(Imm
))
1947 return Error(IDLoc
, "immediate operand value out of range");
1952 // Warn on division by zero. We're checking here as all instructions get
1953 // processed here, not just the macros that need expansion.
1955 // The MIPS backend models most of the divison instructions and macros as
1956 // three operand instructions. The pre-R6 divide instructions however have
1957 // two operands and explicitly define HI/LO as part of the instruction,
1958 // not in the operands.
1959 unsigned FirstOp
= 1;
1960 unsigned SecondOp
= 2;
1961 switch (Inst
.getOpcode()) {
1964 case Mips::SDivIMacro
:
1965 case Mips::UDivIMacro
:
1966 case Mips::DSDivIMacro
:
1967 case Mips::DUDivIMacro
:
1968 if (Inst
.getOperand(2).getImm() == 0) {
1969 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
1970 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
1971 Warning(IDLoc
, "dividing zero by zero");
1973 Warning(IDLoc
, "division by zero");
1985 case Mips::SDivMacro
:
1986 case Mips::DSDivMacro
:
1987 case Mips::UDivMacro
:
1988 case Mips::DUDivMacro
:
1993 case Mips::DIVU_MMR6
:
1994 case Mips::DIV_MMR6
:
1995 if (Inst
.getOperand(SecondOp
).getReg() == Mips::ZERO
||
1996 Inst
.getOperand(SecondOp
).getReg() == Mips::ZERO_64
) {
1997 if (Inst
.getOperand(FirstOp
).getReg() == Mips::ZERO
||
1998 Inst
.getOperand(FirstOp
).getReg() == Mips::ZERO_64
)
1999 Warning(IDLoc
, "dividing zero by zero");
2001 Warning(IDLoc
, "division by zero");
2006 // For PIC code convert unconditional jump to unconditional branch.
2007 if ((Inst
.getOpcode() == Mips::J
|| Inst
.getOpcode() == Mips::J_MM
) &&
2010 BInst
.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM
: Mips::BEQ
);
2011 BInst
.addOperand(MCOperand::createReg(Mips::ZERO
));
2012 BInst
.addOperand(MCOperand::createReg(Mips::ZERO
));
2013 BInst
.addOperand(Inst
.getOperand(0));
2017 // This expansion is not in a function called by tryExpandInstruction()
2018 // because the pseudo-instruction doesn't have a distinct opcode.
2019 if ((Inst
.getOpcode() == Mips::JAL
|| Inst
.getOpcode() == Mips::JAL_MM
) &&
2021 warnIfNoMacro(IDLoc
);
2023 const MCExpr
*JalExpr
= Inst
.getOperand(0).getExpr();
2025 // We can do this expansion if there's only 1 symbol in the argument
2027 if (countMCSymbolRefExpr(JalExpr
) > 1)
2028 return Error(IDLoc
, "jal doesn't support multiple symbols in PIC mode");
2030 // FIXME: This is checking the expression can be handled by the later stages
2031 // of the assembler. We ought to leave it to those later stages.
2032 const MCSymbol
*JalSym
= getSingleMCSymbol(JalExpr
);
2034 // FIXME: Add support for label+offset operands (currently causes an error).
2035 // FIXME: Add support for forward-declared local symbols.
2036 // FIXME: Add expansion for when the LargeGOT option is enabled.
2037 if (JalSym
->isInSection() || JalSym
->isTemporary() ||
2039 cast
<MCSymbolELF
>(JalSym
)->getBinding() == ELF::STB_LOCAL
)) {
2041 // If it's a local symbol and the O32 ABI is being used, we expand to:
2043 // R_(MICRO)MIPS_GOT16 label
2044 // addiu $25, $25, 0
2045 // R_(MICRO)MIPS_LO16 label
2047 const MCExpr
*Got16RelocExpr
=
2048 MipsMCExpr::create(MipsMCExpr::MEK_GOT
, JalExpr
, getContext());
2049 const MCExpr
*Lo16RelocExpr
=
2050 MipsMCExpr::create(MipsMCExpr::MEK_LO
, JalExpr
, getContext());
2052 TOut
.emitRRX(Mips::LW
, Mips::T9
, GPReg
,
2053 MCOperand::createExpr(Got16RelocExpr
), IDLoc
, STI
);
2054 TOut
.emitRRX(Mips::ADDiu
, Mips::T9
, Mips::T9
,
2055 MCOperand::createExpr(Lo16RelocExpr
), IDLoc
, STI
);
2056 } else if (isABI_N32() || isABI_N64()) {
2057 // If it's a local symbol and the N32/N64 ABIs are being used,
2059 // lw/ld $25, 0($gp)
2060 // R_(MICRO)MIPS_GOT_DISP label
2062 const MCExpr
*GotDispRelocExpr
=
2063 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP
, JalExpr
, getContext());
2065 TOut
.emitRRX(ABI
.ArePtrs64bit() ? Mips::LD
: Mips::LW
, Mips::T9
,
2066 GPReg
, MCOperand::createExpr(GotDispRelocExpr
), IDLoc
,
2070 // If it's an external/weak symbol, we expand to:
2071 // lw/ld $25, 0($gp)
2072 // R_(MICRO)MIPS_CALL16 label
2074 const MCExpr
*Call16RelocExpr
=
2075 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL
, JalExpr
, getContext());
2077 TOut
.emitRRX(ABI
.ArePtrs64bit() ? Mips::LD
: Mips::LW
, Mips::T9
, GPReg
,
2078 MCOperand::createExpr(Call16RelocExpr
), IDLoc
, STI
);
2082 if (IsCpRestoreSet
&& inMicroMipsMode())
2083 JalrInst
.setOpcode(Mips::JALRS_MM
);
2085 JalrInst
.setOpcode(inMicroMipsMode() ? Mips::JALR_MM
: Mips::JALR
);
2086 JalrInst
.addOperand(MCOperand::createReg(Mips::RA
));
2087 JalrInst
.addOperand(MCOperand::createReg(Mips::T9
));
2089 if (EmitJalrReloc
) {
2090 // As an optimization hint for the linker, before the JALR we add:
2091 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2093 MCSymbol
*TmpLabel
= getContext().createTempSymbol();
2094 const MCExpr
*TmpExpr
= MCSymbolRefExpr::create(TmpLabel
, getContext());
2095 const MCExpr
*RelocJalrExpr
=
2096 MCSymbolRefExpr::create(JalSym
, MCSymbolRefExpr::VK_None
,
2097 getContext(), IDLoc
);
2099 TOut
.getStreamer().EmitRelocDirective(*TmpExpr
,
2100 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2101 RelocJalrExpr
, IDLoc
, *STI
);
2102 TOut
.getStreamer().EmitLabel(TmpLabel
);
2106 ExpandedJalSym
= true;
2109 bool IsPCRelativeLoad
= (MCID
.TSFlags
& MipsII::IsPCRelativeLoad
) != 0;
2110 if ((MCID
.mayLoad() || MCID
.mayStore()) && !IsPCRelativeLoad
) {
2111 // Check the offset of memory operand, if it is a symbol
2112 // reference or immediate we may have to expand instructions.
2113 for (unsigned i
= 0; i
< MCID
.getNumOperands(); i
++) {
2114 const MCOperandInfo
&OpInfo
= MCID
.OpInfo
[i
];
2115 if ((OpInfo
.OperandType
== MCOI::OPERAND_MEMORY
) ||
2116 (OpInfo
.OperandType
== MCOI::OPERAND_UNKNOWN
)) {
2117 MCOperand
&Op
= Inst
.getOperand(i
);
2119 int64_t MemOffset
= Op
.getImm();
2120 if (MemOffset
< -32768 || MemOffset
> 32767) {
2121 // Offset can't exceed 16bit value.
2122 expandMemInst(Inst
, IDLoc
, Out
, STI
, MCID
.mayLoad());
2123 return getParser().hasPendingError();
2125 } else if (Op
.isExpr()) {
2126 const MCExpr
*Expr
= Op
.getExpr();
2127 if (Expr
->getKind() == MCExpr::SymbolRef
) {
2128 const MCSymbolRefExpr
*SR
=
2129 static_cast<const MCSymbolRefExpr
*>(Expr
);
2130 if (SR
->getKind() == MCSymbolRefExpr::VK_None
) {
2132 expandMemInst(Inst
, IDLoc
, Out
, STI
, MCID
.mayLoad());
2133 return getParser().hasPendingError();
2135 } else if (!isEvaluated(Expr
)) {
2136 expandMemInst(Inst
, IDLoc
, Out
, STI
, MCID
.mayLoad());
2137 return getParser().hasPendingError();
2144 if (inMicroMipsMode()) {
2145 if (MCID
.mayLoad() && Inst
.getOpcode() != Mips::LWP_MM
) {
2146 // Try to create 16-bit GP relative load instruction.
2147 for (unsigned i
= 0; i
< MCID
.getNumOperands(); i
++) {
2148 const MCOperandInfo
&OpInfo
= MCID
.OpInfo
[i
];
2149 if ((OpInfo
.OperandType
== MCOI::OPERAND_MEMORY
) ||
2150 (OpInfo
.OperandType
== MCOI::OPERAND_UNKNOWN
)) {
2151 MCOperand
&Op
= Inst
.getOperand(i
);
2153 int MemOffset
= Op
.getImm();
2154 MCOperand
&DstReg
= Inst
.getOperand(0);
2155 MCOperand
&BaseReg
= Inst
.getOperand(1);
2156 if (isInt
<9>(MemOffset
) && (MemOffset
% 4 == 0) &&
2157 getContext().getRegisterInfo()->getRegClass(
2158 Mips::GPRMM16RegClassID
).contains(DstReg
.getReg()) &&
2159 (BaseReg
.getReg() == Mips::GP
||
2160 BaseReg
.getReg() == Mips::GP_64
)) {
2162 TOut
.emitRRI(Mips::LWGP_MM
, DstReg
.getReg(), Mips::GP
, MemOffset
,
2171 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2176 switch (Inst
.getOpcode()) {
2179 case Mips::ADDIUSP_MM
:
2180 Opnd
= Inst
.getOperand(0);
2182 return Error(IDLoc
, "expected immediate operand kind");
2183 Imm
= Opnd
.getImm();
2184 if (Imm
< -1032 || Imm
> 1028 || (Imm
< 8 && Imm
> -12) ||
2186 return Error(IDLoc
, "immediate operand value out of range");
2188 case Mips::SLL16_MM
:
2189 case Mips::SRL16_MM
:
2190 Opnd
= Inst
.getOperand(2);
2192 return Error(IDLoc
, "expected immediate operand kind");
2193 Imm
= Opnd
.getImm();
2194 if (Imm
< 1 || Imm
> 8)
2195 return Error(IDLoc
, "immediate operand value out of range");
2198 Opnd
= Inst
.getOperand(1);
2200 return Error(IDLoc
, "expected immediate operand kind");
2201 Imm
= Opnd
.getImm();
2202 if (Imm
< -1 || Imm
> 126)
2203 return Error(IDLoc
, "immediate operand value out of range");
2205 case Mips::ADDIUR2_MM
:
2206 Opnd
= Inst
.getOperand(2);
2208 return Error(IDLoc
, "expected immediate operand kind");
2209 Imm
= Opnd
.getImm();
2210 if (!(Imm
== 1 || Imm
== -1 ||
2211 ((Imm
% 4 == 0) && Imm
< 28 && Imm
> 0)))
2212 return Error(IDLoc
, "immediate operand value out of range");
2214 case Mips::ANDI16_MM
:
2215 Opnd
= Inst
.getOperand(2);
2217 return Error(IDLoc
, "expected immediate operand kind");
2218 Imm
= Opnd
.getImm();
2219 if (!(Imm
== 128 || (Imm
>= 1 && Imm
<= 4) || Imm
== 7 || Imm
== 8 ||
2220 Imm
== 15 || Imm
== 16 || Imm
== 31 || Imm
== 32 || Imm
== 63 ||
2221 Imm
== 64 || Imm
== 255 || Imm
== 32768 || Imm
== 65535))
2222 return Error(IDLoc
, "immediate operand value out of range");
2224 case Mips::LBU16_MM
:
2225 Opnd
= Inst
.getOperand(2);
2227 return Error(IDLoc
, "expected immediate operand kind");
2228 Imm
= Opnd
.getImm();
2229 if (Imm
< -1 || Imm
> 14)
2230 return Error(IDLoc
, "immediate operand value out of range");
2233 case Mips::SB16_MMR6
:
2234 Opnd
= Inst
.getOperand(2);
2236 return Error(IDLoc
, "expected immediate operand kind");
2237 Imm
= Opnd
.getImm();
2238 if (Imm
< 0 || Imm
> 15)
2239 return Error(IDLoc
, "immediate operand value out of range");
2241 case Mips::LHU16_MM
:
2243 case Mips::SH16_MMR6
:
2244 Opnd
= Inst
.getOperand(2);
2246 return Error(IDLoc
, "expected immediate operand kind");
2247 Imm
= Opnd
.getImm();
2248 if (Imm
< 0 || Imm
> 30 || (Imm
% 2 != 0))
2249 return Error(IDLoc
, "immediate operand value out of range");
2253 case Mips::SW16_MMR6
:
2254 Opnd
= Inst
.getOperand(2);
2256 return Error(IDLoc
, "expected immediate operand kind");
2257 Imm
= Opnd
.getImm();
2258 if (Imm
< 0 || Imm
> 60 || (Imm
% 4 != 0))
2259 return Error(IDLoc
, "immediate operand value out of range");
2261 case Mips::ADDIUPC_MM
:
2262 Opnd
= Inst
.getOperand(1);
2264 return Error(IDLoc
, "expected immediate operand kind");
2265 Imm
= Opnd
.getImm();
2266 if ((Imm
% 4 != 0) || !isInt
<25>(Imm
))
2267 return Error(IDLoc
, "immediate operand value out of range");
2271 if (Inst
.getOperand(0).getReg() == Mips::RA
)
2272 return Error(IDLoc
, "invalid operand for instruction");
2274 case Mips::MOVEP_MM
:
2275 case Mips::MOVEP_MMR6
: {
2276 unsigned R0
= Inst
.getOperand(0).getReg();
2277 unsigned R1
= Inst
.getOperand(1).getReg();
2278 bool RegPair
= ((R0
== Mips::A1
&& R1
== Mips::A2
) ||
2279 (R0
== Mips::A1
&& R1
== Mips::A3
) ||
2280 (R0
== Mips::A2
&& R1
== Mips::A3
) ||
2281 (R0
== Mips::A0
&& R1
== Mips::S5
) ||
2282 (R0
== Mips::A0
&& R1
== Mips::S6
) ||
2283 (R0
== Mips::A0
&& R1
== Mips::A1
) ||
2284 (R0
== Mips::A0
&& R1
== Mips::A2
) ||
2285 (R0
== Mips::A0
&& R1
== Mips::A3
));
2287 return Error(IDLoc
, "invalid operand for instruction");
2293 bool FillDelaySlot
=
2294 MCID
.hasDelaySlot() && AssemblerOptions
.back()->isReorder();
2296 TOut
.emitDirectiveSetNoReorder();
2298 MacroExpanderResultTy ExpandResult
=
2299 tryExpandInstruction(Inst
, IDLoc
, Out
, STI
);
2300 switch (ExpandResult
) {
2302 Out
.EmitInstruction(Inst
, *STI
);
2310 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2311 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2312 if (inMicroMipsMode()) {
2313 TOut
.setUsesMicroMips();
2314 TOut
.updateABIInfo(*this);
2317 // If this instruction has a delay slot and .set reorder is active,
2318 // emit a NOP after it.
2319 if (FillDelaySlot
) {
2320 TOut
.emitEmptyDelaySlot(hasShortDelaySlot(Inst
), IDLoc
, STI
);
2321 TOut
.emitDirectiveSetReorder();
2324 if ((Inst
.getOpcode() == Mips::JalOneReg
||
2325 Inst
.getOpcode() == Mips::JalTwoReg
|| ExpandedJalSym
) &&
2326 isPicAndNotNxxAbi()) {
2327 if (IsCpRestoreSet
) {
2328 // We need a NOP between the JALR and the LW:
2329 // If .set reorder has been used, we've already emitted a NOP.
2330 // If .set noreorder has been used, we need to emit a NOP at this point.
2331 if (!AssemblerOptions
.back()->isReorder())
2332 TOut
.emitEmptyDelaySlot(hasShortDelaySlot(Inst
), IDLoc
,
2335 // Load the $gp from the stack.
2336 TOut
.emitGPRestore(CpRestoreOffset
, IDLoc
, STI
);
2338 Warning(IDLoc
, "no .cprestore used in PIC mode");
2344 MipsAsmParser::MacroExpanderResultTy
2345 MipsAsmParser::tryExpandInstruction(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
2346 const MCSubtargetInfo
*STI
) {
2347 switch (Inst
.getOpcode()) {
2349 return MER_NotAMacro
;
2350 case Mips::LoadImm32
:
2351 return expandLoadImm(Inst
, true, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2352 case Mips::LoadImm64
:
2353 return expandLoadImm(Inst
, false, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2354 case Mips::LoadAddrImm32
:
2355 case Mips::LoadAddrImm64
:
2356 assert(Inst
.getOperand(0).isReg() && "expected register operand kind");
2357 assert((Inst
.getOperand(1).isImm() || Inst
.getOperand(1).isExpr()) &&
2358 "expected immediate operand kind");
2360 return expandLoadAddress(Inst
.getOperand(0).getReg(), Mips::NoRegister
,
2362 Inst
.getOpcode() == Mips::LoadAddrImm32
, IDLoc
,
2366 case Mips::LoadAddrReg32
:
2367 case Mips::LoadAddrReg64
:
2368 assert(Inst
.getOperand(0).isReg() && "expected register operand kind");
2369 assert(Inst
.getOperand(1).isReg() && "expected register operand kind");
2370 assert((Inst
.getOperand(2).isImm() || Inst
.getOperand(2).isExpr()) &&
2371 "expected immediate operand kind");
2373 return expandLoadAddress(Inst
.getOperand(0).getReg(),
2374 Inst
.getOperand(1).getReg(), Inst
.getOperand(2),
2375 Inst
.getOpcode() == Mips::LoadAddrReg32
, IDLoc
,
2379 case Mips::B_MM_Pseudo
:
2380 case Mips::B_MMR6_Pseudo
:
2381 return expandUncondBranchMMPseudo(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2385 return expandLoadStoreMultiple(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2387 case Mips::JalOneReg
:
2388 case Mips::JalTwoReg
:
2389 return expandJalWithRegs(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2392 case Mips::BEQLImmMacro
:
2393 case Mips::BNELImmMacro
:
2394 return expandBranchImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2411 case Mips::BLTImmMacro
:
2412 case Mips::BLEImmMacro
:
2413 case Mips::BGEImmMacro
:
2414 case Mips::BGTImmMacro
:
2415 case Mips::BLTUImmMacro
:
2416 case Mips::BLEUImmMacro
:
2417 case Mips::BGEUImmMacro
:
2418 case Mips::BGTUImmMacro
:
2419 case Mips::BLTLImmMacro
:
2420 case Mips::BLELImmMacro
:
2421 case Mips::BGELImmMacro
:
2422 case Mips::BGTLImmMacro
:
2423 case Mips::BLTULImmMacro
:
2424 case Mips::BLEULImmMacro
:
2425 case Mips::BGEULImmMacro
:
2426 case Mips::BGTULImmMacro
:
2427 return expandCondBranches(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2428 case Mips::SDivMacro
:
2429 case Mips::SDivIMacro
:
2430 case Mips::SRemMacro
:
2431 case Mips::SRemIMacro
:
2432 return expandDivRem(Inst
, IDLoc
, Out
, STI
, false, true) ? MER_Fail
2434 case Mips::DSDivMacro
:
2435 case Mips::DSDivIMacro
:
2436 case Mips::DSRemMacro
:
2437 case Mips::DSRemIMacro
:
2438 return expandDivRem(Inst
, IDLoc
, Out
, STI
, true, true) ? MER_Fail
2440 case Mips::UDivMacro
:
2441 case Mips::UDivIMacro
:
2442 case Mips::URemMacro
:
2443 case Mips::URemIMacro
:
2444 return expandDivRem(Inst
, IDLoc
, Out
, STI
, false, false) ? MER_Fail
2446 case Mips::DUDivMacro
:
2447 case Mips::DUDivIMacro
:
2448 case Mips::DURemMacro
:
2449 case Mips::DURemIMacro
:
2450 return expandDivRem(Inst
, IDLoc
, Out
, STI
, true, false) ? MER_Fail
2452 case Mips::PseudoTRUNC_W_S
:
2453 return expandTrunc(Inst
, false, false, IDLoc
, Out
, STI
) ? MER_Fail
2455 case Mips::PseudoTRUNC_W_D32
:
2456 return expandTrunc(Inst
, true, false, IDLoc
, Out
, STI
) ? MER_Fail
2458 case Mips::PseudoTRUNC_W_D
:
2459 return expandTrunc(Inst
, true, true, IDLoc
, Out
, STI
) ? MER_Fail
2462 case Mips::LoadImmSingleGPR
:
2463 return expandLoadSingleImmToGPR(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2465 case Mips::LoadImmSingleFGR
:
2466 return expandLoadSingleImmToFPR(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2468 case Mips::LoadImmDoubleGPR
:
2469 return expandLoadDoubleImmToGPR(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2471 case Mips::LoadImmDoubleFGR
:
2472 return expandLoadDoubleImmToFPR(Inst
, true, IDLoc
, Out
, STI
) ? MER_Fail
2474 case Mips::LoadImmDoubleFGR_32
:
2475 return expandLoadDoubleImmToFPR(Inst
, false, IDLoc
, Out
, STI
) ? MER_Fail
2479 return expandUlh(Inst
, true, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2481 return expandUlh(Inst
, false, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2483 return expandUsh(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2486 return expandUxw(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2488 case Mips::NORImm64
:
2489 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2492 return expandSge(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2495 case Mips::SGEImm64
:
2496 case Mips::SGEUImm64
:
2497 return expandSgeImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2500 case Mips::SGTImm64
:
2501 case Mips::SGTUImm64
:
2502 return expandSgtImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2503 case Mips::SLTImm64
:
2504 if (isInt
<16>(Inst
.getOperand(2).getImm())) {
2505 Inst
.setOpcode(Mips::SLTi64
);
2506 return MER_NotAMacro
;
2508 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2509 case Mips::SLTUImm64
:
2510 if (isInt
<16>(Inst
.getOperand(2).getImm())) {
2511 Inst
.setOpcode(Mips::SLTiu64
);
2512 return MER_NotAMacro
;
2514 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2515 case Mips::ADDi
: case Mips::ADDi_MM
:
2516 case Mips::ADDiu
: case Mips::ADDiu_MM
:
2517 case Mips::SLTi
: case Mips::SLTi_MM
:
2518 case Mips::SLTiu
: case Mips::SLTiu_MM
:
2519 if ((Inst
.getNumOperands() == 3) && Inst
.getOperand(0).isReg() &&
2520 Inst
.getOperand(1).isReg() && Inst
.getOperand(2).isImm()) {
2521 int64_t ImmValue
= Inst
.getOperand(2).getImm();
2522 if (isInt
<16>(ImmValue
))
2523 return MER_NotAMacro
;
2524 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2527 return MER_NotAMacro
;
2528 case Mips::ANDi
: case Mips::ANDi_MM
: case Mips::ANDi64
:
2529 case Mips::ORi
: case Mips::ORi_MM
: case Mips::ORi64
:
2530 case Mips::XORi
: case Mips::XORi_MM
: case Mips::XORi64
:
2531 if ((Inst
.getNumOperands() == 3) && Inst
.getOperand(0).isReg() &&
2532 Inst
.getOperand(1).isReg() && Inst
.getOperand(2).isImm()) {
2533 int64_t ImmValue
= Inst
.getOperand(2).getImm();
2534 if (isUInt
<16>(ImmValue
))
2535 return MER_NotAMacro
;
2536 return expandAliasImmediate(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
2539 return MER_NotAMacro
;
2542 return expandRotation(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2545 return expandRotationImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2548 return expandDRotation(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2551 return expandDRotationImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2552 case Mips::ABSMacro
:
2553 return expandAbs(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2554 case Mips::MULImmMacro
:
2555 case Mips::DMULImmMacro
:
2556 return expandMulImm(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2557 case Mips::MULOMacro
:
2558 case Mips::DMULOMacro
:
2559 return expandMulO(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2560 case Mips::MULOUMacro
:
2561 case Mips::DMULOUMacro
:
2562 return expandMulOU(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2563 case Mips::DMULMacro
:
2564 return expandDMULMacro(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2567 return expandLoadStoreDMacro(Inst
, IDLoc
, Out
, STI
,
2568 Inst
.getOpcode() == Mips::LDMacro
)
2572 return expandStoreDM1Macro(Inst
, IDLoc
, Out
, STI
)
2575 case Mips::SEQMacro
:
2576 return expandSeq(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2577 case Mips::SEQIMacro
:
2578 return expandSeqI(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2579 case Mips::MFTC0
: case Mips::MTTC0
:
2580 case Mips::MFTGPR
: case Mips::MTTGPR
:
2581 case Mips::MFTLO
: case Mips::MTTLO
:
2582 case Mips::MFTHI
: case Mips::MTTHI
:
2583 case Mips::MFTACX
: case Mips::MTTACX
:
2584 case Mips::MFTDSP
: case Mips::MTTDSP
:
2585 case Mips::MFTC1
: case Mips::MTTC1
:
2586 case Mips::MFTHC1
: case Mips::MTTHC1
:
2587 case Mips::CFTC1
: case Mips::CTTC1
:
2588 return expandMXTRAlias(Inst
, IDLoc
, Out
, STI
) ? MER_Fail
: MER_Success
;
2592 bool MipsAsmParser::expandJalWithRegs(MCInst
&Inst
, SMLoc IDLoc
,
2594 const MCSubtargetInfo
*STI
) {
2595 MipsTargetStreamer
&TOut
= getTargetStreamer();
2597 // Create a JALR instruction which is going to replace the pseudo-JAL.
2599 JalrInst
.setLoc(IDLoc
);
2600 const MCOperand FirstRegOp
= Inst
.getOperand(0);
2601 const unsigned Opcode
= Inst
.getOpcode();
2603 if (Opcode
== Mips::JalOneReg
) {
2604 // jal $rs => jalr $rs
2605 if (IsCpRestoreSet
&& inMicroMipsMode()) {
2606 JalrInst
.setOpcode(Mips::JALRS16_MM
);
2607 JalrInst
.addOperand(FirstRegOp
);
2608 } else if (inMicroMipsMode()) {
2609 JalrInst
.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6
: Mips::JALR16_MM
);
2610 JalrInst
.addOperand(FirstRegOp
);
2612 JalrInst
.setOpcode(Mips::JALR
);
2613 JalrInst
.addOperand(MCOperand::createReg(Mips::RA
));
2614 JalrInst
.addOperand(FirstRegOp
);
2616 } else if (Opcode
== Mips::JalTwoReg
) {
2617 // jal $rd, $rs => jalr $rd, $rs
2618 if (IsCpRestoreSet
&& inMicroMipsMode())
2619 JalrInst
.setOpcode(Mips::JALRS_MM
);
2621 JalrInst
.setOpcode(inMicroMipsMode() ? Mips::JALR_MM
: Mips::JALR
);
2622 JalrInst
.addOperand(FirstRegOp
);
2623 const MCOperand SecondRegOp
= Inst
.getOperand(1);
2624 JalrInst
.addOperand(SecondRegOp
);
2626 Out
.EmitInstruction(JalrInst
, *STI
);
2628 // If .set reorder is active and branch instruction has a delay slot,
2629 // emit a NOP after it.
2630 const MCInstrDesc
&MCID
= getInstDesc(JalrInst
.getOpcode());
2631 if (MCID
.hasDelaySlot() && AssemblerOptions
.back()->isReorder())
2632 TOut
.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst
), IDLoc
,
2638 /// Can the value be represented by a unsigned N-bit value and a shift left?
2639 template <unsigned N
> static bool isShiftedUIntAtAnyPosition(uint64_t x
) {
2640 unsigned BitNum
= findFirstSet(x
);
2642 return (x
== x
>> BitNum
<< BitNum
) && isUInt
<N
>(x
>> BitNum
);
2645 /// Load (or add) an immediate into a register.
2647 /// @param ImmValue The immediate to load.
2648 /// @param DstReg The register that will hold the immediate.
2649 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2650 /// for a simple initialization.
2651 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2652 /// @param IsAddress True if the immediate represents an address. False if it
2654 /// @param IDLoc Location of the immediate in the source file.
2655 bool MipsAsmParser::loadImmediate(int64_t ImmValue
, unsigned DstReg
,
2656 unsigned SrcReg
, bool Is32BitImm
,
2657 bool IsAddress
, SMLoc IDLoc
, MCStreamer
&Out
,
2658 const MCSubtargetInfo
*STI
) {
2659 MipsTargetStreamer
&TOut
= getTargetStreamer();
2661 if (!Is32BitImm
&& !isGP64bit()) {
2662 Error(IDLoc
, "instruction requires a 64-bit architecture");
2667 if (isInt
<32>(ImmValue
) || isUInt
<32>(ImmValue
)) {
2668 // Sign extend up to 64-bit so that the predicates match the hardware
2669 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2671 ImmValue
= SignExtend64
<32>(ImmValue
);
2673 Error(IDLoc
, "instruction requires a 32-bit immediate");
2678 unsigned ZeroReg
= IsAddress
? ABI
.GetNullPtr() : ABI
.GetZeroReg();
2679 unsigned AdduOp
= !Is32BitImm
? Mips::DADDu
: Mips::ADDu
;
2681 bool UseSrcReg
= false;
2682 if (SrcReg
!= Mips::NoRegister
)
2685 unsigned TmpReg
= DstReg
;
2687 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, SrcReg
)) {
2688 // At this point we need AT to perform the expansions and we exit if it is
2690 unsigned ATReg
= getATReg(IDLoc
);
2696 if (isInt
<16>(ImmValue
)) {
2700 // This doesn't quite follow the usual ABI expectations for N32 but matches
2701 // traditional assembler behaviour. N32 would normally use addiu for both
2702 // integers and addresses.
2703 if (IsAddress
&& !Is32BitImm
) {
2704 TOut
.emitRRI(Mips::DADDiu
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
2708 TOut
.emitRRI(Mips::ADDiu
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
2712 if (isUInt
<16>(ImmValue
)) {
2713 unsigned TmpReg
= DstReg
;
2714 if (SrcReg
== DstReg
) {
2715 TmpReg
= getATReg(IDLoc
);
2720 TOut
.emitRRI(Mips::ORi
, TmpReg
, ZeroReg
, ImmValue
, IDLoc
, STI
);
2722 TOut
.emitRRR(ABI
.GetPtrAdduOp(), DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2726 if (isInt
<32>(ImmValue
) || isUInt
<32>(ImmValue
)) {
2727 warnIfNoMacro(IDLoc
);
2729 uint16_t Bits31To16
= (ImmValue
>> 16) & 0xffff;
2730 uint16_t Bits15To0
= ImmValue
& 0xffff;
2731 if (!Is32BitImm
&& !isInt
<32>(ImmValue
)) {
2732 // Traditional behaviour seems to special case this particular value. It's
2733 // not clear why other masks are handled differently.
2734 if (ImmValue
== 0xffffffff) {
2735 TOut
.emitRI(Mips::LUi
, TmpReg
, 0xffff, IDLoc
, STI
);
2736 TOut
.emitRRI(Mips::DSRL32
, TmpReg
, TmpReg
, 0, IDLoc
, STI
);
2738 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2742 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2744 TOut
.emitRRI(Mips::ORi
, TmpReg
, ZeroReg
, Bits31To16
, IDLoc
, STI
);
2745 TOut
.emitRRI(Mips::DSLL
, TmpReg
, TmpReg
, 16, IDLoc
, STI
);
2747 TOut
.emitRRI(Mips::ORi
, TmpReg
, TmpReg
, Bits15To0
, IDLoc
, STI
);
2749 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2753 TOut
.emitRI(Mips::LUi
, TmpReg
, Bits31To16
, IDLoc
, STI
);
2755 TOut
.emitRRI(Mips::ORi
, TmpReg
, TmpReg
, Bits15To0
, IDLoc
, STI
);
2757 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2761 if (isShiftedUIntAtAnyPosition
<16>(ImmValue
)) {
2763 Error(IDLoc
, "instruction requires a 32-bit immediate");
2767 // Traditionally, these immediates are shifted as little as possible and as
2768 // such we align the most significant bit to bit 15 of our temporary.
2769 unsigned FirstSet
= findFirstSet((uint64_t)ImmValue
);
2770 unsigned LastSet
= findLastSet((uint64_t)ImmValue
);
2771 unsigned ShiftAmount
= FirstSet
- (15 - (LastSet
- FirstSet
));
2772 uint16_t Bits
= (ImmValue
>> ShiftAmount
) & 0xffff;
2773 TOut
.emitRRI(Mips::ORi
, TmpReg
, ZeroReg
, Bits
, IDLoc
, STI
);
2774 TOut
.emitRRI(Mips::DSLL
, TmpReg
, TmpReg
, ShiftAmount
, IDLoc
, STI
);
2777 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2782 warnIfNoMacro(IDLoc
);
2784 // The remaining case is packed with a sequence of dsll and ori with zeros
2785 // being omitted and any neighbouring dsll's being coalesced.
2786 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2788 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2789 if (loadImmediate(ImmValue
>> 32, TmpReg
, Mips::NoRegister
, true, false,
2793 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2794 // skip it and defer the shift to the next chunk.
2795 unsigned ShiftCarriedForwards
= 16;
2796 for (int BitNum
= 16; BitNum
>= 0; BitNum
-= 16) {
2797 uint16_t ImmChunk
= (ImmValue
>> BitNum
) & 0xffff;
2799 if (ImmChunk
!= 0) {
2800 TOut
.emitDSLL(TmpReg
, TmpReg
, ShiftCarriedForwards
, IDLoc
, STI
);
2801 TOut
.emitRRI(Mips::ORi
, TmpReg
, TmpReg
, ImmChunk
, IDLoc
, STI
);
2802 ShiftCarriedForwards
= 0;
2805 ShiftCarriedForwards
+= 16;
2807 ShiftCarriedForwards
-= 16;
2809 // Finish any remaining shifts left by trailing zeros.
2810 if (ShiftCarriedForwards
)
2811 TOut
.emitDSLL(TmpReg
, TmpReg
, ShiftCarriedForwards
, IDLoc
, STI
);
2814 TOut
.emitRRR(AdduOp
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
2819 bool MipsAsmParser::expandLoadImm(MCInst
&Inst
, bool Is32BitImm
, SMLoc IDLoc
,
2820 MCStreamer
&Out
, const MCSubtargetInfo
*STI
) {
2821 const MCOperand
&ImmOp
= Inst
.getOperand(1);
2822 assert(ImmOp
.isImm() && "expected immediate operand kind");
2823 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
2824 assert(DstRegOp
.isReg() && "expected register operand kind");
2826 if (loadImmediate(ImmOp
.getImm(), DstRegOp
.getReg(), Mips::NoRegister
,
2827 Is32BitImm
, false, IDLoc
, Out
, STI
))
2833 bool MipsAsmParser::expandLoadAddress(unsigned DstReg
, unsigned BaseReg
,
2834 const MCOperand
&Offset
,
2835 bool Is32BitAddress
, SMLoc IDLoc
,
2837 const MCSubtargetInfo
*STI
) {
2838 // la can't produce a usable address when addresses are 64-bit.
2839 if (Is32BitAddress
&& ABI
.ArePtrs64bit()) {
2840 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2841 // We currently can't do this because we depend on the equality
2842 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2843 Error(IDLoc
, "la used to load 64-bit address");
2844 // Continue as if we had 'dla' instead.
2845 Is32BitAddress
= false;
2849 // dla requires 64-bit addresses.
2850 if (!Is32BitAddress
&& !hasMips3()) {
2851 Error(IDLoc
, "instruction requires a 64-bit architecture");
2855 if (!Offset
.isImm())
2856 return loadAndAddSymbolAddress(Offset
.getExpr(), DstReg
, BaseReg
,
2857 Is32BitAddress
, IDLoc
, Out
, STI
);
2859 if (!ABI
.ArePtrs64bit()) {
2860 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2861 Is32BitAddress
= true;
2864 return loadImmediate(Offset
.getImm(), DstReg
, BaseReg
, Is32BitAddress
, true,
2868 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr
*SymExpr
,
2869 unsigned DstReg
, unsigned SrcReg
,
2870 bool Is32BitSym
, SMLoc IDLoc
,
2872 const MCSubtargetInfo
*STI
) {
2873 MipsTargetStreamer
&TOut
= getTargetStreamer();
2874 bool UseSrcReg
= SrcReg
!= Mips::NoRegister
&& SrcReg
!= Mips::ZERO
&&
2875 SrcReg
!= Mips::ZERO_64
;
2876 warnIfNoMacro(IDLoc
);
2880 if (!SymExpr
->evaluateAsRelocatable(Res
, nullptr, nullptr)) {
2881 Error(IDLoc
, "expected relocatable expression");
2884 if (Res
.getSymB() != nullptr) {
2885 Error(IDLoc
, "expected relocatable expression with only one symbol");
2889 bool IsPtr64
= ABI
.ArePtrs64bit();
2891 Res
.getSymA()->getSymbol().isInSection() ||
2892 Res
.getSymA()->getSymbol().isTemporary() ||
2893 (Res
.getSymA()->getSymbol().isELF() &&
2894 cast
<MCSymbolELF
>(Res
.getSymA()->getSymbol()).getBinding() ==
2896 bool UseXGOT
= STI
->getFeatureBits()[Mips::FeatureXGOT
] && !IsLocalSym
;
2898 // The case where the result register is $25 is somewhat special. If the
2899 // symbol in the final relocation is external and not modified with a
2900 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2901 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2902 if ((DstReg
== Mips::T9
|| DstReg
== Mips::T9_64
) && !UseSrcReg
&&
2903 Res
.getConstant() == 0 && !IsLocalSym
) {
2905 const MCExpr
*CallHiExpr
= MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16
,
2906 SymExpr
, getContext());
2907 const MCExpr
*CallLoExpr
= MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16
,
2908 SymExpr
, getContext());
2909 TOut
.emitRX(Mips::LUi
, DstReg
, MCOperand::createExpr(CallHiExpr
), IDLoc
,
2911 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, DstReg
, DstReg
, GPReg
,
2913 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, DstReg
, DstReg
,
2914 MCOperand::createExpr(CallLoExpr
), IDLoc
, STI
);
2916 const MCExpr
*CallExpr
=
2917 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL
, SymExpr
, getContext());
2918 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, DstReg
, GPReg
,
2919 MCOperand::createExpr(CallExpr
), IDLoc
, STI
);
2924 unsigned TmpReg
= DstReg
;
2926 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
,
2928 // If $rs is the same as $rd, we need to use AT.
2929 // If it is not available we exit.
2930 unsigned ATReg
= getATReg(IDLoc
);
2937 // Loading address from XGOT
2938 // External GOT: lui $tmp, %got_hi(symbol)($gp)
2939 // addu $tmp, $tmp, $gp
2940 // lw $tmp, %got_lo(symbol)($tmp)
2941 // >addiu $tmp, $tmp, offset
2942 // >addiu $rd, $tmp, $rs
2943 // The addiu's marked with a '>' may be omitted if they are redundant. If
2944 // this happens then the last instruction must use $rd as the result
2946 const MCExpr
*CallHiExpr
=
2947 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16
, SymExpr
, getContext());
2948 const MCExpr
*CallLoExpr
= MipsMCExpr::create(
2949 MipsMCExpr::MEK_GOT_LO16
, Res
.getSymA(), getContext());
2951 TOut
.emitRX(Mips::LUi
, TmpReg
, MCOperand::createExpr(CallHiExpr
), IDLoc
,
2953 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, TmpReg
, TmpReg
, GPReg
,
2955 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, TmpReg
, TmpReg
,
2956 MCOperand::createExpr(CallLoExpr
), IDLoc
, STI
);
2958 if (Res
.getConstant() != 0)
2959 TOut
.emitRRX(IsPtr64
? Mips::DADDiu
: Mips::ADDiu
, TmpReg
, TmpReg
,
2960 MCOperand::createExpr(MCConstantExpr::create(
2961 Res
.getConstant(), getContext())),
2965 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, DstReg
, TmpReg
, SrcReg
,
2970 const MipsMCExpr
*GotExpr
= nullptr;
2971 const MCExpr
*LoExpr
= nullptr;
2973 // The remaining cases are:
2974 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2975 // >daddiu $tmp, $tmp, offset
2976 // >daddu $rd, $tmp, $rs
2977 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2978 // this happens then the last instruction must use $rd as the result
2980 GotExpr
= MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP
, Res
.getSymA(),
2982 if (Res
.getConstant() != 0) {
2983 // Symbols fully resolve with just the %got_disp(symbol) but we
2984 // must still account for any offset to the symbol for
2985 // expressions like symbol+8.
2986 LoExpr
= MCConstantExpr::create(Res
.getConstant(), getContext());
2988 // FIXME: Offsets greater than 16 bits are not yet implemented.
2989 // FIXME: The correct range is a 32-bit sign-extended number.
2990 if (Res
.getConstant() < -0x8000 || Res
.getConstant() > 0x7fff) {
2991 Error(IDLoc
, "macro instruction uses large offset, which is not "
2992 "currently supported");
2997 // The remaining cases are:
2998 // External GOT: lw $tmp, %got(symbol)($gp)
2999 // >addiu $tmp, $tmp, offset
3000 // >addiu $rd, $tmp, $rs
3001 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3002 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3003 // >addiu $rd, $tmp, $rs
3004 // The addiu's marked with a '>' may be omitted if they are redundant. If
3005 // this happens then the last instruction must use $rd as the result
3009 MipsMCExpr::create(MipsMCExpr::MEK_GOT
, SymExpr
, getContext());
3010 LoExpr
= MipsMCExpr::create(MipsMCExpr::MEK_LO
, SymExpr
, getContext());
3012 // External symbols fully resolve the symbol with just the %got(symbol)
3013 // but we must still account for any offset to the symbol for
3014 // expressions like symbol+8.
3015 GotExpr
= MipsMCExpr::create(MipsMCExpr::MEK_GOT
, Res
.getSymA(),
3017 if (Res
.getConstant() != 0)
3018 LoExpr
= MCConstantExpr::create(Res
.getConstant(), getContext());
3022 TOut
.emitRRX(IsPtr64
? Mips::LD
: Mips::LW
, TmpReg
, GPReg
,
3023 MCOperand::createExpr(GotExpr
), IDLoc
, STI
);
3026 TOut
.emitRRX(IsPtr64
? Mips::DADDiu
: Mips::ADDiu
, TmpReg
, TmpReg
,
3027 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3030 TOut
.emitRRR(IsPtr64
? Mips::DADDu
: Mips::ADDu
, DstReg
, TmpReg
, SrcReg
,
3036 const MipsMCExpr
*HiExpr
=
3037 MipsMCExpr::create(MipsMCExpr::MEK_HI
, SymExpr
, getContext());
3038 const MipsMCExpr
*LoExpr
=
3039 MipsMCExpr::create(MipsMCExpr::MEK_LO
, SymExpr
, getContext());
3041 // This is the 64-bit symbol address expansion.
3042 if (ABI
.ArePtrs64bit() && isGP64bit()) {
3043 // We need AT for the 64-bit expansion in the cases where the optional
3044 // source register is the destination register and for the superscalar
3047 // If it is not available we exit if the destination is the same as the
3050 const MipsMCExpr
*HighestExpr
=
3051 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST
, SymExpr
, getContext());
3052 const MipsMCExpr
*HigherExpr
=
3053 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER
, SymExpr
, getContext());
3056 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, SrcReg
);
3058 if (canUseATReg() && UseSrcReg
&& RdRegIsRsReg
) {
3059 unsigned ATReg
= getATReg(IDLoc
);
3061 // If $rs is the same as $rd:
3062 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3063 // daddiu $at, $at, %higher(sym)
3064 // dsll $at, $at, 16
3065 // daddiu $at, $at, %hi(sym)
3066 // dsll $at, $at, 16
3067 // daddiu $at, $at, %lo(sym)
3068 // daddu $rd, $at, $rd
3069 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3071 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
,
3072 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3073 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3074 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(HiExpr
),
3076 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3077 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(LoExpr
),
3079 TOut
.emitRRR(Mips::DADDu
, DstReg
, ATReg
, SrcReg
, IDLoc
, STI
);
3082 } else if (canUseATReg() && !RdRegIsRsReg
) {
3083 unsigned ATReg
= getATReg(IDLoc
);
3085 // If the $rs is different from $rd or if $rs isn't specified and we
3086 // have $at available:
3087 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3088 // lui $at, %hi(sym)
3089 // daddiu $rd, $rd, %higher(sym)
3090 // daddiu $at, $at, %lo(sym)
3091 // dsll32 $rd, $rd, 0
3092 // daddu $rd, $rd, $at
3093 // (daddu $rd, $rd, $rs)
3095 // Which is preferred for superscalar issue.
3096 TOut
.emitRX(Mips::LUi
, DstReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3098 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3099 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3100 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3101 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(LoExpr
),
3103 TOut
.emitRRI(Mips::DSLL32
, DstReg
, DstReg
, 0, IDLoc
, STI
);
3104 TOut
.emitRRR(Mips::DADDu
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
3106 TOut
.emitRRR(Mips::DADDu
, DstReg
, DstReg
, SrcReg
, IDLoc
, STI
);
3109 } else if (!canUseATReg() && !RdRegIsRsReg
) {
3110 // Otherwise, synthesize the address in the destination register
3112 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3113 // daddiu $rd, $rd, %higher(sym)
3114 // dsll $rd, $rd, 16
3115 // daddiu $rd, $rd, %hi(sym)
3116 // dsll $rd, $rd, 16
3117 // daddiu $rd, $rd, %lo(sym)
3118 TOut
.emitRX(Mips::LUi
, DstReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3120 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3121 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3122 TOut
.emitRRI(Mips::DSLL
, DstReg
, DstReg
, 16, IDLoc
, STI
);
3123 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3124 MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3125 TOut
.emitRRI(Mips::DSLL
, DstReg
, DstReg
, 16, IDLoc
, STI
);
3126 TOut
.emitRRX(Mips::DADDiu
, DstReg
, DstReg
,
3127 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3129 TOut
.emitRRR(Mips::DADDu
, DstReg
, DstReg
, SrcReg
, IDLoc
, STI
);
3133 // We have a case where SrcReg == DstReg and we don't have $at
3134 // available. We can't expand this case, so error out appropriately.
3135 assert(SrcReg
== DstReg
&& !canUseATReg() &&
3136 "Could have expanded dla but didn't?");
3137 reportParseError(IDLoc
,
3138 "pseudo-instruction requires $at, which is not available");
3143 // And now, the 32-bit symbol address expansion:
3144 // If $rs is the same as $rd:
3145 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3146 // ori $at, $at, %lo(sym)
3147 // addu $rd, $at, $rd
3148 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3149 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3150 // ori $rd, $rd, %lo(sym)
3151 // (addu $rd, $rd, $rs)
3152 unsigned TmpReg
= DstReg
;
3154 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, SrcReg
)) {
3155 // If $rs is the same as $rd, we need to use AT.
3156 // If it is not available we exit.
3157 unsigned ATReg
= getATReg(IDLoc
);
3163 TOut
.emitRX(Mips::LUi
, TmpReg
, MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3164 TOut
.emitRRX(Mips::ADDiu
, TmpReg
, TmpReg
, MCOperand::createExpr(LoExpr
),
3168 TOut
.emitRRR(Mips::ADDu
, DstReg
, TmpReg
, SrcReg
, IDLoc
, STI
);
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg
));
3176 // Each double-precision register DO-D15 overlaps with two of the single
3177 // precision registers F0-F31. As an example, all of the following hold true:
3178 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3179 static unsigned nextReg(unsigned Reg
) {
3180 if (MipsMCRegisterClasses
[Mips::FGR32RegClassID
].contains(Reg
))
3181 return Reg
== (unsigned)Mips::F31
? (unsigned)Mips::F0
: Reg
+ 1;
3183 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3184 case Mips::ZERO
: return Mips::AT
;
3185 case Mips::AT
: return Mips::V0
;
3186 case Mips::V0
: return Mips::V1
;
3187 case Mips::V1
: return Mips::A0
;
3188 case Mips::A0
: return Mips::A1
;
3189 case Mips::A1
: return Mips::A2
;
3190 case Mips::A2
: return Mips::A3
;
3191 case Mips::A3
: return Mips::T0
;
3192 case Mips::T0
: return Mips::T1
;
3193 case Mips::T1
: return Mips::T2
;
3194 case Mips::T2
: return Mips::T3
;
3195 case Mips::T3
: return Mips::T4
;
3196 case Mips::T4
: return Mips::T5
;
3197 case Mips::T5
: return Mips::T6
;
3198 case Mips::T6
: return Mips::T7
;
3199 case Mips::T7
: return Mips::S0
;
3200 case Mips::S0
: return Mips::S1
;
3201 case Mips::S1
: return Mips::S2
;
3202 case Mips::S2
: return Mips::S3
;
3203 case Mips::S3
: return Mips::S4
;
3204 case Mips::S4
: return Mips::S5
;
3205 case Mips::S5
: return Mips::S6
;
3206 case Mips::S6
: return Mips::S7
;
3207 case Mips::S7
: return Mips::T8
;
3208 case Mips::T8
: return Mips::T9
;
3209 case Mips::T9
: return Mips::K0
;
3210 case Mips::K0
: return Mips::K1
;
3211 case Mips::K1
: return Mips::GP
;
3212 case Mips::GP
: return Mips::SP
;
3213 case Mips::SP
: return Mips::FP
;
3214 case Mips::FP
: return Mips::RA
;
3215 case Mips::RA
: return Mips::ZERO
;
3216 case Mips::D0
: return Mips::F1
;
3217 case Mips::D1
: return Mips::F3
;
3218 case Mips::D2
: return Mips::F5
;
3219 case Mips::D3
: return Mips::F7
;
3220 case Mips::D4
: return Mips::F9
;
3221 case Mips::D5
: return Mips::F11
;
3222 case Mips::D6
: return Mips::F13
;
3223 case Mips::D7
: return Mips::F15
;
3224 case Mips::D8
: return Mips::F17
;
3225 case Mips::D9
: return Mips::F19
;
3226 case Mips::D10
: return Mips::F21
;
3227 case Mips::D11
: return Mips::F23
;
3228 case Mips::D12
: return Mips::F25
;
3229 case Mips::D13
: return Mips::F27
;
3230 case Mips::D14
: return Mips::F29
;
3231 case Mips::D15
: return Mips::F31
;
3235 // FIXME: This method is too general. In principle we should compute the number
3236 // of instructions required to synthesize the immediate inline compared to
3237 // synthesizing the address inline and relying on non .text sections.
3238 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3239 // likely to yield a much larger benefit as we have to synthesize a 64bit
3240 // address to load a 64 bit value.
3241 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer
&TOut
, SMLoc IDLoc
,
3243 unsigned ATReg
= getATReg(IDLoc
);
3248 const MCExpr
*GotSym
=
3249 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3250 const MipsMCExpr
*GotExpr
=
3251 MipsMCExpr::create(MipsMCExpr::MEK_GOT
, GotSym
, getContext());
3253 if(isABI_O32() || isABI_N32()) {
3254 TOut
.emitRRX(Mips::LW
, ATReg
, GPReg
, MCOperand::createExpr(GotExpr
),
3256 } else { //isABI_N64()
3257 TOut
.emitRRX(Mips::LD
, ATReg
, GPReg
, MCOperand::createExpr(GotExpr
),
3260 } else { //!IsPicEnabled
3261 const MCExpr
*HiSym
=
3262 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3263 const MipsMCExpr
*HiExpr
=
3264 MipsMCExpr::create(MipsMCExpr::MEK_HI
, HiSym
, getContext());
3266 // FIXME: This is technically correct but gives a different result to gas,
3267 // but gas is incomplete there (it has a fixme noting it doesn't work with
3268 // 64-bit addresses).
3269 // FIXME: With -msym32 option, the address expansion for N64 should probably
3270 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3271 // symbol's value is considered sign extended.
3272 if(isABI_O32() || isABI_N32()) {
3273 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HiExpr
), IDLoc
, STI
);
3274 } else { //isABI_N64()
3275 const MCExpr
*HighestSym
=
3276 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3277 const MipsMCExpr
*HighestExpr
=
3278 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST
, HighestSym
, getContext());
3279 const MCExpr
*HigherSym
=
3280 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3281 const MipsMCExpr
*HigherExpr
=
3282 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER
, HigherSym
, getContext());
3284 TOut
.emitRX(Mips::LUi
, ATReg
, MCOperand::createExpr(HighestExpr
), IDLoc
,
3286 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
,
3287 MCOperand::createExpr(HigherExpr
), IDLoc
, STI
);
3288 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3289 TOut
.emitRRX(Mips::DADDiu
, ATReg
, ATReg
, MCOperand::createExpr(HiExpr
),
3291 TOut
.emitRRI(Mips::DSLL
, ATReg
, ATReg
, 16, IDLoc
, STI
);
3297 static uint64_t convertIntToDoubleImm(uint64_t ImmOp64
) {
3298 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3299 // exponent field), convert it to double (e.g. 1 to 1.0)
3300 if ((Hi_32(ImmOp64
) & 0x7ff00000) == 0) {
3301 APFloat
RealVal(APFloat::IEEEdouble(), ImmOp64
);
3302 ImmOp64
= RealVal
.bitcastToAPInt().getZExtValue();
3307 static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64
) {
3308 // Conversion of a double in an uint64_t to a float in a uint32_t,
3309 // retaining the bit pattern of a float.
3310 double DoubleImm
= BitsToDouble(ImmOp64
);
3311 float TmpFloat
= static_cast<float>(DoubleImm
);
3312 return FloatToBits(TmpFloat
);
3315 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
,
3317 const MCSubtargetInfo
*STI
) {
3318 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3319 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3320 "Invalid instruction operand.");
3322 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3323 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3325 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3327 uint32_t ImmOp32
= covertDoubleImmToSingleImm(ImmOp64
);
3329 return loadImmediate(ImmOp32
, FirstReg
, Mips::NoRegister
, true, true, IDLoc
,
3333 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst
&Inst
, SMLoc IDLoc
,
3335 const MCSubtargetInfo
*STI
) {
3336 MipsTargetStreamer
&TOut
= getTargetStreamer();
3337 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3338 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3339 "Invalid instruction operand.");
3341 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3342 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3344 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3346 uint32_t ImmOp32
= covertDoubleImmToSingleImm(ImmOp64
);
3348 unsigned TmpReg
= getATReg(IDLoc
);
3352 if (Lo_32(ImmOp64
) == 0) {
3353 if (loadImmediate(ImmOp32
, TmpReg
, Mips::NoRegister
, true, true, IDLoc
, Out
,
3356 TOut
.emitRR(Mips::MTC1
, FirstReg
, TmpReg
, IDLoc
, STI
);
3360 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3361 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3362 // where appropriate.
3363 MCSection
*ReadOnlySection
=
3364 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3366 MCSymbol
*Sym
= getContext().createTempSymbol();
3367 const MCExpr
*LoSym
=
3368 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3369 const MipsMCExpr
*LoExpr
=
3370 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3372 getStreamer().SwitchSection(ReadOnlySection
);
3373 getStreamer().EmitLabel(Sym
, IDLoc
);
3374 getStreamer().EmitIntValue(ImmOp32
, 4);
3375 getStreamer().SwitchSection(CS
);
3377 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3379 TOut
.emitRRX(Mips::LWC1
, FirstReg
, TmpReg
, MCOperand::createExpr(LoExpr
),
3384 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
,
3386 const MCSubtargetInfo
*STI
) {
3387 MipsTargetStreamer
&TOut
= getTargetStreamer();
3388 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3389 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3390 "Invalid instruction operand.");
3392 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3393 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3395 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3397 uint32_t LoImmOp64
= Lo_32(ImmOp64
);
3398 uint32_t HiImmOp64
= Hi_32(ImmOp64
);
3400 unsigned TmpReg
= getATReg(IDLoc
);
3404 if (LoImmOp64
== 0) {
3405 if (isABI_N32() || isABI_N64()) {
3406 if (loadImmediate(HiImmOp64
, FirstReg
, Mips::NoRegister
, false, true,
3410 if (loadImmediate(HiImmOp64
, FirstReg
, Mips::NoRegister
, true, true,
3414 if (loadImmediate(0, nextReg(FirstReg
), Mips::NoRegister
, true, true,
3421 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3422 MCSection
*ReadOnlySection
=
3423 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3425 MCSymbol
*Sym
= getContext().createTempSymbol();
3426 const MCExpr
*LoSym
=
3427 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3428 const MipsMCExpr
*LoExpr
=
3429 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3431 getStreamer().SwitchSection(ReadOnlySection
);
3432 getStreamer().EmitLabel(Sym
, IDLoc
);
3433 getStreamer().EmitIntValue(HiImmOp64
, 4);
3434 getStreamer().EmitIntValue(LoImmOp64
, 4);
3435 getStreamer().SwitchSection(CS
);
3437 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3441 TOut
.emitRRX(Mips::DADDiu
, TmpReg
, TmpReg
, MCOperand::createExpr(LoExpr
),
3444 TOut
.emitRRX(Mips::ADDiu
, TmpReg
, TmpReg
, MCOperand::createExpr(LoExpr
),
3447 if (isABI_N32() || isABI_N64())
3448 TOut
.emitRRI(Mips::LD
, FirstReg
, TmpReg
, 0, IDLoc
, STI
);
3450 TOut
.emitRRI(Mips::LW
, FirstReg
, TmpReg
, 0, IDLoc
, STI
);
3451 TOut
.emitRRI(Mips::LW
, nextReg(FirstReg
), TmpReg
, 4, IDLoc
, STI
);
3456 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst
&Inst
, bool Is64FPU
,
3457 SMLoc IDLoc
, MCStreamer
&Out
,
3458 const MCSubtargetInfo
*STI
) {
3459 MipsTargetStreamer
&TOut
= getTargetStreamer();
3460 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3461 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3462 "Invalid instruction operand.");
3464 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3465 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3467 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3469 uint32_t LoImmOp64
= Lo_32(ImmOp64
);
3470 uint32_t HiImmOp64
= Hi_32(ImmOp64
);
3472 unsigned TmpReg
= getATReg(IDLoc
);
3476 if ((LoImmOp64
== 0) &&
3477 !((HiImmOp64
& 0xffff0000) && (HiImmOp64
& 0x0000ffff))) {
3478 // FIXME: In the case where the constant is zero, we can load the
3479 // register directly from the zero register.
3480 if (loadImmediate(HiImmOp64
, TmpReg
, Mips::NoRegister
, true, true, IDLoc
,
3483 if (isABI_N32() || isABI_N64())
3484 TOut
.emitRR(Mips::DMTC1
, FirstReg
, TmpReg
, IDLoc
, STI
);
3485 else if (hasMips32r2()) {
3486 TOut
.emitRR(Mips::MTC1
, FirstReg
, Mips::ZERO
, IDLoc
, STI
);
3487 TOut
.emitRRR(Mips::MTHC1_D32
, FirstReg
, FirstReg
, TmpReg
, IDLoc
, STI
);
3489 TOut
.emitRR(Mips::MTC1
, nextReg(FirstReg
), TmpReg
, IDLoc
, STI
);
3490 TOut
.emitRR(Mips::MTC1
, FirstReg
, Mips::ZERO
, IDLoc
, STI
);
3495 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3496 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3497 // where appropriate.
3498 MCSection
*ReadOnlySection
=
3499 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3501 MCSymbol
*Sym
= getContext().createTempSymbol();
3502 const MCExpr
*LoSym
=
3503 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3504 const MipsMCExpr
*LoExpr
=
3505 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3507 getStreamer().SwitchSection(ReadOnlySection
);
3508 getStreamer().EmitLabel(Sym
, IDLoc
);
3509 getStreamer().EmitIntValue(HiImmOp64
, 4);
3510 getStreamer().EmitIntValue(LoImmOp64
, 4);
3511 getStreamer().SwitchSection(CS
);
3513 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3516 TOut
.emitRRX(Is64FPU
? Mips::LDC164
: Mips::LDC1
, FirstReg
, TmpReg
,
3517 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3522 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst
&Inst
, SMLoc IDLoc
,
3524 const MCSubtargetInfo
*STI
) {
3525 MipsTargetStreamer
&TOut
= getTargetStreamer();
3527 assert(getInstDesc(Inst
.getOpcode()).getNumOperands() == 1 &&
3528 "unexpected number of operands");
3530 MCOperand Offset
= Inst
.getOperand(0);
3531 if (Offset
.isExpr()) {
3533 Inst
.setOpcode(Mips::BEQ_MM
);
3534 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3535 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3536 Inst
.addOperand(MCOperand::createExpr(Offset
.getExpr()));
3538 assert(Offset
.isImm() && "expected immediate operand kind");
3539 if (isInt
<11>(Offset
.getImm())) {
3540 // If offset fits into 11 bits then this instruction becomes microMIPS
3541 // 16-bit unconditional branch instruction.
3542 if (inMicroMipsMode())
3543 Inst
.setOpcode(hasMips32r6() ? Mips::BC16_MMR6
: Mips::B16_MM
);
3545 if (!isInt
<17>(Offset
.getImm()))
3546 return Error(IDLoc
, "branch target out of range");
3547 if (offsetToAlignment(Offset
.getImm(), Align(2)))
3548 return Error(IDLoc
, "branch to misaligned address");
3550 Inst
.setOpcode(Mips::BEQ_MM
);
3551 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3552 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3553 Inst
.addOperand(MCOperand::createImm(Offset
.getImm()));
3556 Out
.EmitInstruction(Inst
, *STI
);
3558 // If .set reorder is active and branch instruction has a delay slot,
3559 // emit a NOP after it.
3560 const MCInstrDesc
&MCID
= getInstDesc(Inst
.getOpcode());
3561 if (MCID
.hasDelaySlot() && AssemblerOptions
.back()->isReorder())
3562 TOut
.emitEmptyDelaySlot(true, IDLoc
, STI
);
3567 bool MipsAsmParser::expandBranchImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
3568 const MCSubtargetInfo
*STI
) {
3569 MipsTargetStreamer
&TOut
= getTargetStreamer();
3570 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
3571 assert(DstRegOp
.isReg() && "expected register operand kind");
3573 const MCOperand
&ImmOp
= Inst
.getOperand(1);
3574 assert(ImmOp
.isImm() && "expected immediate operand kind");
3576 const MCOperand
&MemOffsetOp
= Inst
.getOperand(2);
3577 assert((MemOffsetOp
.isImm() || MemOffsetOp
.isExpr()) &&
3578 "expected immediate or expression operand");
3580 bool IsLikely
= false;
3582 unsigned OpCode
= 0;
3583 switch(Inst
.getOpcode()) {
3590 case Mips::BEQLImmMacro
:
3591 OpCode
= Mips::BEQL
;
3594 case Mips::BNELImmMacro
:
3595 OpCode
= Mips::BNEL
;
3599 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3603 int64_t ImmValue
= ImmOp
.getImm();
3604 if (ImmValue
== 0) {
3606 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), Mips::ZERO
,
3607 MCOperand::createExpr(MemOffsetOp
.getExpr()), IDLoc
, STI
);
3608 TOut
.emitRRI(Mips::SLL
, Mips::ZERO
, Mips::ZERO
, 0, IDLoc
, STI
);
3610 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), Mips::ZERO
, MemOffsetOp
, IDLoc
,
3613 warnIfNoMacro(IDLoc
);
3615 unsigned ATReg
= getATReg(IDLoc
);
3619 if (loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, !isGP64bit(), true,
3624 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), ATReg
,
3625 MCOperand::createExpr(MemOffsetOp
.getExpr()), IDLoc
, STI
);
3626 TOut
.emitRRI(Mips::SLL
, Mips::ZERO
, Mips::ZERO
, 0, IDLoc
, STI
);
3628 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), ATReg
, MemOffsetOp
, IDLoc
, STI
);
3633 void MipsAsmParser::expandMemInst(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
3634 const MCSubtargetInfo
*STI
, bool IsLoad
) {
3635 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
3636 assert(DstRegOp
.isReg() && "expected register operand kind");
3637 const MCOperand
&BaseRegOp
= Inst
.getOperand(1);
3638 assert(BaseRegOp
.isReg() && "expected register operand kind");
3640 MipsTargetStreamer
&TOut
= getTargetStreamer();
3641 unsigned DstReg
= DstRegOp
.getReg();
3642 unsigned BaseReg
= BaseRegOp
.getReg();
3643 unsigned TmpReg
= DstReg
;
3645 const MCInstrDesc
&Desc
= getInstDesc(Inst
.getOpcode());
3646 int16_t DstRegClass
= Desc
.OpInfo
[0].RegClass
;
3647 unsigned DstRegClassID
=
3648 getContext().getRegisterInfo()->getRegClass(DstRegClass
).getID();
3649 bool IsGPR
= (DstRegClassID
== Mips::GPR32RegClassID
) ||
3650 (DstRegClassID
== Mips::GPR64RegClassID
);
3652 if (!IsLoad
|| !IsGPR
|| (BaseReg
== DstReg
)) {
3653 // At this point we need AT to perform the expansions
3654 // and we exit if it is not available.
3655 TmpReg
= getATReg(IDLoc
);
3660 if (Inst
.getNumOperands() > 3) {
3661 const MCOperand
&BaseRegOp
= Inst
.getOperand(2);
3662 assert(BaseRegOp
.isReg() && "expected register operand kind");
3663 const MCOperand
&ExprOp
= Inst
.getOperand(3);
3664 assert(ExprOp
.isExpr() && "expected expression oprand kind");
3666 unsigned BaseReg
= BaseRegOp
.getReg();
3667 const MCExpr
*ExprOffset
= ExprOp
.getExpr();
3669 MCOperand LoOperand
= MCOperand::createExpr(
3670 MipsMCExpr::create(MipsMCExpr::MEK_LO
, ExprOffset
, getContext()));
3671 MCOperand HiOperand
= MCOperand::createExpr(
3672 MipsMCExpr::create(MipsMCExpr::MEK_HI
, ExprOffset
, getContext()));
3673 TOut
.emitSCWithSymOffset(Inst
.getOpcode(), DstReg
, BaseReg
, HiOperand
,
3674 LoOperand
, TmpReg
, IDLoc
, STI
);
3678 const MCOperand
&OffsetOp
= Inst
.getOperand(2);
3680 if (OffsetOp
.isImm()) {
3681 int64_t LoOffset
= OffsetOp
.getImm() & 0xffff;
3682 int64_t HiOffset
= OffsetOp
.getImm() & ~0xffff;
3684 // If msb of LoOffset is 1(negative number) we must increment
3685 // HiOffset to account for the sign-extension of the low part.
3686 if (LoOffset
& 0x8000)
3687 HiOffset
+= 0x10000;
3689 bool IsLargeOffset
= HiOffset
!= 0;
3691 if (IsLargeOffset
) {
3692 bool Is32BitImm
= (HiOffset
>> 32) == 0;
3693 if (loadImmediate(HiOffset
, TmpReg
, Mips::NoRegister
, Is32BitImm
, true,
3698 if (BaseReg
!= Mips::ZERO
&& BaseReg
!= Mips::ZERO_64
)
3699 TOut
.emitRRR(isGP64bit() ? Mips::DADDu
: Mips::ADDu
, TmpReg
, TmpReg
,
3700 BaseReg
, IDLoc
, STI
);
3701 TOut
.emitRRI(Inst
.getOpcode(), DstReg
, TmpReg
, LoOffset
, IDLoc
, STI
);
3705 if (OffsetOp
.isExpr()) {
3708 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3709 // do not exceed 16-bit.
3710 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3711 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3714 if (!OffsetOp
.getExpr()->evaluateAsRelocatable(Res
, nullptr, nullptr)) {
3715 Error(IDLoc
, "expected relocatable expression");
3718 if (Res
.getSymB() != nullptr) {
3719 Error(IDLoc
, "expected relocatable expression with only one symbol");
3723 loadAndAddSymbolAddress(Res
.getSymA(), TmpReg
, BaseReg
,
3724 !ABI
.ArePtrs64bit(), IDLoc
, Out
, STI
);
3725 TOut
.emitRRI(Inst
.getOpcode(), DstReg
, TmpReg
, Res
.getConstant(), IDLoc
,
3728 // FIXME: Implement 64-bit case.
3729 // 1) lw $8, sym => lui $8, %hi(sym)
3730 // lw $8, %lo(sym)($8)
3731 // 2) sw $8, sym => lui $at, %hi(sym)
3732 // sw $8, %lo(sym)($at)
3733 const MCExpr
*ExprOffset
= OffsetOp
.getExpr();
3734 MCOperand LoOperand
= MCOperand::createExpr(
3735 MipsMCExpr::create(MipsMCExpr::MEK_LO
, ExprOffset
, getContext()));
3736 MCOperand HiOperand
= MCOperand::createExpr(
3737 MipsMCExpr::create(MipsMCExpr::MEK_HI
, ExprOffset
, getContext()));
3739 // Generate the base address in TmpReg.
3740 TOut
.emitRX(Mips::LUi
, TmpReg
, HiOperand
, IDLoc
, STI
);
3741 if (BaseReg
!= Mips::ZERO
)
3742 TOut
.emitRRR(Mips::ADDu
, TmpReg
, TmpReg
, BaseReg
, IDLoc
, STI
);
3743 // Emit the load or store with the adjusted base and offset.
3744 TOut
.emitRRX(Inst
.getOpcode(), DstReg
, TmpReg
, LoOperand
, IDLoc
, STI
);
3749 llvm_unreachable("unexpected operand type");
3752 bool MipsAsmParser::expandLoadStoreMultiple(MCInst
&Inst
, SMLoc IDLoc
,
3754 const MCSubtargetInfo
*STI
) {
3755 unsigned OpNum
= Inst
.getNumOperands();
3756 unsigned Opcode
= Inst
.getOpcode();
3757 unsigned NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM32_MM
: Mips::LWM32_MM
;
3759 assert(Inst
.getOperand(OpNum
- 1).isImm() &&
3760 Inst
.getOperand(OpNum
- 2).isReg() &&
3761 Inst
.getOperand(OpNum
- 3).isReg() && "Invalid instruction operand.");
3763 if (OpNum
< 8 && Inst
.getOperand(OpNum
- 1).getImm() <= 60 &&
3764 Inst
.getOperand(OpNum
- 1).getImm() >= 0 &&
3765 (Inst
.getOperand(OpNum
- 2).getReg() == Mips::SP
||
3766 Inst
.getOperand(OpNum
- 2).getReg() == Mips::SP_64
) &&
3767 (Inst
.getOperand(OpNum
- 3).getReg() == Mips::RA
||
3768 Inst
.getOperand(OpNum
- 3).getReg() == Mips::RA_64
)) {
3769 // It can be implemented as SWM16 or LWM16 instruction.
3770 if (inMicroMipsMode() && hasMips32r6())
3771 NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM16_MMR6
: Mips::LWM16_MMR6
;
3773 NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM16_MM
: Mips::LWM16_MM
;
3776 Inst
.setOpcode(NewOpcode
);
3777 Out
.EmitInstruction(Inst
, *STI
);
3781 bool MipsAsmParser::expandCondBranches(MCInst
&Inst
, SMLoc IDLoc
,
3783 const MCSubtargetInfo
*STI
) {
3784 MipsTargetStreamer
&TOut
= getTargetStreamer();
3785 bool EmittedNoMacroWarning
= false;
3786 unsigned PseudoOpcode
= Inst
.getOpcode();
3787 unsigned SrcReg
= Inst
.getOperand(0).getReg();
3788 const MCOperand
&TrgOp
= Inst
.getOperand(1);
3789 const MCExpr
*OffsetExpr
= Inst
.getOperand(2).getExpr();
3791 unsigned ZeroSrcOpcode
, ZeroTrgOpcode
;
3792 bool ReverseOrderSLT
, IsUnsigned
, IsLikely
, AcceptsEquality
;
3796 TrgReg
= TrgOp
.getReg();
3797 else if (TrgOp
.isImm()) {
3798 warnIfNoMacro(IDLoc
);
3799 EmittedNoMacroWarning
= true;
3801 TrgReg
= getATReg(IDLoc
);
3805 switch(PseudoOpcode
) {
3807 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3808 case Mips::BLTImmMacro
:
3809 PseudoOpcode
= Mips::BLT
;
3811 case Mips::BLEImmMacro
:
3812 PseudoOpcode
= Mips::BLE
;
3814 case Mips::BGEImmMacro
:
3815 PseudoOpcode
= Mips::BGE
;
3817 case Mips::BGTImmMacro
:
3818 PseudoOpcode
= Mips::BGT
;
3820 case Mips::BLTUImmMacro
:
3821 PseudoOpcode
= Mips::BLTU
;
3823 case Mips::BLEUImmMacro
:
3824 PseudoOpcode
= Mips::BLEU
;
3826 case Mips::BGEUImmMacro
:
3827 PseudoOpcode
= Mips::BGEU
;
3829 case Mips::BGTUImmMacro
:
3830 PseudoOpcode
= Mips::BGTU
;
3832 case Mips::BLTLImmMacro
:
3833 PseudoOpcode
= Mips::BLTL
;
3835 case Mips::BLELImmMacro
:
3836 PseudoOpcode
= Mips::BLEL
;
3838 case Mips::BGELImmMacro
:
3839 PseudoOpcode
= Mips::BGEL
;
3841 case Mips::BGTLImmMacro
:
3842 PseudoOpcode
= Mips::BGTL
;
3844 case Mips::BLTULImmMacro
:
3845 PseudoOpcode
= Mips::BLTUL
;
3847 case Mips::BLEULImmMacro
:
3848 PseudoOpcode
= Mips::BLEUL
;
3850 case Mips::BGEULImmMacro
:
3851 PseudoOpcode
= Mips::BGEUL
;
3853 case Mips::BGTULImmMacro
:
3854 PseudoOpcode
= Mips::BGTUL
;
3858 if (loadImmediate(TrgOp
.getImm(), TrgReg
, Mips::NoRegister
, !isGP64bit(),
3859 false, IDLoc
, Out
, STI
))
3863 switch (PseudoOpcode
) {
3868 AcceptsEquality
= false;
3869 ReverseOrderSLT
= false;
3871 ((PseudoOpcode
== Mips::BLTU
) || (PseudoOpcode
== Mips::BLTUL
));
3872 IsLikely
= ((PseudoOpcode
== Mips::BLTL
) || (PseudoOpcode
== Mips::BLTUL
));
3873 ZeroSrcOpcode
= Mips::BGTZ
;
3874 ZeroTrgOpcode
= Mips::BLTZ
;
3880 AcceptsEquality
= true;
3881 ReverseOrderSLT
= true;
3883 ((PseudoOpcode
== Mips::BLEU
) || (PseudoOpcode
== Mips::BLEUL
));
3884 IsLikely
= ((PseudoOpcode
== Mips::BLEL
) || (PseudoOpcode
== Mips::BLEUL
));
3885 ZeroSrcOpcode
= Mips::BGEZ
;
3886 ZeroTrgOpcode
= Mips::BLEZ
;
3892 AcceptsEquality
= true;
3893 ReverseOrderSLT
= false;
3895 ((PseudoOpcode
== Mips::BGEU
) || (PseudoOpcode
== Mips::BGEUL
));
3896 IsLikely
= ((PseudoOpcode
== Mips::BGEL
) || (PseudoOpcode
== Mips::BGEUL
));
3897 ZeroSrcOpcode
= Mips::BLEZ
;
3898 ZeroTrgOpcode
= Mips::BGEZ
;
3904 AcceptsEquality
= false;
3905 ReverseOrderSLT
= true;
3907 ((PseudoOpcode
== Mips::BGTU
) || (PseudoOpcode
== Mips::BGTUL
));
3908 IsLikely
= ((PseudoOpcode
== Mips::BGTL
) || (PseudoOpcode
== Mips::BGTUL
));
3909 ZeroSrcOpcode
= Mips::BLTZ
;
3910 ZeroTrgOpcode
= Mips::BGTZ
;
3913 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3916 bool IsTrgRegZero
= (TrgReg
== Mips::ZERO
);
3917 bool IsSrcRegZero
= (SrcReg
== Mips::ZERO
);
3918 if (IsSrcRegZero
&& IsTrgRegZero
) {
3919 // FIXME: All of these Opcode-specific if's are needed for compatibility
3920 // with GAS' behaviour. However, they may not generate the most efficient
3921 // code in some circumstances.
3922 if (PseudoOpcode
== Mips::BLT
) {
3923 TOut
.emitRX(Mips::BLTZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3927 if (PseudoOpcode
== Mips::BLE
) {
3928 TOut
.emitRX(Mips::BLEZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3930 Warning(IDLoc
, "branch is always taken");
3933 if (PseudoOpcode
== Mips::BGE
) {
3934 TOut
.emitRX(Mips::BGEZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3936 Warning(IDLoc
, "branch is always taken");
3939 if (PseudoOpcode
== Mips::BGT
) {
3940 TOut
.emitRX(Mips::BGTZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3944 if (PseudoOpcode
== Mips::BGTU
) {
3945 TOut
.emitRRX(Mips::BNE
, Mips::ZERO
, Mips::ZERO
,
3946 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
3949 if (AcceptsEquality
) {
3950 // If both registers are $0 and the pseudo-branch accepts equality, it
3951 // will always be taken, so we emit an unconditional branch.
3952 TOut
.emitRRX(Mips::BEQ
, Mips::ZERO
, Mips::ZERO
,
3953 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
3954 Warning(IDLoc
, "branch is always taken");
3957 // If both registers are $0 and the pseudo-branch does not accept
3958 // equality, it will never be taken, so we don't have to emit anything.
3961 if (IsSrcRegZero
|| IsTrgRegZero
) {
3962 if ((IsSrcRegZero
&& PseudoOpcode
== Mips::BGTU
) ||
3963 (IsTrgRegZero
&& PseudoOpcode
== Mips::BLTU
)) {
3964 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3965 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3966 // the pseudo-branch will never be taken, so we don't emit anything.
3967 // This only applies to unsigned pseudo-branches.
3970 if ((IsSrcRegZero
&& PseudoOpcode
== Mips::BLEU
) ||
3971 (IsTrgRegZero
&& PseudoOpcode
== Mips::BGEU
)) {
3972 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3973 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3974 // the pseudo-branch will always be taken, so we emit an unconditional
3976 // This only applies to unsigned pseudo-branches.
3977 TOut
.emitRRX(Mips::BEQ
, Mips::ZERO
, Mips::ZERO
,
3978 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
3979 Warning(IDLoc
, "branch is always taken");
3983 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3984 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3985 // the pseudo-branch will be taken only when the non-zero register is
3986 // different from 0, so we emit a BNEZ.
3988 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3989 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3990 // the pseudo-branch will be taken only when the non-zero register is
3991 // equal to 0, so we emit a BEQZ.
3993 // Because only BLEU and BGEU branch on equality, we can use the
3994 // AcceptsEquality variable to decide when to emit the BEQZ.
3995 TOut
.emitRRX(AcceptsEquality
? Mips::BEQ
: Mips::BNE
,
3996 IsSrcRegZero
? TrgReg
: SrcReg
, Mips::ZERO
,
3997 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4000 // If we have a signed pseudo-branch and one of the registers is $0,
4001 // we can use an appropriate compare-to-zero branch. We select which one
4002 // to use in the switch statement above.
4003 TOut
.emitRX(IsSrcRegZero
? ZeroSrcOpcode
: ZeroTrgOpcode
,
4004 IsSrcRegZero
? TrgReg
: SrcReg
,
4005 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4009 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4010 // expansions. If it is not available, we return.
4011 unsigned ATRegNum
= getATReg(IDLoc
);
4015 if (!EmittedNoMacroWarning
)
4016 warnIfNoMacro(IDLoc
);
4018 // SLT fits well with 2 of our 4 pseudo-branches:
4019 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4020 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4021 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4022 // This is accomplished by using a BNEZ with the result of the SLT.
4024 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4025 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4026 // Because only BGE and BLE branch on equality, we can use the
4027 // AcceptsEquality variable to decide when to emit the BEQZ.
4028 // Note that the order of the SLT arguments doesn't change between
4031 // The same applies to the unsigned variants, except that SLTu is used
4033 TOut
.emitRRR(IsUnsigned
? Mips::SLTu
: Mips::SLT
, ATRegNum
,
4034 ReverseOrderSLT
? TrgReg
: SrcReg
,
4035 ReverseOrderSLT
? SrcReg
: TrgReg
, IDLoc
, STI
);
4037 TOut
.emitRRX(IsLikely
? (AcceptsEquality
? Mips::BEQL
: Mips::BNEL
)
4038 : (AcceptsEquality
? Mips::BEQ
: Mips::BNE
),
4039 ATRegNum
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
), IDLoc
,
4044 // Expand a integer division macro.
4046 // Notably we don't have to emit a warning when encountering $rt as the $zero
4047 // register, or 0 as an immediate. processInstruction() has already done that.
4049 // The destination register can only be $zero when expanding (S)DivIMacro or
4052 bool MipsAsmParser::expandDivRem(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4053 const MCSubtargetInfo
*STI
, const bool IsMips64
,
4054 const bool Signed
) {
4055 MipsTargetStreamer
&TOut
= getTargetStreamer();
4057 warnIfNoMacro(IDLoc
);
4059 const MCOperand
&RdRegOp
= Inst
.getOperand(0);
4060 assert(RdRegOp
.isReg() && "expected register operand kind");
4061 unsigned RdReg
= RdRegOp
.getReg();
4063 const MCOperand
&RsRegOp
= Inst
.getOperand(1);
4064 assert(RsRegOp
.isReg() && "expected register operand kind");
4065 unsigned RsReg
= RsRegOp
.getReg();
4070 const MCOperand
&RtOp
= Inst
.getOperand(2);
4071 assert((RtOp
.isReg() || RtOp
.isImm()) &&
4072 "expected register or immediate operand kind");
4074 RtReg
= RtOp
.getReg();
4076 ImmValue
= RtOp
.getImm();
4083 DivOp
= Signed
? Mips::DSDIV
: Mips::DUDIV
;
4084 ZeroReg
= Mips::ZERO_64
;
4087 DivOp
= Signed
? Mips::SDIV
: Mips::UDIV
;
4088 ZeroReg
= Mips::ZERO
;
4092 bool UseTraps
= useTraps();
4094 unsigned Opcode
= Inst
.getOpcode();
4095 bool isDiv
= Opcode
== Mips::SDivMacro
|| Opcode
== Mips::SDivIMacro
||
4096 Opcode
== Mips::UDivMacro
|| Opcode
== Mips::UDivIMacro
||
4097 Opcode
== Mips::DSDivMacro
|| Opcode
== Mips::DSDivIMacro
||
4098 Opcode
== Mips::DUDivMacro
|| Opcode
== Mips::DUDivIMacro
;
4100 bool isRem
= Opcode
== Mips::SRemMacro
|| Opcode
== Mips::SRemIMacro
||
4101 Opcode
== Mips::URemMacro
|| Opcode
== Mips::URemIMacro
||
4102 Opcode
== Mips::DSRemMacro
|| Opcode
== Mips::DSRemIMacro
||
4103 Opcode
== Mips::DURemMacro
|| Opcode
== Mips::DURemIMacro
;
4106 unsigned ATReg
= getATReg(IDLoc
);
4110 if (ImmValue
== 0) {
4112 TOut
.emitRRI(Mips::TEQ
, ZeroReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4114 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4118 if (isRem
&& (ImmValue
== 1 || (Signed
&& (ImmValue
== -1)))) {
4119 TOut
.emitRRR(Mips::OR
, RdReg
, ZeroReg
, ZeroReg
, IDLoc
, STI
);
4121 } else if (isDiv
&& ImmValue
== 1) {
4122 TOut
.emitRRR(Mips::OR
, RdReg
, RsReg
, Mips::ZERO
, IDLoc
, STI
);
4124 } else if (isDiv
&& Signed
&& ImmValue
== -1) {
4125 TOut
.emitRRR(SubOp
, RdReg
, ZeroReg
, RsReg
, IDLoc
, STI
);
4128 if (loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4129 false, Inst
.getLoc(), Out
, STI
))
4131 TOut
.emitRR(DivOp
, RsReg
, ATReg
, IDLoc
, STI
);
4132 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4138 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4139 // break, insert the trap/break and exit. This gives a different result to
4140 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4141 // are handled equivalently. As the observed behaviour is the same, we're ok.
4142 if (RtReg
== Mips::ZERO
|| RtReg
== Mips::ZERO_64
) {
4144 TOut
.emitRRI(Mips::TEQ
, ZeroReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4147 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4151 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4152 // not expand to macro sequence.
4153 if (isRem
&& (RdReg
== Mips::ZERO
|| RdReg
== Mips::ZERO_64
)) {
4154 TOut
.emitRR(DivOp
, RsReg
, RtReg
, IDLoc
, STI
);
4158 // Temporary label for first branch traget
4159 MCContext
&Context
= TOut
.getStreamer().getContext();
4164 TOut
.emitRRI(Mips::TEQ
, RtReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4166 // Branch to the li instruction.
4167 BrTarget
= Context
.createTempSymbol();
4168 LabelOp
= MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
4169 TOut
.emitRRX(Mips::BNE
, RtReg
, ZeroReg
, LabelOp
, IDLoc
, STI
);
4172 TOut
.emitRR(DivOp
, RsReg
, RtReg
, IDLoc
, STI
);
4175 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4179 TOut
.getStreamer().EmitLabel(BrTarget
);
4181 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4185 unsigned ATReg
= getATReg(IDLoc
);
4190 TOut
.getStreamer().EmitLabel(BrTarget
);
4192 TOut
.emitRRI(Mips::ADDiu
, ATReg
, ZeroReg
, -1, IDLoc
, STI
);
4194 // Temporary label for the second branch target.
4195 MCSymbol
*BrTargetEnd
= Context
.createTempSymbol();
4196 MCOperand LabelOpEnd
=
4197 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd
, Context
));
4199 // Branch to the mflo instruction.
4200 TOut
.emitRRX(Mips::BNE
, RtReg
, ATReg
, LabelOpEnd
, IDLoc
, STI
);
4203 TOut
.emitRRI(Mips::ADDiu
, ATReg
, ZeroReg
, 1, IDLoc
, STI
);
4204 TOut
.emitDSLL(ATReg
, ATReg
, 63, IDLoc
, STI
);
4206 TOut
.emitRI(Mips::LUi
, ATReg
, (uint16_t)0x8000, IDLoc
, STI
);
4210 TOut
.emitRRI(Mips::TEQ
, RsReg
, ATReg
, 0x6, IDLoc
, STI
);
4212 // Branch to the mflo instruction.
4213 TOut
.emitRRX(Mips::BNE
, RsReg
, ATReg
, LabelOpEnd
, IDLoc
, STI
);
4214 TOut
.emitNop(IDLoc
, STI
);
4215 TOut
.emitII(Mips::BREAK
, 0x6, 0, IDLoc
, STI
);
4218 TOut
.getStreamer().EmitLabel(BrTargetEnd
);
4219 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4223 bool MipsAsmParser::expandTrunc(MCInst
&Inst
, bool IsDouble
, bool Is64FPU
,
4224 SMLoc IDLoc
, MCStreamer
&Out
,
4225 const MCSubtargetInfo
*STI
) {
4226 MipsTargetStreamer
&TOut
= getTargetStreamer();
4228 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4229 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isReg() &&
4230 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
4232 unsigned FirstReg
= Inst
.getOperand(0).getReg();
4233 unsigned SecondReg
= Inst
.getOperand(1).getReg();
4234 unsigned ThirdReg
= Inst
.getOperand(2).getReg();
4236 if (hasMips1() && !hasMips2()) {
4237 unsigned ATReg
= getATReg(IDLoc
);
4240 TOut
.emitRR(Mips::CFC1
, ThirdReg
, Mips::RA
, IDLoc
, STI
);
4241 TOut
.emitRR(Mips::CFC1
, ThirdReg
, Mips::RA
, IDLoc
, STI
);
4242 TOut
.emitNop(IDLoc
, STI
);
4243 TOut
.emitRRI(Mips::ORi
, ATReg
, ThirdReg
, 0x3, IDLoc
, STI
);
4244 TOut
.emitRRI(Mips::XORi
, ATReg
, ATReg
, 0x2, IDLoc
, STI
);
4245 TOut
.emitRR(Mips::CTC1
, Mips::RA
, ATReg
, IDLoc
, STI
);
4246 TOut
.emitNop(IDLoc
, STI
);
4247 TOut
.emitRR(IsDouble
? (Is64FPU
? Mips::CVT_W_D64
: Mips::CVT_W_D32
)
4249 FirstReg
, SecondReg
, IDLoc
, STI
);
4250 TOut
.emitRR(Mips::CTC1
, Mips::RA
, ThirdReg
, IDLoc
, STI
);
4251 TOut
.emitNop(IDLoc
, STI
);
4255 TOut
.emitRR(IsDouble
? (Is64FPU
? Mips::TRUNC_W_D64
: Mips::TRUNC_W_D32
)
4257 FirstReg
, SecondReg
, IDLoc
, STI
);
4262 bool MipsAsmParser::expandUlh(MCInst
&Inst
, bool Signed
, SMLoc IDLoc
,
4263 MCStreamer
&Out
, const MCSubtargetInfo
*STI
) {
4264 if (hasMips32r6() || hasMips64r6()) {
4265 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4268 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4269 assert(DstRegOp
.isReg() && "expected register operand kind");
4270 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4271 assert(SrcRegOp
.isReg() && "expected register operand kind");
4272 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4273 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4275 MipsTargetStreamer
&TOut
= getTargetStreamer();
4276 unsigned DstReg
= DstRegOp
.getReg();
4277 unsigned SrcReg
= SrcRegOp
.getReg();
4278 int64_t OffsetValue
= OffsetImmOp
.getImm();
4280 // NOTE: We always need AT for ULHU, as it is always used as the source
4281 // register for one of the LBu's.
4282 warnIfNoMacro(IDLoc
);
4283 unsigned ATReg
= getATReg(IDLoc
);
4287 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 1) && isInt
<16>(OffsetValue
));
4288 if (IsLargeOffset
) {
4289 if (loadImmediate(OffsetValue
, ATReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4294 int64_t FirstOffset
= IsLargeOffset
? 0 : OffsetValue
;
4295 int64_t SecondOffset
= IsLargeOffset
? 1 : (OffsetValue
+ 1);
4297 std::swap(FirstOffset
, SecondOffset
);
4299 unsigned FirstLbuDstReg
= IsLargeOffset
? DstReg
: ATReg
;
4300 unsigned SecondLbuDstReg
= IsLargeOffset
? ATReg
: DstReg
;
4302 unsigned LbuSrcReg
= IsLargeOffset
? ATReg
: SrcReg
;
4303 unsigned SllReg
= IsLargeOffset
? DstReg
: ATReg
;
4305 TOut
.emitRRI(Signed
? Mips::LB
: Mips::LBu
, FirstLbuDstReg
, LbuSrcReg
,
4306 FirstOffset
, IDLoc
, STI
);
4307 TOut
.emitRRI(Mips::LBu
, SecondLbuDstReg
, LbuSrcReg
, SecondOffset
, IDLoc
, STI
);
4308 TOut
.emitRRI(Mips::SLL
, SllReg
, SllReg
, 8, IDLoc
, STI
);
4309 TOut
.emitRRR(Mips::OR
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
4314 bool MipsAsmParser::expandUsh(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4315 const MCSubtargetInfo
*STI
) {
4316 if (hasMips32r6() || hasMips64r6()) {
4317 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4320 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4321 assert(DstRegOp
.isReg() && "expected register operand kind");
4322 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4323 assert(SrcRegOp
.isReg() && "expected register operand kind");
4324 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4325 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4327 MipsTargetStreamer
&TOut
= getTargetStreamer();
4328 unsigned DstReg
= DstRegOp
.getReg();
4329 unsigned SrcReg
= SrcRegOp
.getReg();
4330 int64_t OffsetValue
= OffsetImmOp
.getImm();
4332 warnIfNoMacro(IDLoc
);
4333 unsigned ATReg
= getATReg(IDLoc
);
4337 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 1) && isInt
<16>(OffsetValue
));
4338 if (IsLargeOffset
) {
4339 if (loadImmediate(OffsetValue
, ATReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4344 int64_t FirstOffset
= IsLargeOffset
? 1 : (OffsetValue
+ 1);
4345 int64_t SecondOffset
= IsLargeOffset
? 0 : OffsetValue
;
4347 std::swap(FirstOffset
, SecondOffset
);
4349 if (IsLargeOffset
) {
4350 TOut
.emitRRI(Mips::SB
, DstReg
, ATReg
, FirstOffset
, IDLoc
, STI
);
4351 TOut
.emitRRI(Mips::SRL
, DstReg
, DstReg
, 8, IDLoc
, STI
);
4352 TOut
.emitRRI(Mips::SB
, DstReg
, ATReg
, SecondOffset
, IDLoc
, STI
);
4353 TOut
.emitRRI(Mips::LBu
, ATReg
, ATReg
, 0, IDLoc
, STI
);
4354 TOut
.emitRRI(Mips::SLL
, DstReg
, DstReg
, 8, IDLoc
, STI
);
4355 TOut
.emitRRR(Mips::OR
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
4357 TOut
.emitRRI(Mips::SB
, DstReg
, SrcReg
, FirstOffset
, IDLoc
, STI
);
4358 TOut
.emitRRI(Mips::SRL
, ATReg
, DstReg
, 8, IDLoc
, STI
);
4359 TOut
.emitRRI(Mips::SB
, ATReg
, SrcReg
, SecondOffset
, IDLoc
, STI
);
4365 bool MipsAsmParser::expandUxw(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4366 const MCSubtargetInfo
*STI
) {
4367 if (hasMips32r6() || hasMips64r6()) {
4368 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4371 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4372 assert(DstRegOp
.isReg() && "expected register operand kind");
4373 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4374 assert(SrcRegOp
.isReg() && "expected register operand kind");
4375 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4376 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4378 MipsTargetStreamer
&TOut
= getTargetStreamer();
4379 unsigned DstReg
= DstRegOp
.getReg();
4380 unsigned SrcReg
= SrcRegOp
.getReg();
4381 int64_t OffsetValue
= OffsetImmOp
.getImm();
4383 // Compute left/right load/store offsets.
4384 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 3) && isInt
<16>(OffsetValue
));
4385 int64_t LxlOffset
= IsLargeOffset
? 0 : OffsetValue
;
4386 int64_t LxrOffset
= IsLargeOffset
? 3 : (OffsetValue
+ 3);
4388 std::swap(LxlOffset
, LxrOffset
);
4390 bool IsLoadInst
= (Inst
.getOpcode() == Mips::Ulw
);
4391 bool DoMove
= IsLoadInst
&& (SrcReg
== DstReg
) && !IsLargeOffset
;
4392 unsigned TmpReg
= SrcReg
;
4393 if (IsLargeOffset
|| DoMove
) {
4394 warnIfNoMacro(IDLoc
);
4395 TmpReg
= getATReg(IDLoc
);
4400 if (IsLargeOffset
) {
4401 if (loadImmediate(OffsetValue
, TmpReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4407 std::swap(DstReg
, TmpReg
);
4409 unsigned XWL
= IsLoadInst
? Mips::LWL
: Mips::SWL
;
4410 unsigned XWR
= IsLoadInst
? Mips::LWR
: Mips::SWR
;
4411 TOut
.emitRRI(XWL
, DstReg
, TmpReg
, LxlOffset
, IDLoc
, STI
);
4412 TOut
.emitRRI(XWR
, DstReg
, TmpReg
, LxrOffset
, IDLoc
, STI
);
4415 TOut
.emitRRR(Mips::OR
, TmpReg
, DstReg
, Mips::ZERO
, IDLoc
, STI
);
4420 bool MipsAsmParser::expandSge(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4421 const MCSubtargetInfo
*STI
) {
4422 MipsTargetStreamer
&TOut
= getTargetStreamer();
4424 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4425 assert(Inst
.getOperand(0).isReg() &&
4426 Inst
.getOperand(1).isReg() &&
4427 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
4429 unsigned DstReg
= Inst
.getOperand(0).getReg();
4430 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4431 unsigned OpReg
= Inst
.getOperand(2).getReg();
4434 warnIfNoMacro(IDLoc
);
4436 switch (Inst
.getOpcode()) {
4441 OpCode
= Mips::SLTu
;
4444 llvm_unreachable("unexpected 'sge' opcode");
4447 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4448 TOut
.emitRRR(OpCode
, DstReg
, SrcReg
, OpReg
, IDLoc
, STI
);
4449 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4454 bool MipsAsmParser::expandSgeImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4455 const MCSubtargetInfo
*STI
) {
4456 MipsTargetStreamer
&TOut
= getTargetStreamer();
4458 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4459 assert(Inst
.getOperand(0).isReg() &&
4460 Inst
.getOperand(1).isReg() &&
4461 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4463 unsigned DstReg
= Inst
.getOperand(0).getReg();
4464 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4465 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4466 unsigned OpRegCode
, OpImmCode
;
4468 warnIfNoMacro(IDLoc
);
4470 switch (Inst
.getOpcode()) {
4472 case Mips::SGEImm64
:
4473 OpRegCode
= Mips::SLT
;
4474 OpImmCode
= Mips::SLTi
;
4477 case Mips::SGEUImm64
:
4478 OpRegCode
= Mips::SLTu
;
4479 OpImmCode
= Mips::SLTiu
;
4482 llvm_unreachable("unexpected 'sge' opcode with immediate");
4485 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4486 if (isInt
<16>(ImmValue
)) {
4487 // Use immediate version of STL.
4488 TOut
.emitRRI(OpImmCode
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
4489 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4491 unsigned ImmReg
= DstReg
;
4492 if (DstReg
== SrcReg
) {
4493 unsigned ATReg
= getATReg(Inst
.getLoc());
4499 if (loadImmediate(ImmValue
, ImmReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4500 false, IDLoc
, Out
, STI
))
4503 TOut
.emitRRR(OpRegCode
, DstReg
, SrcReg
, ImmReg
, IDLoc
, STI
);
4504 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4510 bool MipsAsmParser::expandSgtImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4511 const MCSubtargetInfo
*STI
) {
4512 MipsTargetStreamer
&TOut
= getTargetStreamer();
4514 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4515 assert(Inst
.getOperand(0).isReg() &&
4516 Inst
.getOperand(1).isReg() &&
4517 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4519 unsigned DstReg
= Inst
.getOperand(0).getReg();
4520 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4521 unsigned ImmReg
= DstReg
;
4522 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4525 warnIfNoMacro(IDLoc
);
4527 switch (Inst
.getOpcode()) {
4529 case Mips::SGTImm64
:
4533 case Mips::SGTUImm64
:
4534 OpCode
= Mips::SLTu
;
4537 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4540 if (DstReg
== SrcReg
) {
4541 unsigned ATReg
= getATReg(Inst
.getLoc());
4547 if (loadImmediate(ImmValue
, ImmReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4548 false, IDLoc
, Out
, STI
))
4551 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4552 TOut
.emitRRR(OpCode
, DstReg
, ImmReg
, SrcReg
, IDLoc
, STI
);
4557 bool MipsAsmParser::expandAliasImmediate(MCInst
&Inst
, SMLoc IDLoc
,
4559 const MCSubtargetInfo
*STI
) {
4560 MipsTargetStreamer
&TOut
= getTargetStreamer();
4562 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4563 assert(Inst
.getOperand(0).isReg() &&
4564 Inst
.getOperand(1).isReg() &&
4565 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4567 unsigned ATReg
= Mips::NoRegister
;
4568 unsigned FinalDstReg
= Mips::NoRegister
;
4569 unsigned DstReg
= Inst
.getOperand(0).getReg();
4570 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4571 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4573 bool Is32Bit
= isInt
<32>(ImmValue
) || (!isGP64bit() && isUInt
<32>(ImmValue
));
4575 unsigned FinalOpcode
= Inst
.getOpcode();
4577 if (DstReg
== SrcReg
) {
4578 ATReg
= getATReg(Inst
.getLoc());
4581 FinalDstReg
= DstReg
;
4585 if (!loadImmediate(ImmValue
, DstReg
, Mips::NoRegister
, Is32Bit
, false,
4586 Inst
.getLoc(), Out
, STI
)) {
4587 switch (FinalOpcode
) {
4589 llvm_unreachable("unimplemented expansion");
4591 FinalOpcode
= Mips::ADD
;
4594 FinalOpcode
= Mips::ADDu
;
4597 FinalOpcode
= Mips::AND
;
4600 FinalOpcode
= Mips::NOR
;
4603 FinalOpcode
= Mips::OR
;
4606 FinalOpcode
= Mips::SLT
;
4609 FinalOpcode
= Mips::SLTu
;
4612 FinalOpcode
= Mips::XOR
;
4615 FinalOpcode
= Mips::ADD_MM
;
4617 case Mips::ADDiu_MM
:
4618 FinalOpcode
= Mips::ADDu_MM
;
4621 FinalOpcode
= Mips::AND_MM
;
4624 FinalOpcode
= Mips::OR_MM
;
4627 FinalOpcode
= Mips::SLT_MM
;
4629 case Mips::SLTiu_MM
:
4630 FinalOpcode
= Mips::SLTu_MM
;
4633 FinalOpcode
= Mips::XOR_MM
;
4636 FinalOpcode
= Mips::AND64
;
4638 case Mips::NORImm64
:
4639 FinalOpcode
= Mips::NOR64
;
4642 FinalOpcode
= Mips::OR64
;
4644 case Mips::SLTImm64
:
4645 FinalOpcode
= Mips::SLT64
;
4647 case Mips::SLTUImm64
:
4648 FinalOpcode
= Mips::SLTu64
;
4651 FinalOpcode
= Mips::XOR64
;
4655 if (FinalDstReg
== Mips::NoRegister
)
4656 TOut
.emitRRR(FinalOpcode
, DstReg
, DstReg
, SrcReg
, IDLoc
, STI
);
4658 TOut
.emitRRR(FinalOpcode
, FinalDstReg
, FinalDstReg
, DstReg
, IDLoc
, STI
);
4664 bool MipsAsmParser::expandRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4665 const MCSubtargetInfo
*STI
) {
4666 MipsTargetStreamer
&TOut
= getTargetStreamer();
4667 unsigned ATReg
= Mips::NoRegister
;
4668 unsigned DReg
= Inst
.getOperand(0).getReg();
4669 unsigned SReg
= Inst
.getOperand(1).getReg();
4670 unsigned TReg
= Inst
.getOperand(2).getReg();
4671 unsigned TmpReg
= DReg
;
4673 unsigned FirstShift
= Mips::NOP
;
4674 unsigned SecondShift
= Mips::NOP
;
4676 if (hasMips32r2()) {
4678 TmpReg
= getATReg(Inst
.getLoc());
4683 if (Inst
.getOpcode() == Mips::ROL
) {
4684 TOut
.emitRRR(Mips::SUBu
, TmpReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4685 TOut
.emitRRR(Mips::ROTRV
, DReg
, SReg
, TmpReg
, Inst
.getLoc(), STI
);
4689 if (Inst
.getOpcode() == Mips::ROR
) {
4690 TOut
.emitRRR(Mips::ROTRV
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4698 switch (Inst
.getOpcode()) {
4700 llvm_unreachable("unexpected instruction opcode");
4702 FirstShift
= Mips::SRLV
;
4703 SecondShift
= Mips::SLLV
;
4706 FirstShift
= Mips::SLLV
;
4707 SecondShift
= Mips::SRLV
;
4711 ATReg
= getATReg(Inst
.getLoc());
4715 TOut
.emitRRR(Mips::SUBu
, ATReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4716 TOut
.emitRRR(FirstShift
, ATReg
, SReg
, ATReg
, Inst
.getLoc(), STI
);
4717 TOut
.emitRRR(SecondShift
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4718 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4726 bool MipsAsmParser::expandRotationImm(MCInst
&Inst
, SMLoc IDLoc
,
4728 const MCSubtargetInfo
*STI
) {
4729 MipsTargetStreamer
&TOut
= getTargetStreamer();
4730 unsigned ATReg
= Mips::NoRegister
;
4731 unsigned DReg
= Inst
.getOperand(0).getReg();
4732 unsigned SReg
= Inst
.getOperand(1).getReg();
4733 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4735 unsigned FirstShift
= Mips::NOP
;
4736 unsigned SecondShift
= Mips::NOP
;
4738 if (hasMips32r2()) {
4739 if (Inst
.getOpcode() == Mips::ROLImm
) {
4740 uint64_t MaxShift
= 32;
4741 uint64_t ShiftValue
= ImmValue
;
4743 ShiftValue
= MaxShift
- ImmValue
;
4744 TOut
.emitRRI(Mips::ROTR
, DReg
, SReg
, ShiftValue
, Inst
.getLoc(), STI
);
4748 if (Inst
.getOpcode() == Mips::RORImm
) {
4749 TOut
.emitRRI(Mips::ROTR
, DReg
, SReg
, ImmValue
, Inst
.getLoc(), STI
);
4757 if (ImmValue
== 0) {
4758 TOut
.emitRRI(Mips::SRL
, DReg
, SReg
, 0, Inst
.getLoc(), STI
);
4762 switch (Inst
.getOpcode()) {
4764 llvm_unreachable("unexpected instruction opcode");
4766 FirstShift
= Mips::SLL
;
4767 SecondShift
= Mips::SRL
;
4770 FirstShift
= Mips::SRL
;
4771 SecondShift
= Mips::SLL
;
4775 ATReg
= getATReg(Inst
.getLoc());
4779 TOut
.emitRRI(FirstShift
, ATReg
, SReg
, ImmValue
, Inst
.getLoc(), STI
);
4780 TOut
.emitRRI(SecondShift
, DReg
, SReg
, 32 - ImmValue
, Inst
.getLoc(), STI
);
4781 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4789 bool MipsAsmParser::expandDRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4790 const MCSubtargetInfo
*STI
) {
4791 MipsTargetStreamer
&TOut
= getTargetStreamer();
4792 unsigned ATReg
= Mips::NoRegister
;
4793 unsigned DReg
= Inst
.getOperand(0).getReg();
4794 unsigned SReg
= Inst
.getOperand(1).getReg();
4795 unsigned TReg
= Inst
.getOperand(2).getReg();
4796 unsigned TmpReg
= DReg
;
4798 unsigned FirstShift
= Mips::NOP
;
4799 unsigned SecondShift
= Mips::NOP
;
4801 if (hasMips64r2()) {
4802 if (TmpReg
== SReg
) {
4803 TmpReg
= getATReg(Inst
.getLoc());
4808 if (Inst
.getOpcode() == Mips::DROL
) {
4809 TOut
.emitRRR(Mips::DSUBu
, TmpReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4810 TOut
.emitRRR(Mips::DROTRV
, DReg
, SReg
, TmpReg
, Inst
.getLoc(), STI
);
4814 if (Inst
.getOpcode() == Mips::DROR
) {
4815 TOut
.emitRRR(Mips::DROTRV
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4823 switch (Inst
.getOpcode()) {
4825 llvm_unreachable("unexpected instruction opcode");
4827 FirstShift
= Mips::DSRLV
;
4828 SecondShift
= Mips::DSLLV
;
4831 FirstShift
= Mips::DSLLV
;
4832 SecondShift
= Mips::DSRLV
;
4836 ATReg
= getATReg(Inst
.getLoc());
4840 TOut
.emitRRR(Mips::DSUBu
, ATReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4841 TOut
.emitRRR(FirstShift
, ATReg
, SReg
, ATReg
, Inst
.getLoc(), STI
);
4842 TOut
.emitRRR(SecondShift
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4843 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4851 bool MipsAsmParser::expandDRotationImm(MCInst
&Inst
, SMLoc IDLoc
,
4853 const MCSubtargetInfo
*STI
) {
4854 MipsTargetStreamer
&TOut
= getTargetStreamer();
4855 unsigned ATReg
= Mips::NoRegister
;
4856 unsigned DReg
= Inst
.getOperand(0).getReg();
4857 unsigned SReg
= Inst
.getOperand(1).getReg();
4858 int64_t ImmValue
= Inst
.getOperand(2).getImm() % 64;
4860 unsigned FirstShift
= Mips::NOP
;
4861 unsigned SecondShift
= Mips::NOP
;
4865 if (hasMips64r2()) {
4866 unsigned FinalOpcode
= Mips::NOP
;
4868 FinalOpcode
= Mips::DROTR
;
4869 else if (ImmValue
% 32 == 0)
4870 FinalOpcode
= Mips::DROTR32
;
4871 else if ((ImmValue
>= 1) && (ImmValue
<= 32)) {
4872 if (Inst
.getOpcode() == Mips::DROLImm
)
4873 FinalOpcode
= Mips::DROTR32
;
4875 FinalOpcode
= Mips::DROTR
;
4876 } else if (ImmValue
>= 33) {
4877 if (Inst
.getOpcode() == Mips::DROLImm
)
4878 FinalOpcode
= Mips::DROTR
;
4880 FinalOpcode
= Mips::DROTR32
;
4883 uint64_t ShiftValue
= ImmValue
% 32;
4884 if (Inst
.getOpcode() == Mips::DROLImm
)
4885 ShiftValue
= (32 - ImmValue
% 32) % 32;
4887 TOut
.emitRRI(FinalOpcode
, DReg
, SReg
, ShiftValue
, Inst
.getLoc(), STI
);
4893 if (ImmValue
== 0) {
4894 TOut
.emitRRI(Mips::DSRL
, DReg
, SReg
, 0, Inst
.getLoc(), STI
);
4898 switch (Inst
.getOpcode()) {
4900 llvm_unreachable("unexpected instruction opcode");
4902 if ((ImmValue
>= 1) && (ImmValue
<= 31)) {
4903 FirstShift
= Mips::DSLL
;
4904 SecondShift
= Mips::DSRL32
;
4906 if (ImmValue
== 32) {
4907 FirstShift
= Mips::DSLL32
;
4908 SecondShift
= Mips::DSRL32
;
4910 if ((ImmValue
>= 33) && (ImmValue
<= 63)) {
4911 FirstShift
= Mips::DSLL32
;
4912 SecondShift
= Mips::DSRL
;
4916 if ((ImmValue
>= 1) && (ImmValue
<= 31)) {
4917 FirstShift
= Mips::DSRL
;
4918 SecondShift
= Mips::DSLL32
;
4920 if (ImmValue
== 32) {
4921 FirstShift
= Mips::DSRL32
;
4922 SecondShift
= Mips::DSLL32
;
4924 if ((ImmValue
>= 33) && (ImmValue
<= 63)) {
4925 FirstShift
= Mips::DSRL32
;
4926 SecondShift
= Mips::DSLL
;
4931 ATReg
= getATReg(Inst
.getLoc());
4935 TOut
.emitRRI(FirstShift
, ATReg
, SReg
, ImmValue
% 32, Inst
.getLoc(), STI
);
4936 TOut
.emitRRI(SecondShift
, DReg
, SReg
, (32 - ImmValue
% 32) % 32,
4937 Inst
.getLoc(), STI
);
4938 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4946 bool MipsAsmParser::expandAbs(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4947 const MCSubtargetInfo
*STI
) {
4948 MipsTargetStreamer
&TOut
= getTargetStreamer();
4949 unsigned FirstRegOp
= Inst
.getOperand(0).getReg();
4950 unsigned SecondRegOp
= Inst
.getOperand(1).getReg();
4952 TOut
.emitRI(Mips::BGEZ
, SecondRegOp
, 8, IDLoc
, STI
);
4953 if (FirstRegOp
!= SecondRegOp
)
4954 TOut
.emitRRR(Mips::ADDu
, FirstRegOp
, SecondRegOp
, Mips::ZERO
, IDLoc
, STI
);
4956 TOut
.emitEmptyDelaySlot(false, IDLoc
, STI
);
4957 TOut
.emitRRR(Mips::SUB
, FirstRegOp
, Mips::ZERO
, SecondRegOp
, IDLoc
, STI
);
4962 bool MipsAsmParser::expandMulImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4963 const MCSubtargetInfo
*STI
) {
4964 MipsTargetStreamer
&TOut
= getTargetStreamer();
4965 unsigned ATReg
= Mips::NoRegister
;
4966 unsigned DstReg
= Inst
.getOperand(0).getReg();
4967 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4968 int32_t ImmValue
= Inst
.getOperand(2).getImm();
4970 ATReg
= getATReg(IDLoc
);
4974 loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, true, false, IDLoc
, Out
,
4977 TOut
.emitRR(Inst
.getOpcode() == Mips::MULImmMacro
? Mips::MULT
: Mips::DMULT
,
4978 SrcReg
, ATReg
, IDLoc
, STI
);
4980 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
4985 bool MipsAsmParser::expandMulO(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4986 const MCSubtargetInfo
*STI
) {
4987 MipsTargetStreamer
&TOut
= getTargetStreamer();
4988 unsigned ATReg
= Mips::NoRegister
;
4989 unsigned DstReg
= Inst
.getOperand(0).getReg();
4990 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4991 unsigned TmpReg
= Inst
.getOperand(2).getReg();
4993 ATReg
= getATReg(Inst
.getLoc());
4997 TOut
.emitRR(Inst
.getOpcode() == Mips::MULOMacro
? Mips::MULT
: Mips::DMULT
,
4998 SrcReg
, TmpReg
, IDLoc
, STI
);
5000 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5002 TOut
.emitRRI(Inst
.getOpcode() == Mips::MULOMacro
? Mips::SRA
: Mips::DSRA32
,
5003 DstReg
, DstReg
, 0x1F, IDLoc
, STI
);
5005 TOut
.emitR(Mips::MFHI
, ATReg
, IDLoc
, STI
);
5008 TOut
.emitRRI(Mips::TNE
, DstReg
, ATReg
, 6, IDLoc
, STI
);
5010 MCContext
& Context
= TOut
.getStreamer().getContext();
5011 MCSymbol
* BrTarget
= Context
.createTempSymbol();
5013 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
5015 TOut
.emitRRX(Mips::BEQ
, DstReg
, ATReg
, LabelOp
, IDLoc
, STI
);
5016 if (AssemblerOptions
.back()->isReorder())
5017 TOut
.emitNop(IDLoc
, STI
);
5018 TOut
.emitII(Mips::BREAK
, 6, 0, IDLoc
, STI
);
5020 TOut
.getStreamer().EmitLabel(BrTarget
);
5022 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5027 bool MipsAsmParser::expandMulOU(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5028 const MCSubtargetInfo
*STI
) {
5029 MipsTargetStreamer
&TOut
= getTargetStreamer();
5030 unsigned ATReg
= Mips::NoRegister
;
5031 unsigned DstReg
= Inst
.getOperand(0).getReg();
5032 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5033 unsigned TmpReg
= Inst
.getOperand(2).getReg();
5035 ATReg
= getATReg(IDLoc
);
5039 TOut
.emitRR(Inst
.getOpcode() == Mips::MULOUMacro
? Mips::MULTu
: Mips::DMULTu
,
5040 SrcReg
, TmpReg
, IDLoc
, STI
);
5042 TOut
.emitR(Mips::MFHI
, ATReg
, IDLoc
, STI
);
5043 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5045 TOut
.emitRRI(Mips::TNE
, ATReg
, Mips::ZERO
, 6, IDLoc
, STI
);
5047 MCContext
& Context
= TOut
.getStreamer().getContext();
5048 MCSymbol
* BrTarget
= Context
.createTempSymbol();
5050 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
5052 TOut
.emitRRX(Mips::BEQ
, ATReg
, Mips::ZERO
, LabelOp
, IDLoc
, STI
);
5053 if (AssemblerOptions
.back()->isReorder())
5054 TOut
.emitNop(IDLoc
, STI
);
5055 TOut
.emitII(Mips::BREAK
, 6, 0, IDLoc
, STI
);
5057 TOut
.getStreamer().EmitLabel(BrTarget
);
5063 bool MipsAsmParser::expandDMULMacro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5064 const MCSubtargetInfo
*STI
) {
5065 MipsTargetStreamer
&TOut
= getTargetStreamer();
5066 unsigned DstReg
= Inst
.getOperand(0).getReg();
5067 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5068 unsigned TmpReg
= Inst
.getOperand(2).getReg();
5070 TOut
.emitRR(Mips::DMULTu
, SrcReg
, TmpReg
, IDLoc
, STI
);
5071 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5076 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5077 // lw $<reg+1>>, offset+4($reg2)'
5078 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5079 // sw $<reg+1>>, offset+4($reg2)'
5081 bool MipsAsmParser::expandLoadStoreDMacro(MCInst
&Inst
, SMLoc IDLoc
,
5083 const MCSubtargetInfo
*STI
,
5088 warnIfNoMacro(IDLoc
);
5090 MipsTargetStreamer
&TOut
= getTargetStreamer();
5091 unsigned Opcode
= IsLoad
? Mips::LW
: Mips::SW
;
5092 unsigned FirstReg
= Inst
.getOperand(0).getReg();
5093 unsigned SecondReg
= nextReg(FirstReg
);
5094 unsigned BaseReg
= Inst
.getOperand(1).getReg();
5098 warnIfRegIndexIsAT(FirstReg
, IDLoc
);
5100 assert(Inst
.getOperand(2).isImm() &&
5101 "Offset for load macro is not immediate!");
5103 MCOperand
&FirstOffset
= Inst
.getOperand(2);
5104 signed NextOffset
= FirstOffset
.getImm() + 4;
5105 MCOperand SecondOffset
= MCOperand::createImm(NextOffset
);
5107 if (!isInt
<16>(FirstOffset
.getImm()) || !isInt
<16>(NextOffset
))
5110 // For loads, clobber the base register with the second load instead of the
5111 // first if the BaseReg == FirstReg.
5112 if (FirstReg
!= BaseReg
|| !IsLoad
) {
5113 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5114 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5116 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5117 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5124 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5125 // swc1 $<reg>, offset+4($reg2)'
5126 // or if little endian to 'swc1 $<reg>, offset($reg2);
5127 // swc1 $<reg+1>, offset+4($reg2)'
5129 bool MipsAsmParser::expandStoreDM1Macro(MCInst
&Inst
, SMLoc IDLoc
,
5131 const MCSubtargetInfo
*STI
) {
5135 warnIfNoMacro(IDLoc
);
5137 MipsTargetStreamer
&TOut
= getTargetStreamer();
5138 unsigned Opcode
= Mips::SWC1
;
5139 unsigned FirstReg
= Inst
.getOperand(0).getReg();
5140 unsigned SecondReg
= nextReg(FirstReg
);
5141 unsigned BaseReg
= Inst
.getOperand(1).getReg();
5145 warnIfRegIndexIsAT(FirstReg
, IDLoc
);
5147 assert(Inst
.getOperand(2).isImm() &&
5148 "Offset for macro is not immediate!");
5150 MCOperand
&FirstOffset
= Inst
.getOperand(2);
5151 signed NextOffset
= FirstOffset
.getImm() + 4;
5152 MCOperand SecondOffset
= MCOperand::createImm(NextOffset
);
5154 if (!isInt
<16>(FirstOffset
.getImm()) || !isInt
<16>(NextOffset
))
5157 if (!IsLittleEndian
)
5158 std::swap(FirstReg
, SecondReg
);
5160 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5161 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5166 bool MipsAsmParser::expandSeq(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5167 const MCSubtargetInfo
*STI
) {
5168 MipsTargetStreamer
&TOut
= getTargetStreamer();
5170 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5171 assert(Inst
.getOperand(0).isReg() &&
5172 Inst
.getOperand(1).isReg() &&
5173 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
5175 unsigned DstReg
= Inst
.getOperand(0).getReg();
5176 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5177 unsigned OpReg
= Inst
.getOperand(2).getReg();
5179 warnIfNoMacro(IDLoc
);
5181 if (SrcReg
!= Mips::ZERO
&& OpReg
!= Mips::ZERO
) {
5182 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, OpReg
, IDLoc
, STI
);
5183 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5187 unsigned Reg
= SrcReg
== Mips::ZERO
? OpReg
: SrcReg
;
5188 TOut
.emitRRI(Mips::SLTiu
, DstReg
, Reg
, 1, IDLoc
, STI
);
5192 bool MipsAsmParser::expandSeqI(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5193 const MCSubtargetInfo
*STI
) {
5194 MipsTargetStreamer
&TOut
= getTargetStreamer();
5196 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5197 assert(Inst
.getOperand(0).isReg() &&
5198 Inst
.getOperand(1).isReg() &&
5199 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
5201 unsigned DstReg
= Inst
.getOperand(0).getReg();
5202 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5203 int64_t Imm
= Inst
.getOperand(2).getImm();
5205 warnIfNoMacro(IDLoc
);
5208 TOut
.emitRRI(Mips::SLTiu
, DstReg
, SrcReg
, 1, IDLoc
, STI
);
5212 if (SrcReg
== Mips::ZERO
) {
5213 Warning(IDLoc
, "comparison is always false");
5214 TOut
.emitRRR(isGP64bit() ? Mips::DADDu
: Mips::ADDu
,
5215 DstReg
, SrcReg
, SrcReg
, IDLoc
, STI
);
5220 if (Imm
> -0x8000 && Imm
< 0) {
5222 Opc
= isGP64bit() ? Mips::DADDiu
: Mips::ADDiu
;
5227 if (!isUInt
<16>(Imm
)) {
5228 unsigned ATReg
= getATReg(IDLoc
);
5232 if (loadImmediate(Imm
, ATReg
, Mips::NoRegister
, true, isGP64bit(), IDLoc
,
5236 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, ATReg
, IDLoc
, STI
);
5237 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5241 TOut
.emitRRI(Opc
, DstReg
, SrcReg
, Imm
, IDLoc
, STI
);
5242 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5246 // Map the DSP accumulator and control register to the corresponding gpr
5247 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5248 // do not map the DSP registers contigously to gpr registers.
5249 static unsigned getRegisterForMxtrDSP(MCInst
&Inst
, bool IsMFDSP
) {
5250 switch (Inst
.getOpcode()) {
5253 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5263 llvm_unreachable("Unknown register for 'mttr' alias!");
5267 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5277 llvm_unreachable("Unknown register for 'mttr' alias!");
5281 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5291 llvm_unreachable("Unknown register for 'mttr' alias!");
5297 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5301 // Map the floating point register operand to the corresponding register
5303 static unsigned getRegisterForMxtrFP(MCInst
&Inst
, bool IsMFTC1
) {
5304 switch (Inst
.getOperand(IsMFTC1
? 1 : 0).getReg()) {
5305 case Mips::F0
: return Mips::ZERO
;
5306 case Mips::F1
: return Mips::AT
;
5307 case Mips::F2
: return Mips::V0
;
5308 case Mips::F3
: return Mips::V1
;
5309 case Mips::F4
: return Mips::A0
;
5310 case Mips::F5
: return Mips::A1
;
5311 case Mips::F6
: return Mips::A2
;
5312 case Mips::F7
: return Mips::A3
;
5313 case Mips::F8
: return Mips::T0
;
5314 case Mips::F9
: return Mips::T1
;
5315 case Mips::F10
: return Mips::T2
;
5316 case Mips::F11
: return Mips::T3
;
5317 case Mips::F12
: return Mips::T4
;
5318 case Mips::F13
: return Mips::T5
;
5319 case Mips::F14
: return Mips::T6
;
5320 case Mips::F15
: return Mips::T7
;
5321 case Mips::F16
: return Mips::S0
;
5322 case Mips::F17
: return Mips::S1
;
5323 case Mips::F18
: return Mips::S2
;
5324 case Mips::F19
: return Mips::S3
;
5325 case Mips::F20
: return Mips::S4
;
5326 case Mips::F21
: return Mips::S5
;
5327 case Mips::F22
: return Mips::S6
;
5328 case Mips::F23
: return Mips::S7
;
5329 case Mips::F24
: return Mips::T8
;
5330 case Mips::F25
: return Mips::T9
;
5331 case Mips::F26
: return Mips::K0
;
5332 case Mips::F27
: return Mips::K1
;
5333 case Mips::F28
: return Mips::GP
;
5334 case Mips::F29
: return Mips::SP
;
5335 case Mips::F30
: return Mips::FP
;
5336 case Mips::F31
: return Mips::RA
;
5337 default: llvm_unreachable("Unknown register for mttc1 alias!");
5341 // Map the coprocessor operand the corresponding gpr register operand.
5342 static unsigned getRegisterForMxtrC0(MCInst
&Inst
, bool IsMFTC0
) {
5343 switch (Inst
.getOperand(IsMFTC0
? 1 : 0).getReg()) {
5344 case Mips::COP00
: return Mips::ZERO
;
5345 case Mips::COP01
: return Mips::AT
;
5346 case Mips::COP02
: return Mips::V0
;
5347 case Mips::COP03
: return Mips::V1
;
5348 case Mips::COP04
: return Mips::A0
;
5349 case Mips::COP05
: return Mips::A1
;
5350 case Mips::COP06
: return Mips::A2
;
5351 case Mips::COP07
: return Mips::A3
;
5352 case Mips::COP08
: return Mips::T0
;
5353 case Mips::COP09
: return Mips::T1
;
5354 case Mips::COP010
: return Mips::T2
;
5355 case Mips::COP011
: return Mips::T3
;
5356 case Mips::COP012
: return Mips::T4
;
5357 case Mips::COP013
: return Mips::T5
;
5358 case Mips::COP014
: return Mips::T6
;
5359 case Mips::COP015
: return Mips::T7
;
5360 case Mips::COP016
: return Mips::S0
;
5361 case Mips::COP017
: return Mips::S1
;
5362 case Mips::COP018
: return Mips::S2
;
5363 case Mips::COP019
: return Mips::S3
;
5364 case Mips::COP020
: return Mips::S4
;
5365 case Mips::COP021
: return Mips::S5
;
5366 case Mips::COP022
: return Mips::S6
;
5367 case Mips::COP023
: return Mips::S7
;
5368 case Mips::COP024
: return Mips::T8
;
5369 case Mips::COP025
: return Mips::T9
;
5370 case Mips::COP026
: return Mips::K0
;
5371 case Mips::COP027
: return Mips::K1
;
5372 case Mips::COP028
: return Mips::GP
;
5373 case Mips::COP029
: return Mips::SP
;
5374 case Mips::COP030
: return Mips::FP
;
5375 case Mips::COP031
: return Mips::RA
;
5376 default: llvm_unreachable("Unknown register for mttc0 alias!");
5380 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5381 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5382 bool MipsAsmParser::expandMXTRAlias(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5383 const MCSubtargetInfo
*STI
) {
5384 MipsTargetStreamer
&TOut
= getTargetStreamer();
5389 bool IsMFTR
= false;
5390 switch (Inst
.getOpcode()) {
5396 rd
= getRegisterForMxtrC0(Inst
, IsMFTR
);
5397 sel
= Inst
.getOperand(2).getImm();
5403 rd
= Inst
.getOperand(IsMFTR
? 1 : 0).getReg();
5415 rd
= getRegisterForMxtrDSP(Inst
, IsMFTR
);
5423 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5430 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5437 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5441 unsigned Op0
= IsMFTR
? Inst
.getOperand(0).getReg() : rd
;
5444 : (Inst
.getOpcode() != Mips::MTTDSP
? Inst
.getOperand(1).getReg()
5445 : Inst
.getOperand(0).getReg());
5447 TOut
.emitRRIII(IsMFTR
? Mips::MFTR
: Mips::MTTR
, Op0
, Op1
, u
, sel
, h
, IDLoc
,
5453 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst
&Inst
,
5454 const OperandVector
&Operands
) {
5455 switch (Inst
.getOpcode()) {
5457 return Match_Success
;
5460 if (static_cast<MipsOperand
&>(*Operands
[1])
5461 .isValidForTie(static_cast<MipsOperand
&>(*Operands
[2])))
5462 return Match_Success
;
5463 return Match_RequiresSameSrcAndDst
;
5467 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst
&Inst
) {
5468 switch (Inst
.getOpcode()) {
5469 // As described by the MIPSR6 spec, daui must not use the zero operand for
5470 // its source operand.
5472 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
5473 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
5474 return Match_RequiresNoZeroRegister
;
5475 return Match_Success
;
5476 // As described by the Mips32r2 spec, the registers Rd and Rs for
5477 // jalr.hb must be different.
5478 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5479 // and registers Rd and Base for microMIPS lwp instruction
5481 case Mips::JALR_HB64
:
5482 case Mips::JALRC_HB_MMR6
:
5483 case Mips::JALRC_MMR6
:
5484 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(1).getReg())
5485 return Match_RequiresDifferentSrcAndDst
;
5486 return Match_Success
;
5488 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(2).getReg())
5489 return Match_RequiresDifferentSrcAndDst
;
5490 return Match_Success
;
5492 if (Inst
.getOperand(0).getImm() != 0 && !hasMips32())
5493 return Match_NonZeroOperandForSync
;
5494 return Match_Success
;
5499 if (Inst
.getOperand(2).getImm() != 0 && !hasMips32())
5500 return Match_NonZeroOperandForMTCX
;
5501 return Match_Success
;
5502 // As described the MIPSR6 spec, the compact branches that compare registers
5504 // a) Not use the zero register.
5505 // b) Not use the same register twice.
5506 // c) rs < rt for bnec, beqc.
5507 // NB: For this case, the encoding will swap the operands as their
5508 // ordering doesn't matter. GAS performs this transformation too.
5509 // Hence, that constraint does not have to be enforced.
5511 // The compact branches that branch iff the signed addition of two registers
5512 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5513 // operand swapping. They do not have restriction of using the zero register.
5514 case Mips::BLEZC
: case Mips::BLEZC_MMR6
:
5515 case Mips::BGEZC
: case Mips::BGEZC_MMR6
:
5516 case Mips::BGTZC
: case Mips::BGTZC_MMR6
:
5517 case Mips::BLTZC
: case Mips::BLTZC_MMR6
:
5518 case Mips::BEQZC
: case Mips::BEQZC_MMR6
:
5519 case Mips::BNEZC
: case Mips::BNEZC_MMR6
:
5526 if (Inst
.getOperand(0).getReg() == Mips::ZERO
||
5527 Inst
.getOperand(0).getReg() == Mips::ZERO_64
)
5528 return Match_RequiresNoZeroRegister
;
5529 return Match_Success
;
5530 case Mips::BGEC
: case Mips::BGEC_MMR6
:
5531 case Mips::BLTC
: case Mips::BLTC_MMR6
:
5532 case Mips::BGEUC
: case Mips::BGEUC_MMR6
:
5533 case Mips::BLTUC
: case Mips::BLTUC_MMR6
:
5534 case Mips::BEQC
: case Mips::BEQC_MMR6
:
5535 case Mips::BNEC
: case Mips::BNEC_MMR6
:
5542 if (Inst
.getOperand(0).getReg() == Mips::ZERO
||
5543 Inst
.getOperand(0).getReg() == Mips::ZERO_64
)
5544 return Match_RequiresNoZeroRegister
;
5545 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
5546 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
5547 return Match_RequiresNoZeroRegister
;
5548 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(1).getReg())
5549 return Match_RequiresDifferentOperands
;
5550 return Match_Success
;
5552 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5553 "Operands must be immediates for dins!");
5554 const signed Pos
= Inst
.getOperand(2).getImm();
5555 const signed Size
= Inst
.getOperand(3).getImm();
5556 if ((0 > (Pos
+ Size
)) || ((Pos
+ Size
) > 32))
5557 return Match_RequiresPosSizeRange0_32
;
5558 return Match_Success
;
5562 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5563 "Operands must be immediates for dinsm/dinsu!");
5564 const signed Pos
= Inst
.getOperand(2).getImm();
5565 const signed Size
= Inst
.getOperand(3).getImm();
5566 if ((32 >= (Pos
+ Size
)) || ((Pos
+ Size
) > 64))
5567 return Match_RequiresPosSizeRange33_64
;
5568 return Match_Success
;
5571 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5572 "Operands must be immediates for DEXTM!");
5573 const signed Pos
= Inst
.getOperand(2).getImm();
5574 const signed Size
= Inst
.getOperand(3).getImm();
5575 if ((1 > (Pos
+ Size
)) || ((Pos
+ Size
) > 63))
5576 return Match_RequiresPosSizeUImm6
;
5577 return Match_Success
;
5581 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5582 "Operands must be immediates for dextm/dextu!");
5583 const signed Pos
= Inst
.getOperand(2).getImm();
5584 const signed Size
= Inst
.getOperand(3).getImm();
5585 if ((32 > (Pos
+ Size
)) || ((Pos
+ Size
) > 64))
5586 return Match_RequiresPosSizeRange33_64
;
5587 return Match_Success
;
5589 case Mips::CRC32B
: case Mips::CRC32CB
:
5590 case Mips::CRC32H
: case Mips::CRC32CH
:
5591 case Mips::CRC32W
: case Mips::CRC32CW
:
5592 case Mips::CRC32D
: case Mips::CRC32CD
:
5593 if (Inst
.getOperand(0).getReg() != Inst
.getOperand(2).getReg())
5594 return Match_RequiresSameSrcAndDst
;
5595 return Match_Success
;
5598 uint64_t TSFlags
= getInstDesc(Inst
.getOpcode()).TSFlags
;
5599 if ((TSFlags
& MipsII::HasFCCRegOperand
) &&
5600 (Inst
.getOperand(0).getReg() != Mips::FCC0
) && !hasEightFccRegisters())
5601 return Match_NoFCCRegisterForCurrentISA
;
5603 return Match_Success
;
5607 static SMLoc
RefineErrorLoc(const SMLoc Loc
, const OperandVector
&Operands
,
5608 uint64_t ErrorInfo
) {
5609 if (ErrorInfo
!= ~0ULL && ErrorInfo
< Operands
.size()) {
5610 SMLoc ErrorLoc
= Operands
[ErrorInfo
]->getStartLoc();
5611 if (ErrorLoc
== SMLoc())
5618 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
5619 OperandVector
&Operands
,
5621 uint64_t &ErrorInfo
,
5622 bool MatchingInlineAsm
) {
5624 unsigned MatchResult
=
5625 MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
);
5627 switch (MatchResult
) {
5629 if (processInstruction(Inst
, IDLoc
, Out
, STI
))
5632 case Match_MissingFeature
:
5633 Error(IDLoc
, "instruction requires a CPU feature not currently enabled");
5635 case Match_InvalidOperand
: {
5636 SMLoc ErrorLoc
= IDLoc
;
5637 if (ErrorInfo
!= ~0ULL) {
5638 if (ErrorInfo
>= Operands
.size())
5639 return Error(IDLoc
, "too few operands for instruction");
5641 ErrorLoc
= Operands
[ErrorInfo
]->getStartLoc();
5642 if (ErrorLoc
== SMLoc())
5646 return Error(ErrorLoc
, "invalid operand for instruction");
5648 case Match_NonZeroOperandForSync
:
5650 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5651 case Match_NonZeroOperandForMTCX
:
5652 return Error(IDLoc
, "selector must be zero for pre-MIPS32 ISAs");
5653 case Match_MnemonicFail
:
5654 return Error(IDLoc
, "invalid instruction");
5655 case Match_RequiresDifferentSrcAndDst
:
5656 return Error(IDLoc
, "source and destination must be different");
5657 case Match_RequiresDifferentOperands
:
5658 return Error(IDLoc
, "registers must be different");
5659 case Match_RequiresNoZeroRegister
:
5660 return Error(IDLoc
, "invalid operand ($zero) for instruction");
5661 case Match_RequiresSameSrcAndDst
:
5662 return Error(IDLoc
, "source and destination must match");
5663 case Match_NoFCCRegisterForCurrentISA
:
5664 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5665 "non-zero fcc register doesn't exist in current ISA level");
5667 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
), "expected '0'");
5669 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5670 "expected 1-bit unsigned immediate");
5672 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5673 "expected 2-bit unsigned immediate");
5675 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5676 "expected immediate in range 1 .. 4");
5678 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5679 "expected 3-bit unsigned immediate");
5681 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5682 "expected 4-bit unsigned immediate");
5684 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5685 "expected 4-bit signed immediate");
5687 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5688 "expected 5-bit unsigned immediate");
5690 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5691 "expected 5-bit signed immediate");
5693 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5694 "expected immediate in range 1 .. 32");
5695 case Match_UImm5_32
:
5696 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5697 "expected immediate in range 32 .. 63");
5698 case Match_UImm5_33
:
5699 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5700 "expected immediate in range 33 .. 64");
5701 case Match_UImm5_0_Report_UImm6
:
5702 // This is used on UImm5 operands that have a corresponding UImm5_32
5703 // operand to avoid confusing the user.
5704 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5705 "expected 6-bit unsigned immediate");
5706 case Match_UImm5_Lsl2
:
5707 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5708 "expected both 7-bit unsigned immediate and multiple of 4");
5709 case Match_UImmRange2_64
:
5710 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5711 "expected immediate in range 2 .. 64");
5713 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5714 "expected 6-bit unsigned immediate");
5715 case Match_UImm6_Lsl2
:
5716 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5717 "expected both 8-bit unsigned immediate and multiple of 4");
5719 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5720 "expected 6-bit signed immediate");
5722 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5723 "expected 7-bit unsigned immediate");
5724 case Match_UImm7_N1
:
5725 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5726 "expected immediate in range -1 .. 126");
5727 case Match_SImm7_Lsl2
:
5728 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5729 "expected both 9-bit signed immediate and multiple of 4");
5731 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5732 "expected 8-bit unsigned immediate");
5733 case Match_UImm10_0
:
5734 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5735 "expected 10-bit unsigned immediate");
5736 case Match_SImm10_0
:
5737 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5738 "expected 10-bit signed immediate");
5739 case Match_SImm11_0
:
5740 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5741 "expected 11-bit signed immediate");
5743 case Match_UImm16_Relaxed
:
5744 case Match_UImm16_AltRelaxed
:
5745 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5746 "expected 16-bit unsigned immediate");
5748 case Match_SImm16_Relaxed
:
5749 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5750 "expected 16-bit signed immediate");
5751 case Match_SImm19_Lsl2
:
5752 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5753 "expected both 19-bit signed immediate and multiple of 4");
5754 case Match_UImm20_0
:
5755 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5756 "expected 20-bit unsigned immediate");
5757 case Match_UImm26_0
:
5758 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5759 "expected 26-bit unsigned immediate");
5761 case Match_SImm32_Relaxed
:
5762 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5763 "expected 32-bit signed immediate");
5764 case Match_UImm32_Coerced
:
5765 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5766 "expected 32-bit immediate");
5767 case Match_MemSImm9
:
5768 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5769 "expected memory with 9-bit signed offset");
5770 case Match_MemSImm10
:
5771 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5772 "expected memory with 10-bit signed offset");
5773 case Match_MemSImm10Lsl1
:
5774 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5775 "expected memory with 11-bit signed offset and multiple of 2");
5776 case Match_MemSImm10Lsl2
:
5777 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5778 "expected memory with 12-bit signed offset and multiple of 4");
5779 case Match_MemSImm10Lsl3
:
5780 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5781 "expected memory with 13-bit signed offset and multiple of 8");
5782 case Match_MemSImm11
:
5783 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5784 "expected memory with 11-bit signed offset");
5785 case Match_MemSImm12
:
5786 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5787 "expected memory with 12-bit signed offset");
5788 case Match_MemSImm16
:
5789 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5790 "expected memory with 16-bit signed offset");
5791 case Match_MemSImmPtr
:
5792 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5793 "expected memory with 32-bit signed offset");
5794 case Match_RequiresPosSizeRange0_32
: {
5795 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
5796 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
5797 return Error(ErrorStart
, "size plus position are not in the range 0 .. 32",
5798 SMRange(ErrorStart
, ErrorEnd
));
5800 case Match_RequiresPosSizeUImm6
: {
5801 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
5802 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
5803 return Error(ErrorStart
, "size plus position are not in the range 1 .. 63",
5804 SMRange(ErrorStart
, ErrorEnd
));
5806 case Match_RequiresPosSizeRange33_64
: {
5807 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
5808 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
5809 return Error(ErrorStart
, "size plus position are not in the range 33 .. 64",
5810 SMRange(ErrorStart
, ErrorEnd
));
5814 llvm_unreachable("Implement any new match types added!");
5817 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex
, SMLoc Loc
) {
5818 if (RegIndex
!= 0 && AssemblerOptions
.back()->getATRegIndex() == RegIndex
)
5819 Warning(Loc
, "used $at (currently $" + Twine(RegIndex
) +
5820 ") without \".set noat\"");
5823 void MipsAsmParser::warnIfNoMacro(SMLoc Loc
) {
5824 if (!AssemblerOptions
.back()->isMacro())
5825 Warning(Loc
, "macro instruction expanded into multiple instructions");
5828 void MipsAsmParser::ConvertXWPOperands(MCInst
&Inst
,
5829 const OperandVector
&Operands
) {
5831 (Inst
.getOpcode() == Mips::LWP_MM
|| Inst
.getOpcode() == Mips::SWP_MM
) &&
5832 "Unexpected instruction!");
5833 ((MipsOperand
&)*Operands
[1]).addGPR32ZeroAsmRegOperands(Inst
, 1);
5834 int NextReg
= nextReg(((MipsOperand
&)*Operands
[1]).getGPR32Reg());
5835 Inst
.addOperand(MCOperand::createReg(NextReg
));
5836 ((MipsOperand
&)*Operands
[2]).addMemOperands(Inst
, 2);
5840 MipsAsmParser::printWarningWithFixIt(const Twine
&Msg
, const Twine
&FixMsg
,
5841 SMRange Range
, bool ShowColors
) {
5842 getSourceManager().PrintMessage(Range
.Start
, SourceMgr::DK_Warning
, Msg
,
5843 Range
, SMFixIt(Range
, FixMsg
),
5847 int MipsAsmParser::matchCPURegisterName(StringRef Name
) {
5850 CC
= StringSwitch
<unsigned>(Name
)
5852 .Cases("at", "AT", 1)
5886 if (!(isABI_N32() || isABI_N64()))
5889 if (12 <= CC
&& CC
<= 15) {
5890 // Name is one of t4-t7
5891 AsmToken RegTok
= getLexer().peekTok();
5892 SMRange RegRange
= RegTok
.getLocRange();
5894 StringRef FixedName
= StringSwitch
<StringRef
>(Name
)
5900 assert(FixedName
!= "" && "Register name is not one of t4-t7.");
5902 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5903 "Did you mean $" + FixedName
+ "?", RegRange
);
5906 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5907 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5908 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5909 if (8 <= CC
&& CC
<= 11)
5913 CC
= StringSwitch
<unsigned>(Name
)
5925 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name
) {
5928 CC
= StringSwitch
<unsigned>(Name
)
5929 .Case("hwr_cpunum", 0)
5930 .Case("hwr_synci_step", 1)
5932 .Case("hwr_ccres", 3)
5933 .Case("hwr_ulr", 29)
5939 int MipsAsmParser::matchFPURegisterName(StringRef Name
) {
5940 if (Name
[0] == 'f') {
5941 StringRef NumString
= Name
.substr(1);
5943 if (NumString
.getAsInteger(10, IntVal
))
5944 return -1; // This is not an integer.
5945 if (IntVal
> 31) // Maximum index for fpu register.
5952 int MipsAsmParser::matchFCCRegisterName(StringRef Name
) {
5953 if (Name
.startswith("fcc")) {
5954 StringRef NumString
= Name
.substr(3);
5956 if (NumString
.getAsInteger(10, IntVal
))
5957 return -1; // This is not an integer.
5958 if (IntVal
> 7) // There are only 8 fcc registers.
5965 int MipsAsmParser::matchACRegisterName(StringRef Name
) {
5966 if (Name
.startswith("ac")) {
5967 StringRef NumString
= Name
.substr(2);
5969 if (NumString
.getAsInteger(10, IntVal
))
5970 return -1; // This is not an integer.
5971 if (IntVal
> 3) // There are only 3 acc registers.
5978 int MipsAsmParser::matchMSA128RegisterName(StringRef Name
) {
5981 if (Name
.front() != 'w' || Name
.drop_front(1).getAsInteger(10, IntVal
))
5990 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name
) {
5993 CC
= StringSwitch
<unsigned>(Name
)
5996 .Case("msaaccess", 2)
5998 .Case("msamodify", 4)
5999 .Case("msarequest", 5)
6001 .Case("msaunmap", 7)
6007 bool MipsAsmParser::canUseATReg() {
6008 return AssemblerOptions
.back()->getATRegIndex() != 0;
6011 unsigned MipsAsmParser::getATReg(SMLoc Loc
) {
6012 unsigned ATIndex
= AssemblerOptions
.back()->getATRegIndex();
6014 reportParseError(Loc
,
6015 "pseudo-instruction requires $at, which is not available");
6018 unsigned AT
= getReg(
6019 (isGP64bit()) ? Mips::GPR64RegClassID
: Mips::GPR32RegClassID
, ATIndex
);
6023 unsigned MipsAsmParser::getReg(int RC
, int RegNo
) {
6024 return *(getContext().getRegisterInfo()->getRegClass(RC
).begin() + RegNo
);
6027 bool MipsAsmParser::parseOperand(OperandVector
&Operands
, StringRef Mnemonic
) {
6028 MCAsmParser
&Parser
= getParser();
6029 LLVM_DEBUG(dbgs() << "parseOperand\n");
6031 // Check if the current operand has a custom associated parser, if so, try to
6032 // custom parse the operand, or fallback to the general approach.
6033 OperandMatchResultTy ResTy
= MatchOperandParserImpl(Operands
, Mnemonic
);
6034 if (ResTy
== MatchOperand_Success
)
6036 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6037 // there was a match, but an error occurred, in which case, just return that
6038 // the operand parsing failed.
6039 if (ResTy
== MatchOperand_ParseFail
)
6042 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6044 switch (getLexer().getKind()) {
6045 case AsmToken::Dollar
: {
6046 // Parse the register.
6047 SMLoc S
= Parser
.getTok().getLoc();
6049 // Almost all registers have been parsed by custom parsers. There is only
6050 // one exception to this. $zero (and it's alias $0) will reach this point
6051 // for div, divu, and similar instructions because it is not an operand
6052 // to the instruction definition but an explicit register. Special case
6053 // this situation for now.
6054 if (parseAnyRegister(Operands
) != MatchOperand_NoMatch
)
6057 // Maybe it is a symbol reference.
6058 StringRef Identifier
;
6059 if (Parser
.parseIdentifier(Identifier
))
6062 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6063 MCSymbol
*Sym
= getContext().getOrCreateSymbol("$" + Identifier
);
6064 // Otherwise create a symbol reference.
6066 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
6068 Operands
.push_back(MipsOperand::CreateImm(Res
, S
, E
, *this));
6072 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6075 SMLoc S
= Parser
.getTok().getLoc(); // Start location of the operand.
6076 if (getParser().parseExpression(Expr
))
6079 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6081 Operands
.push_back(MipsOperand::CreateImm(Expr
, S
, E
, *this));
6084 } // switch(getLexer().getKind())
6088 bool MipsAsmParser::isEvaluated(const MCExpr
*Expr
) {
6089 switch (Expr
->getKind()) {
6090 case MCExpr::Constant
:
6092 case MCExpr::SymbolRef
:
6093 return (cast
<MCSymbolRefExpr
>(Expr
)->getKind() != MCSymbolRefExpr::VK_None
);
6094 case MCExpr::Binary
: {
6095 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Expr
);
6096 if (!isEvaluated(BE
->getLHS()))
6098 return isEvaluated(BE
->getRHS());
6101 return isEvaluated(cast
<MCUnaryExpr
>(Expr
)->getSubExpr());
6102 case MCExpr::Target
:
6108 bool MipsAsmParser::ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
,
6110 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Operands
;
6111 OperandMatchResultTy ResTy
= parseAnyRegister(Operands
);
6112 if (ResTy
== MatchOperand_Success
) {
6113 assert(Operands
.size() == 1);
6114 MipsOperand
&Operand
= static_cast<MipsOperand
&>(*Operands
.front());
6115 StartLoc
= Operand
.getStartLoc();
6116 EndLoc
= Operand
.getEndLoc();
6118 // AFAIK, we only support numeric registers and named GPR's in CFI
6120 // Don't worry about eating tokens before failing. Using an unrecognised
6121 // register is a parse error.
6122 if (Operand
.isGPRAsmReg()) {
6123 // Resolve to GPR32 or GPR64 appropriately.
6124 RegNo
= isGP64bit() ? Operand
.getGPR64Reg() : Operand
.getGPR32Reg();
6127 return (RegNo
== (unsigned)-1);
6130 assert(Operands
.size() == 0);
6131 return (RegNo
== (unsigned)-1);
6134 bool MipsAsmParser::parseMemOffset(const MCExpr
*&Res
, bool isParenExpr
) {
6138 return getParser().parseParenExprOfDepth(0, Res
, S
);
6139 return getParser().parseExpression(Res
);
6142 OperandMatchResultTy
6143 MipsAsmParser::parseMemOperand(OperandVector
&Operands
) {
6144 MCAsmParser
&Parser
= getParser();
6145 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6146 const MCExpr
*IdVal
= nullptr;
6148 bool isParenExpr
= false;
6149 OperandMatchResultTy Res
= MatchOperand_NoMatch
;
6150 // First operand is the offset.
6151 S
= Parser
.getTok().getLoc();
6153 if (getLexer().getKind() == AsmToken::LParen
) {
6158 if (getLexer().getKind() != AsmToken::Dollar
) {
6159 if (parseMemOffset(IdVal
, isParenExpr
))
6160 return MatchOperand_ParseFail
;
6162 const AsmToken
&Tok
= Parser
.getTok(); // Get the next token.
6163 if (Tok
.isNot(AsmToken::LParen
)) {
6164 MipsOperand
&Mnemonic
= static_cast<MipsOperand
&>(*Operands
[0]);
6165 if (Mnemonic
.getToken() == "la" || Mnemonic
.getToken() == "dla") {
6167 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6168 Operands
.push_back(MipsOperand::CreateImm(IdVal
, S
, E
, *this));
6169 return MatchOperand_Success
;
6171 if (Tok
.is(AsmToken::EndOfStatement
)) {
6173 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6175 // Zero register assumed, add a memory operand with ZERO as its base.
6176 // "Base" will be managed by k_Memory.
6177 auto Base
= MipsOperand::createGPRReg(
6178 0, "0", getContext().getRegisterInfo(), S
, E
, *this);
6180 MipsOperand::CreateMem(std::move(Base
), IdVal
, S
, E
, *this));
6181 return MatchOperand_Success
;
6183 MCBinaryExpr::Opcode Opcode
;
6184 // GAS and LLVM treat comparison operators different. GAS will generate -1
6185 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6186 // highly unlikely to be found in a memory offset expression, we don't
6188 switch (Tok
.getKind()) {
6189 case AsmToken::Plus
:
6190 Opcode
= MCBinaryExpr::Add
;
6193 case AsmToken::Minus
:
6194 Opcode
= MCBinaryExpr::Sub
;
6197 case AsmToken::Star
:
6198 Opcode
= MCBinaryExpr::Mul
;
6201 case AsmToken::Pipe
:
6202 Opcode
= MCBinaryExpr::Or
;
6206 Opcode
= MCBinaryExpr::And
;
6209 case AsmToken::LessLess
:
6210 Opcode
= MCBinaryExpr::Shl
;
6213 case AsmToken::GreaterGreater
:
6214 Opcode
= MCBinaryExpr::LShr
;
6217 case AsmToken::Caret
:
6218 Opcode
= MCBinaryExpr::Xor
;
6221 case AsmToken::Slash
:
6222 Opcode
= MCBinaryExpr::Div
;
6225 case AsmToken::Percent
:
6226 Opcode
= MCBinaryExpr::Mod
;
6230 Error(Parser
.getTok().getLoc(), "'(' or expression expected");
6231 return MatchOperand_ParseFail
;
6233 const MCExpr
* NextExpr
;
6234 if (getParser().parseExpression(NextExpr
))
6235 return MatchOperand_ParseFail
;
6236 IdVal
= MCBinaryExpr::create(Opcode
, IdVal
, NextExpr
, getContext());
6239 Parser
.Lex(); // Eat the '(' token.
6242 Res
= parseAnyRegister(Operands
);
6243 if (Res
!= MatchOperand_Success
)
6246 if (Parser
.getTok().isNot(AsmToken::RParen
)) {
6247 Error(Parser
.getTok().getLoc(), "')' expected");
6248 return MatchOperand_ParseFail
;
6251 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6253 Parser
.Lex(); // Eat the ')' token.
6256 IdVal
= MCConstantExpr::create(0, getContext());
6258 // Replace the register operand with the memory operand.
6259 std::unique_ptr
<MipsOperand
> op(
6260 static_cast<MipsOperand
*>(Operands
.back().release()));
6261 // Remove the register from the operands.
6262 // "op" will be managed by k_Memory.
6263 Operands
.pop_back();
6264 // Add the memory operand.
6265 if (const MCBinaryExpr
*BE
= dyn_cast
<MCBinaryExpr
>(IdVal
)) {
6267 if (IdVal
->evaluateAsAbsolute(Imm
))
6268 IdVal
= MCConstantExpr::create(Imm
, getContext());
6269 else if (BE
->getLHS()->getKind() != MCExpr::SymbolRef
)
6270 IdVal
= MCBinaryExpr::create(BE
->getOpcode(), BE
->getRHS(), BE
->getLHS(),
6274 Operands
.push_back(MipsOperand::CreateMem(std::move(op
), IdVal
, S
, E
, *this));
6275 return MatchOperand_Success
;
6278 bool MipsAsmParser::searchSymbolAlias(OperandVector
&Operands
) {
6279 MCAsmParser
&Parser
= getParser();
6280 MCSymbol
*Sym
= getContext().lookupSymbol(Parser
.getTok().getIdentifier());
6284 SMLoc S
= Parser
.getTok().getLoc();
6285 if (Sym
->isVariable()) {
6286 const MCExpr
*Expr
= Sym
->getVariableValue();
6287 if (Expr
->getKind() == MCExpr::SymbolRef
) {
6288 const MCSymbolRefExpr
*Ref
= static_cast<const MCSymbolRefExpr
*>(Expr
);
6289 StringRef DefSymbol
= Ref
->getSymbol().getName();
6290 if (DefSymbol
.startswith("$")) {
6291 OperandMatchResultTy ResTy
=
6292 matchAnyRegisterNameWithoutDollar(Operands
, DefSymbol
.substr(1), S
);
6293 if (ResTy
== MatchOperand_Success
) {
6297 if (ResTy
== MatchOperand_ParseFail
)
6298 llvm_unreachable("Should never ParseFail");
6301 } else if (Sym
->isUnset()) {
6302 // If symbol is unset, it might be created in the `parseSetAssignment`
6303 // routine as an alias for a numeric register name.
6304 // Lookup in the aliases list.
6305 auto Entry
= RegisterSets
.find(Sym
->getName());
6306 if (Entry
!= RegisterSets
.end()) {
6307 OperandMatchResultTy ResTy
=
6308 matchAnyRegisterWithoutDollar(Operands
, Entry
->getValue(), S
);
6309 if (ResTy
== MatchOperand_Success
) {
6319 OperandMatchResultTy
6320 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector
&Operands
,
6321 StringRef Identifier
,
6323 int Index
= matchCPURegisterName(Identifier
);
6325 Operands
.push_back(MipsOperand::createGPRReg(
6326 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6327 getLexer().getLoc(), *this));
6328 return MatchOperand_Success
;
6331 Index
= matchHWRegsRegisterName(Identifier
);
6333 Operands
.push_back(MipsOperand::createHWRegsReg(
6334 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6335 getLexer().getLoc(), *this));
6336 return MatchOperand_Success
;
6339 Index
= matchFPURegisterName(Identifier
);
6341 Operands
.push_back(MipsOperand::createFGRReg(
6342 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6343 getLexer().getLoc(), *this));
6344 return MatchOperand_Success
;
6347 Index
= matchFCCRegisterName(Identifier
);
6349 Operands
.push_back(MipsOperand::createFCCReg(
6350 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6351 getLexer().getLoc(), *this));
6352 return MatchOperand_Success
;
6355 Index
= matchACRegisterName(Identifier
);
6357 Operands
.push_back(MipsOperand::createACCReg(
6358 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6359 getLexer().getLoc(), *this));
6360 return MatchOperand_Success
;
6363 Index
= matchMSA128RegisterName(Identifier
);
6365 Operands
.push_back(MipsOperand::createMSA128Reg(
6366 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6367 getLexer().getLoc(), *this));
6368 return MatchOperand_Success
;
6371 Index
= matchMSA128CtrlRegisterName(Identifier
);
6373 Operands
.push_back(MipsOperand::createMSACtrlReg(
6374 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6375 getLexer().getLoc(), *this));
6376 return MatchOperand_Success
;
6379 return MatchOperand_NoMatch
;
6382 OperandMatchResultTy
6383 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector
&Operands
,
6384 const AsmToken
&Token
, SMLoc S
) {
6385 if (Token
.is(AsmToken::Identifier
)) {
6386 LLVM_DEBUG(dbgs() << ".. identifier\n");
6387 StringRef Identifier
= Token
.getIdentifier();
6388 OperandMatchResultTy ResTy
=
6389 matchAnyRegisterNameWithoutDollar(Operands
, Identifier
, S
);
6391 } else if (Token
.is(AsmToken::Integer
)) {
6392 LLVM_DEBUG(dbgs() << ".. integer\n");
6393 int64_t RegNum
= Token
.getIntVal();
6394 if (RegNum
< 0 || RegNum
> 31) {
6395 // Show the error, but treat invalid register
6396 // number as a normal one to continue parsing
6397 // and catch other possible errors.
6398 Error(getLexer().getLoc(), "invalid register number");
6400 Operands
.push_back(MipsOperand::createNumericReg(
6401 RegNum
, Token
.getString(), getContext().getRegisterInfo(), S
,
6402 Token
.getLoc(), *this));
6403 return MatchOperand_Success
;
6406 LLVM_DEBUG(dbgs() << Token
.getKind() << "\n");
6408 return MatchOperand_NoMatch
;
6411 OperandMatchResultTy
6412 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector
&Operands
, SMLoc S
) {
6413 auto Token
= getLexer().peekTok(false);
6414 return matchAnyRegisterWithoutDollar(Operands
, Token
, S
);
6417 OperandMatchResultTy
6418 MipsAsmParser::parseAnyRegister(OperandVector
&Operands
) {
6419 MCAsmParser
&Parser
= getParser();
6420 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6422 auto Token
= Parser
.getTok();
6424 SMLoc S
= Token
.getLoc();
6426 if (Token
.isNot(AsmToken::Dollar
)) {
6427 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6428 if (Token
.is(AsmToken::Identifier
)) {
6429 if (searchSymbolAlias(Operands
))
6430 return MatchOperand_Success
;
6432 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6433 return MatchOperand_NoMatch
;
6435 LLVM_DEBUG(dbgs() << ".. $\n");
6437 OperandMatchResultTy ResTy
= matchAnyRegisterWithoutDollar(Operands
, S
);
6438 if (ResTy
== MatchOperand_Success
) {
6440 Parser
.Lex(); // identifier
6445 OperandMatchResultTy
6446 MipsAsmParser::parseJumpTarget(OperandVector
&Operands
) {
6447 MCAsmParser
&Parser
= getParser();
6448 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6450 SMLoc S
= getLexer().getLoc();
6452 // Registers are a valid target and have priority over symbols.
6453 OperandMatchResultTy ResTy
= parseAnyRegister(Operands
);
6454 if (ResTy
!= MatchOperand_NoMatch
)
6457 // Integers and expressions are acceptable
6458 const MCExpr
*Expr
= nullptr;
6459 if (Parser
.parseExpression(Expr
)) {
6460 // We have no way of knowing if a symbol was consumed so we must ParseFail
6461 return MatchOperand_ParseFail
;
6464 MipsOperand::CreateImm(Expr
, S
, getLexer().getLoc(), *this));
6465 return MatchOperand_Success
;
6468 OperandMatchResultTy
6469 MipsAsmParser::parseInvNum(OperandVector
&Operands
) {
6470 MCAsmParser
&Parser
= getParser();
6471 const MCExpr
*IdVal
;
6472 // If the first token is '$' we may have register operand. We have to reject
6473 // cases where it is not a register. Complicating the matter is that
6474 // register names are not reserved across all ABIs.
6475 // Peek past the dollar to see if it's a register name for this ABI.
6476 SMLoc S
= Parser
.getTok().getLoc();
6477 if (Parser
.getTok().is(AsmToken::Dollar
)) {
6478 return matchCPURegisterName(Parser
.getLexer().peekTok().getString()) == -1
6479 ? MatchOperand_ParseFail
6480 : MatchOperand_NoMatch
;
6482 if (getParser().parseExpression(IdVal
))
6483 return MatchOperand_ParseFail
;
6484 const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(IdVal
);
6486 return MatchOperand_NoMatch
;
6487 int64_t Val
= MCE
->getValue();
6488 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6489 Operands
.push_back(MipsOperand::CreateImm(
6490 MCConstantExpr::create(0 - Val
, getContext()), S
, E
, *this));
6491 return MatchOperand_Success
;
6494 OperandMatchResultTy
6495 MipsAsmParser::parseRegisterList(OperandVector
&Operands
) {
6496 MCAsmParser
&Parser
= getParser();
6497 SmallVector
<unsigned, 10> Regs
;
6499 unsigned PrevReg
= Mips::NoRegister
;
6500 bool RegRange
= false;
6501 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 8> TmpOperands
;
6503 if (Parser
.getTok().isNot(AsmToken::Dollar
))
6504 return MatchOperand_ParseFail
;
6506 SMLoc S
= Parser
.getTok().getLoc();
6507 while (parseAnyRegister(TmpOperands
) == MatchOperand_Success
) {
6508 SMLoc E
= getLexer().getLoc();
6509 MipsOperand
&Reg
= static_cast<MipsOperand
&>(*TmpOperands
.back());
6510 RegNo
= isGP64bit() ? Reg
.getGPR64Reg() : Reg
.getGPR32Reg();
6512 // Remove last register operand because registers from register range
6513 // should be inserted first.
6514 if ((isGP64bit() && RegNo
== Mips::RA_64
) ||
6515 (!isGP64bit() && RegNo
== Mips::RA
)) {
6516 Regs
.push_back(RegNo
);
6518 unsigned TmpReg
= PrevReg
+ 1;
6519 while (TmpReg
<= RegNo
) {
6520 if ((((TmpReg
< Mips::S0
) || (TmpReg
> Mips::S7
)) && !isGP64bit()) ||
6521 (((TmpReg
< Mips::S0_64
) || (TmpReg
> Mips::S7_64
)) &&
6523 Error(E
, "invalid register operand");
6524 return MatchOperand_ParseFail
;
6528 Regs
.push_back(TmpReg
++);
6534 if ((PrevReg
== Mips::NoRegister
) &&
6535 ((isGP64bit() && (RegNo
!= Mips::S0_64
) && (RegNo
!= Mips::RA_64
)) ||
6536 (!isGP64bit() && (RegNo
!= Mips::S0
) && (RegNo
!= Mips::RA
)))) {
6537 Error(E
, "$16 or $31 expected");
6538 return MatchOperand_ParseFail
;
6539 } else if (!(((RegNo
== Mips::FP
|| RegNo
== Mips::RA
||
6540 (RegNo
>= Mips::S0
&& RegNo
<= Mips::S7
)) &&
6542 ((RegNo
== Mips::FP_64
|| RegNo
== Mips::RA_64
||
6543 (RegNo
>= Mips::S0_64
&& RegNo
<= Mips::S7_64
)) &&
6545 Error(E
, "invalid register operand");
6546 return MatchOperand_ParseFail
;
6547 } else if ((PrevReg
!= Mips::NoRegister
) && (RegNo
!= PrevReg
+ 1) &&
6548 ((RegNo
!= Mips::FP
&& RegNo
!= Mips::RA
&& !isGP64bit()) ||
6549 (RegNo
!= Mips::FP_64
&& RegNo
!= Mips::RA_64
&&
6551 Error(E
, "consecutive register numbers expected");
6552 return MatchOperand_ParseFail
;
6555 Regs
.push_back(RegNo
);
6558 if (Parser
.getTok().is(AsmToken::Minus
))
6561 if (!Parser
.getTok().isNot(AsmToken::Minus
) &&
6562 !Parser
.getTok().isNot(AsmToken::Comma
)) {
6563 Error(E
, "',' or '-' expected");
6564 return MatchOperand_ParseFail
;
6567 Lex(); // Consume comma or minus
6568 if (Parser
.getTok().isNot(AsmToken::Dollar
))
6574 SMLoc E
= Parser
.getTok().getLoc();
6575 Operands
.push_back(MipsOperand::CreateRegList(Regs
, S
, E
, *this));
6576 parseMemOperand(Operands
);
6577 return MatchOperand_Success
;
6580 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6582 /// ::= '(', register, ')'
6583 /// handle it before we iterate so we don't get tripped up by the lack of
6585 bool MipsAsmParser::parseParenSuffix(StringRef Name
, OperandVector
&Operands
) {
6586 MCAsmParser
&Parser
= getParser();
6587 if (getLexer().is(AsmToken::LParen
)) {
6589 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6591 if (parseOperand(Operands
, Name
)) {
6592 SMLoc Loc
= getLexer().getLoc();
6593 return Error(Loc
, "unexpected token in argument list");
6595 if (Parser
.getTok().isNot(AsmToken::RParen
)) {
6596 SMLoc Loc
= getLexer().getLoc();
6597 return Error(Loc
, "unexpected token, expected ')'");
6600 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6606 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6607 /// either one of these.
6608 /// ::= '[', register, ']'
6609 /// ::= '[', integer, ']'
6610 /// handle it before we iterate so we don't get tripped up by the lack of
6612 bool MipsAsmParser::parseBracketSuffix(StringRef Name
,
6613 OperandVector
&Operands
) {
6614 MCAsmParser
&Parser
= getParser();
6615 if (getLexer().is(AsmToken::LBrac
)) {
6617 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6619 if (parseOperand(Operands
, Name
)) {
6620 SMLoc Loc
= getLexer().getLoc();
6621 return Error(Loc
, "unexpected token in argument list");
6623 if (Parser
.getTok().isNot(AsmToken::RBrac
)) {
6624 SMLoc Loc
= getLexer().getLoc();
6625 return Error(Loc
, "unexpected token, expected ']'");
6628 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6634 static std::string
MipsMnemonicSpellCheck(StringRef S
, const FeatureBitset
&FBS
,
6635 unsigned VariantID
= 0);
6637 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
6638 SMLoc NameLoc
, OperandVector
&Operands
) {
6639 MCAsmParser
&Parser
= getParser();
6640 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6642 // We have reached first instruction, module directive are now forbidden.
6643 getTargetStreamer().forbidModuleDirective();
6645 // Check if we have valid mnemonic
6646 if (!mnemonicIsValid(Name
, 0)) {
6647 FeatureBitset FBS
= ComputeAvailableFeatures(getSTI().getFeatureBits());
6648 std::string Suggestion
= MipsMnemonicSpellCheck(Name
, FBS
);
6649 return Error(NameLoc
, "unknown instruction" + Suggestion
);
6651 // First operand in MCInst is instruction mnemonic.
6652 Operands
.push_back(MipsOperand::CreateToken(Name
, NameLoc
, *this));
6654 // Read the remaining operands.
6655 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6656 // Read the first operand.
6657 if (parseOperand(Operands
, Name
)) {
6658 SMLoc Loc
= getLexer().getLoc();
6659 return Error(Loc
, "unexpected token in argument list");
6661 if (getLexer().is(AsmToken::LBrac
) && parseBracketSuffix(Name
, Operands
))
6663 // AFAIK, parenthesis suffixes are never on the first operand
6665 while (getLexer().is(AsmToken::Comma
)) {
6666 Parser
.Lex(); // Eat the comma.
6667 // Parse and remember the operand.
6668 if (parseOperand(Operands
, Name
)) {
6669 SMLoc Loc
= getLexer().getLoc();
6670 return Error(Loc
, "unexpected token in argument list");
6672 // Parse bracket and parenthesis suffixes before we iterate
6673 if (getLexer().is(AsmToken::LBrac
)) {
6674 if (parseBracketSuffix(Name
, Operands
))
6676 } else if (getLexer().is(AsmToken::LParen
) &&
6677 parseParenSuffix(Name
, Operands
))
6681 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6682 SMLoc Loc
= getLexer().getLoc();
6683 return Error(Loc
, "unexpected token in argument list");
6685 Parser
.Lex(); // Consume the EndOfStatement.
6689 // FIXME: Given that these have the same name, these should both be
6690 // consistent on affecting the Parser.
6691 bool MipsAsmParser::reportParseError(Twine ErrorMsg
) {
6692 SMLoc Loc
= getLexer().getLoc();
6693 return Error(Loc
, ErrorMsg
);
6696 bool MipsAsmParser::reportParseError(SMLoc Loc
, Twine ErrorMsg
) {
6697 return Error(Loc
, ErrorMsg
);
6700 bool MipsAsmParser::parseSetNoAtDirective() {
6701 MCAsmParser
&Parser
= getParser();
6702 // Line should look like: ".set noat".
6704 // Set the $at register to $0.
6705 AssemblerOptions
.back()->setATRegIndex(0);
6707 Parser
.Lex(); // Eat "noat".
6709 // If this is not the end of the statement, report an error.
6710 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6711 reportParseError("unexpected token, expected end of statement");
6715 getTargetStreamer().emitDirectiveSetNoAt();
6716 Parser
.Lex(); // Consume the EndOfStatement.
6720 bool MipsAsmParser::parseSetAtDirective() {
6721 // Line can be: ".set at", which sets $at to $1
6722 // or ".set at=$reg", which sets $at to $reg.
6723 MCAsmParser
&Parser
= getParser();
6724 Parser
.Lex(); // Eat "at".
6726 if (getLexer().is(AsmToken::EndOfStatement
)) {
6727 // No register was specified, so we set $at to $1.
6728 AssemblerOptions
.back()->setATRegIndex(1);
6730 getTargetStreamer().emitDirectiveSetAt();
6731 Parser
.Lex(); // Consume the EndOfStatement.
6735 if (getLexer().isNot(AsmToken::Equal
)) {
6736 reportParseError("unexpected token, expected equals sign");
6739 Parser
.Lex(); // Eat "=".
6741 if (getLexer().isNot(AsmToken::Dollar
)) {
6742 if (getLexer().is(AsmToken::EndOfStatement
)) {
6743 reportParseError("no register specified");
6746 reportParseError("unexpected token, expected dollar sign '$'");
6750 Parser
.Lex(); // Eat "$".
6752 // Find out what "reg" is.
6754 const AsmToken
&Reg
= Parser
.getTok();
6755 if (Reg
.is(AsmToken::Identifier
)) {
6756 AtRegNo
= matchCPURegisterName(Reg
.getIdentifier());
6757 } else if (Reg
.is(AsmToken::Integer
)) {
6758 AtRegNo
= Reg
.getIntVal();
6760 reportParseError("unexpected token, expected identifier or integer");
6764 // Check if $reg is a valid register. If it is, set $at to $reg.
6765 if (!AssemblerOptions
.back()->setATRegIndex(AtRegNo
)) {
6766 reportParseError("invalid register");
6769 Parser
.Lex(); // Eat "reg".
6771 // If this is not the end of the statement, report an error.
6772 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6773 reportParseError("unexpected token, expected end of statement");
6777 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo
);
6779 Parser
.Lex(); // Consume the EndOfStatement.
6783 bool MipsAsmParser::parseSetReorderDirective() {
6784 MCAsmParser
&Parser
= getParser();
6786 // If this is not the end of the statement, report an error.
6787 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6788 reportParseError("unexpected token, expected end of statement");
6791 AssemblerOptions
.back()->setReorder();
6792 getTargetStreamer().emitDirectiveSetReorder();
6793 Parser
.Lex(); // Consume the EndOfStatement.
6797 bool MipsAsmParser::parseSetNoReorderDirective() {
6798 MCAsmParser
&Parser
= getParser();
6800 // If this is not the end of the statement, report an error.
6801 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6802 reportParseError("unexpected token, expected end of statement");
6805 AssemblerOptions
.back()->setNoReorder();
6806 getTargetStreamer().emitDirectiveSetNoReorder();
6807 Parser
.Lex(); // Consume the EndOfStatement.
6811 bool MipsAsmParser::parseSetMacroDirective() {
6812 MCAsmParser
&Parser
= getParser();
6814 // If this is not the end of the statement, report an error.
6815 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6816 reportParseError("unexpected token, expected end of statement");
6819 AssemblerOptions
.back()->setMacro();
6820 getTargetStreamer().emitDirectiveSetMacro();
6821 Parser
.Lex(); // Consume the EndOfStatement.
6825 bool MipsAsmParser::parseSetNoMacroDirective() {
6826 MCAsmParser
&Parser
= getParser();
6828 // If this is not the end of the statement, report an error.
6829 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6830 reportParseError("unexpected token, expected end of statement");
6833 if (AssemblerOptions
.back()->isReorder()) {
6834 reportParseError("`noreorder' must be set before `nomacro'");
6837 AssemblerOptions
.back()->setNoMacro();
6838 getTargetStreamer().emitDirectiveSetNoMacro();
6839 Parser
.Lex(); // Consume the EndOfStatement.
6843 bool MipsAsmParser::parseSetMsaDirective() {
6844 MCAsmParser
&Parser
= getParser();
6847 // If this is not the end of the statement, report an error.
6848 if (getLexer().isNot(AsmToken::EndOfStatement
))
6849 return reportParseError("unexpected token, expected end of statement");
6851 setFeatureBits(Mips::FeatureMSA
, "msa");
6852 getTargetStreamer().emitDirectiveSetMsa();
6856 bool MipsAsmParser::parseSetNoMsaDirective() {
6857 MCAsmParser
&Parser
= getParser();
6860 // If this is not the end of the statement, report an error.
6861 if (getLexer().isNot(AsmToken::EndOfStatement
))
6862 return reportParseError("unexpected token, expected end of statement");
6864 clearFeatureBits(Mips::FeatureMSA
, "msa");
6865 getTargetStreamer().emitDirectiveSetNoMsa();
6869 bool MipsAsmParser::parseSetNoDspDirective() {
6870 MCAsmParser
&Parser
= getParser();
6871 Parser
.Lex(); // Eat "nodsp".
6873 // If this is not the end of the statement, report an error.
6874 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6875 reportParseError("unexpected token, expected end of statement");
6879 clearFeatureBits(Mips::FeatureDSP
, "dsp");
6880 getTargetStreamer().emitDirectiveSetNoDsp();
6884 bool MipsAsmParser::parseSetMips16Directive() {
6885 MCAsmParser
&Parser
= getParser();
6886 Parser
.Lex(); // Eat "mips16".
6888 // If this is not the end of the statement, report an error.
6889 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6890 reportParseError("unexpected token, expected end of statement");
6894 setFeatureBits(Mips::FeatureMips16
, "mips16");
6895 getTargetStreamer().emitDirectiveSetMips16();
6896 Parser
.Lex(); // Consume the EndOfStatement.
6900 bool MipsAsmParser::parseSetNoMips16Directive() {
6901 MCAsmParser
&Parser
= getParser();
6902 Parser
.Lex(); // Eat "nomips16".
6904 // If this is not the end of the statement, report an error.
6905 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6906 reportParseError("unexpected token, expected end of statement");
6910 clearFeatureBits(Mips::FeatureMips16
, "mips16");
6911 getTargetStreamer().emitDirectiveSetNoMips16();
6912 Parser
.Lex(); // Consume the EndOfStatement.
6916 bool MipsAsmParser::parseSetFpDirective() {
6917 MCAsmParser
&Parser
= getParser();
6918 MipsABIFlagsSection::FpABIKind FpAbiVal
;
6919 // Line can be: .set fp=32
6922 Parser
.Lex(); // Eat fp token
6923 AsmToken Tok
= Parser
.getTok();
6924 if (Tok
.isNot(AsmToken::Equal
)) {
6925 reportParseError("unexpected token, expected equals sign '='");
6928 Parser
.Lex(); // Eat '=' token.
6929 Tok
= Parser
.getTok();
6931 if (!parseFpABIValue(FpAbiVal
, ".set"))
6934 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6935 reportParseError("unexpected token, expected end of statement");
6938 getTargetStreamer().emitDirectiveSetFp(FpAbiVal
);
6939 Parser
.Lex(); // Consume the EndOfStatement.
6943 bool MipsAsmParser::parseSetOddSPRegDirective() {
6944 MCAsmParser
&Parser
= getParser();
6946 Parser
.Lex(); // Eat "oddspreg".
6947 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6948 reportParseError("unexpected token, expected end of statement");
6952 clearFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
6953 getTargetStreamer().emitDirectiveSetOddSPReg();
6957 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6958 MCAsmParser
&Parser
= getParser();
6960 Parser
.Lex(); // Eat "nooddspreg".
6961 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6962 reportParseError("unexpected token, expected end of statement");
6966 setFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
6967 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6971 bool MipsAsmParser::parseSetMtDirective() {
6972 MCAsmParser
&Parser
= getParser();
6973 Parser
.Lex(); // Eat "mt".
6975 // If this is not the end of the statement, report an error.
6976 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6977 reportParseError("unexpected token, expected end of statement");
6981 setFeatureBits(Mips::FeatureMT
, "mt");
6982 getTargetStreamer().emitDirectiveSetMt();
6983 Parser
.Lex(); // Consume the EndOfStatement.
6987 bool MipsAsmParser::parseSetNoMtDirective() {
6988 MCAsmParser
&Parser
= getParser();
6989 Parser
.Lex(); // Eat "nomt".
6991 // If this is not the end of the statement, report an error.
6992 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6993 reportParseError("unexpected token, expected end of statement");
6997 clearFeatureBits(Mips::FeatureMT
, "mt");
6999 getTargetStreamer().emitDirectiveSetNoMt();
7000 Parser
.Lex(); // Consume the EndOfStatement.
7004 bool MipsAsmParser::parseSetNoCRCDirective() {
7005 MCAsmParser
&Parser
= getParser();
7006 Parser
.Lex(); // Eat "nocrc".
7008 // If this is not the end of the statement, report an error.
7009 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7010 reportParseError("unexpected token, expected end of statement");
7014 clearFeatureBits(Mips::FeatureCRC
, "crc");
7016 getTargetStreamer().emitDirectiveSetNoCRC();
7017 Parser
.Lex(); // Consume the EndOfStatement.
7021 bool MipsAsmParser::parseSetNoVirtDirective() {
7022 MCAsmParser
&Parser
= getParser();
7023 Parser
.Lex(); // Eat "novirt".
7025 // If this is not the end of the statement, report an error.
7026 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7027 reportParseError("unexpected token, expected end of statement");
7031 clearFeatureBits(Mips::FeatureVirt
, "virt");
7033 getTargetStreamer().emitDirectiveSetNoVirt();
7034 Parser
.Lex(); // Consume the EndOfStatement.
7038 bool MipsAsmParser::parseSetNoGINVDirective() {
7039 MCAsmParser
&Parser
= getParser();
7040 Parser
.Lex(); // Eat "noginv".
7042 // If this is not the end of the statement, report an error.
7043 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7044 reportParseError("unexpected token, expected end of statement");
7048 clearFeatureBits(Mips::FeatureGINV
, "ginv");
7050 getTargetStreamer().emitDirectiveSetNoGINV();
7051 Parser
.Lex(); // Consume the EndOfStatement.
7055 bool MipsAsmParser::parseSetPopDirective() {
7056 MCAsmParser
&Parser
= getParser();
7057 SMLoc Loc
= getLexer().getLoc();
7060 if (getLexer().isNot(AsmToken::EndOfStatement
))
7061 return reportParseError("unexpected token, expected end of statement");
7063 // Always keep an element on the options "stack" to prevent the user
7064 // from changing the initial options. This is how we remember them.
7065 if (AssemblerOptions
.size() == 2)
7066 return reportParseError(Loc
, ".set pop with no .set push");
7068 MCSubtargetInfo
&STI
= copySTI();
7069 AssemblerOptions
.pop_back();
7070 setAvailableFeatures(
7071 ComputeAvailableFeatures(AssemblerOptions
.back()->getFeatures()));
7072 STI
.setFeatureBits(AssemblerOptions
.back()->getFeatures());
7074 getTargetStreamer().emitDirectiveSetPop();
7078 bool MipsAsmParser::parseSetPushDirective() {
7079 MCAsmParser
&Parser
= getParser();
7081 if (getLexer().isNot(AsmToken::EndOfStatement
))
7082 return reportParseError("unexpected token, expected end of statement");
7084 // Create a copy of the current assembler options environment and push it.
7085 AssemblerOptions
.push_back(
7086 std::make_unique
<MipsAssemblerOptions
>(AssemblerOptions
.back().get()));
7088 getTargetStreamer().emitDirectiveSetPush();
7092 bool MipsAsmParser::parseSetSoftFloatDirective() {
7093 MCAsmParser
&Parser
= getParser();
7095 if (getLexer().isNot(AsmToken::EndOfStatement
))
7096 return reportParseError("unexpected token, expected end of statement");
7098 setFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7099 getTargetStreamer().emitDirectiveSetSoftFloat();
7103 bool MipsAsmParser::parseSetHardFloatDirective() {
7104 MCAsmParser
&Parser
= getParser();
7106 if (getLexer().isNot(AsmToken::EndOfStatement
))
7107 return reportParseError("unexpected token, expected end of statement");
7109 clearFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7110 getTargetStreamer().emitDirectiveSetHardFloat();
7114 bool MipsAsmParser::parseSetAssignment() {
7116 MCAsmParser
&Parser
= getParser();
7118 if (Parser
.parseIdentifier(Name
))
7119 return reportParseError("expected identifier after .set");
7121 if (getLexer().isNot(AsmToken::Comma
))
7122 return reportParseError("unexpected token, expected comma");
7125 if (getLexer().is(AsmToken::Dollar
) &&
7126 getLexer().peekTok().is(AsmToken::Integer
)) {
7127 // Parse assignment of a numeric register:
7129 Parser
.Lex(); // Eat $.
7130 RegisterSets
[Name
] = Parser
.getTok();
7131 Parser
.Lex(); // Eat identifier.
7132 getContext().getOrCreateSymbol(Name
);
7137 const MCExpr
*Value
;
7138 if (MCParserUtils::parseAssignmentExpression(Name
, /* allow_redef */ true,
7139 Parser
, Sym
, Value
))
7141 Sym
->setVariableValue(Value
);
7146 bool MipsAsmParser::parseSetMips0Directive() {
7147 MCAsmParser
&Parser
= getParser();
7149 if (getLexer().isNot(AsmToken::EndOfStatement
))
7150 return reportParseError("unexpected token, expected end of statement");
7152 // Reset assembler options to their initial values.
7153 MCSubtargetInfo
&STI
= copySTI();
7154 setAvailableFeatures(
7155 ComputeAvailableFeatures(AssemblerOptions
.front()->getFeatures()));
7156 STI
.setFeatureBits(AssemblerOptions
.front()->getFeatures());
7157 AssemblerOptions
.back()->setFeatures(AssemblerOptions
.front()->getFeatures());
7159 getTargetStreamer().emitDirectiveSetMips0();
7163 bool MipsAsmParser::parseSetArchDirective() {
7164 MCAsmParser
&Parser
= getParser();
7166 if (getLexer().isNot(AsmToken::Equal
))
7167 return reportParseError("unexpected token, expected equals sign");
7171 if (Parser
.parseIdentifier(Arch
))
7172 return reportParseError("expected arch identifier");
7174 StringRef ArchFeatureName
=
7175 StringSwitch
<StringRef
>(Arch
)
7176 .Case("mips1", "mips1")
7177 .Case("mips2", "mips2")
7178 .Case("mips3", "mips3")
7179 .Case("mips4", "mips4")
7180 .Case("mips5", "mips5")
7181 .Case("mips32", "mips32")
7182 .Case("mips32r2", "mips32r2")
7183 .Case("mips32r3", "mips32r3")
7184 .Case("mips32r5", "mips32r5")
7185 .Case("mips32r6", "mips32r6")
7186 .Case("mips64", "mips64")
7187 .Case("mips64r2", "mips64r2")
7188 .Case("mips64r3", "mips64r3")
7189 .Case("mips64r5", "mips64r5")
7190 .Case("mips64r6", "mips64r6")
7191 .Case("octeon", "cnmips")
7192 .Case("r4000", "mips3") // This is an implementation of Mips3.
7195 if (ArchFeatureName
.empty())
7196 return reportParseError("unsupported architecture");
7198 if (ArchFeatureName
== "mips64r6" && inMicroMipsMode())
7199 return reportParseError("mips64r6 does not support microMIPS");
7201 selectArch(ArchFeatureName
);
7202 getTargetStreamer().emitDirectiveSetArch(Arch
);
7206 bool MipsAsmParser::parseSetFeature(uint64_t Feature
) {
7207 MCAsmParser
&Parser
= getParser();
7209 if (getLexer().isNot(AsmToken::EndOfStatement
))
7210 return reportParseError("unexpected token, expected end of statement");
7214 llvm_unreachable("Unimplemented feature");
7215 case Mips::FeatureDSP
:
7216 setFeatureBits(Mips::FeatureDSP
, "dsp");
7217 getTargetStreamer().emitDirectiveSetDsp();
7219 case Mips::FeatureDSPR2
:
7220 setFeatureBits(Mips::FeatureDSPR2
, "dspr2");
7221 getTargetStreamer().emitDirectiveSetDspr2();
7223 case Mips::FeatureMicroMips
:
7224 setFeatureBits(Mips::FeatureMicroMips
, "micromips");
7225 getTargetStreamer().emitDirectiveSetMicroMips();
7227 case Mips::FeatureMips1
:
7228 selectArch("mips1");
7229 getTargetStreamer().emitDirectiveSetMips1();
7231 case Mips::FeatureMips2
:
7232 selectArch("mips2");
7233 getTargetStreamer().emitDirectiveSetMips2();
7235 case Mips::FeatureMips3
:
7236 selectArch("mips3");
7237 getTargetStreamer().emitDirectiveSetMips3();
7239 case Mips::FeatureMips4
:
7240 selectArch("mips4");
7241 getTargetStreamer().emitDirectiveSetMips4();
7243 case Mips::FeatureMips5
:
7244 selectArch("mips5");
7245 getTargetStreamer().emitDirectiveSetMips5();
7247 case Mips::FeatureMips32
:
7248 selectArch("mips32");
7249 getTargetStreamer().emitDirectiveSetMips32();
7251 case Mips::FeatureMips32r2
:
7252 selectArch("mips32r2");
7253 getTargetStreamer().emitDirectiveSetMips32R2();
7255 case Mips::FeatureMips32r3
:
7256 selectArch("mips32r3");
7257 getTargetStreamer().emitDirectiveSetMips32R3();
7259 case Mips::FeatureMips32r5
:
7260 selectArch("mips32r5");
7261 getTargetStreamer().emitDirectiveSetMips32R5();
7263 case Mips::FeatureMips32r6
:
7264 selectArch("mips32r6");
7265 getTargetStreamer().emitDirectiveSetMips32R6();
7267 case Mips::FeatureMips64
:
7268 selectArch("mips64");
7269 getTargetStreamer().emitDirectiveSetMips64();
7271 case Mips::FeatureMips64r2
:
7272 selectArch("mips64r2");
7273 getTargetStreamer().emitDirectiveSetMips64R2();
7275 case Mips::FeatureMips64r3
:
7276 selectArch("mips64r3");
7277 getTargetStreamer().emitDirectiveSetMips64R3();
7279 case Mips::FeatureMips64r5
:
7280 selectArch("mips64r5");
7281 getTargetStreamer().emitDirectiveSetMips64R5();
7283 case Mips::FeatureMips64r6
:
7284 selectArch("mips64r6");
7285 getTargetStreamer().emitDirectiveSetMips64R6();
7287 case Mips::FeatureCRC
:
7288 setFeatureBits(Mips::FeatureCRC
, "crc");
7289 getTargetStreamer().emitDirectiveSetCRC();
7291 case Mips::FeatureVirt
:
7292 setFeatureBits(Mips::FeatureVirt
, "virt");
7293 getTargetStreamer().emitDirectiveSetVirt();
7295 case Mips::FeatureGINV
:
7296 setFeatureBits(Mips::FeatureGINV
, "ginv");
7297 getTargetStreamer().emitDirectiveSetGINV();
7303 bool MipsAsmParser::eatComma(StringRef ErrorStr
) {
7304 MCAsmParser
&Parser
= getParser();
7305 if (getLexer().isNot(AsmToken::Comma
)) {
7306 SMLoc Loc
= getLexer().getLoc();
7307 return Error(Loc
, ErrorStr
);
7310 Parser
.Lex(); // Eat the comma.
7314 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7315 // In this class, it is only used for .cprestore.
7316 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7317 // MipsTargetELFStreamer and MipsAsmParser.
7318 bool MipsAsmParser::isPicAndNotNxxAbi() {
7319 return inPicMode() && !(isABI_N32() || isABI_N64());
7322 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc
) {
7323 if (AssemblerOptions
.back()->isReorder())
7324 Warning(Loc
, ".cpload should be inside a noreorder section");
7326 if (inMips16Mode()) {
7327 reportParseError(".cpload is not supported in Mips16 mode");
7331 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Reg
;
7332 OperandMatchResultTy ResTy
= parseAnyRegister(Reg
);
7333 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
7334 reportParseError("expected register containing function address");
7338 MipsOperand
&RegOpnd
= static_cast<MipsOperand
&>(*Reg
[0]);
7339 if (!RegOpnd
.isGPRAsmReg()) {
7340 reportParseError(RegOpnd
.getStartLoc(), "invalid register");
7344 // If this is not the end of the statement, report an error.
7345 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7346 reportParseError("unexpected token, expected end of statement");
7350 getTargetStreamer().emitDirectiveCpLoad(RegOpnd
.getGPR32Reg());
7354 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc
) {
7355 if (!isABI_N32() && !isABI_N64()) {
7356 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7360 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Reg
;
7361 OperandMatchResultTy ResTy
= parseAnyRegister(Reg
);
7362 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
7363 reportParseError("expected register containing global pointer");
7367 MipsOperand
&RegOpnd
= static_cast<MipsOperand
&>(*Reg
[0]);
7368 if (!RegOpnd
.isGPRAsmReg()) {
7369 reportParseError(RegOpnd
.getStartLoc(), "invalid register");
7373 // If this is not the end of the statement, report an error.
7374 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7375 reportParseError("unexpected token, expected end of statement");
7378 getParser().Lex(); // Consume the EndOfStatement.
7380 unsigned NewReg
= RegOpnd
.getGPR32Reg();
7384 getTargetStreamer().emitDirectiveCpLocal(NewReg
);
7388 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc
) {
7389 MCAsmParser
&Parser
= getParser();
7391 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7392 // is used in non-PIC mode.
7394 if (inMips16Mode()) {
7395 reportParseError(".cprestore is not supported in Mips16 mode");
7399 // Get the stack offset value.
7400 const MCExpr
*StackOffset
;
7401 int64_t StackOffsetVal
;
7402 if (Parser
.parseExpression(StackOffset
)) {
7403 reportParseError("expected stack offset value");
7407 if (!StackOffset
->evaluateAsAbsolute(StackOffsetVal
)) {
7408 reportParseError("stack offset is not an absolute expression");
7412 if (StackOffsetVal
< 0) {
7413 Warning(Loc
, ".cprestore with negative stack offset has no effect");
7414 IsCpRestoreSet
= false;
7416 IsCpRestoreSet
= true;
7417 CpRestoreOffset
= StackOffsetVal
;
7420 // If this is not the end of the statement, report an error.
7421 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7422 reportParseError("unexpected token, expected end of statement");
7426 if (!getTargetStreamer().emitDirectiveCpRestore(
7427 CpRestoreOffset
, [&]() { return getATReg(Loc
); }, Loc
, STI
))
7429 Parser
.Lex(); // Consume the EndOfStatement.
7433 bool MipsAsmParser::parseDirectiveCPSetup() {
7434 MCAsmParser
&Parser
= getParser();
7437 bool SaveIsReg
= true;
7439 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> TmpReg
;
7440 OperandMatchResultTy ResTy
= parseAnyRegister(TmpReg
);
7441 if (ResTy
== MatchOperand_NoMatch
) {
7442 reportParseError("expected register containing function address");
7446 MipsOperand
&FuncRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
7447 if (!FuncRegOpnd
.isGPRAsmReg()) {
7448 reportParseError(FuncRegOpnd
.getStartLoc(), "invalid register");
7452 FuncReg
= FuncRegOpnd
.getGPR32Reg();
7455 if (!eatComma("unexpected token, expected comma"))
7458 ResTy
= parseAnyRegister(TmpReg
);
7459 if (ResTy
== MatchOperand_NoMatch
) {
7460 const MCExpr
*OffsetExpr
;
7462 SMLoc ExprLoc
= getLexer().getLoc();
7464 if (Parser
.parseExpression(OffsetExpr
) ||
7465 !OffsetExpr
->evaluateAsAbsolute(OffsetVal
)) {
7466 reportParseError(ExprLoc
, "expected save register or stack offset");
7473 MipsOperand
&SaveOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
7474 if (!SaveOpnd
.isGPRAsmReg()) {
7475 reportParseError(SaveOpnd
.getStartLoc(), "invalid register");
7478 Save
= SaveOpnd
.getGPR32Reg();
7481 if (!eatComma("unexpected token, expected comma"))
7485 if (Parser
.parseExpression(Expr
)) {
7486 reportParseError("expected expression");
7490 if (Expr
->getKind() != MCExpr::SymbolRef
) {
7491 reportParseError("expected symbol");
7494 const MCSymbolRefExpr
*Ref
= static_cast<const MCSymbolRefExpr
*>(Expr
);
7496 CpSaveLocation
= Save
;
7497 CpSaveLocationIsRegister
= SaveIsReg
;
7499 getTargetStreamer().emitDirectiveCpsetup(FuncReg
, Save
, Ref
->getSymbol(),
7504 bool MipsAsmParser::parseDirectiveCPReturn() {
7505 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation
,
7506 CpSaveLocationIsRegister
);
7510 bool MipsAsmParser::parseDirectiveNaN() {
7511 MCAsmParser
&Parser
= getParser();
7512 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7513 const AsmToken
&Tok
= Parser
.getTok();
7515 if (Tok
.getString() == "2008") {
7517 getTargetStreamer().emitDirectiveNaN2008();
7519 } else if (Tok
.getString() == "legacy") {
7521 getTargetStreamer().emitDirectiveNaNLegacy();
7525 // If we don't recognize the option passed to the .nan
7526 // directive (e.g. no option or unknown option), emit an error.
7527 reportParseError("invalid option in .nan directive");
7531 bool MipsAsmParser::parseDirectiveSet() {
7532 const AsmToken
&Tok
= getParser().getTok();
7533 StringRef IdVal
= Tok
.getString();
7534 SMLoc Loc
= Tok
.getLoc();
7536 if (IdVal
== "noat")
7537 return parseSetNoAtDirective();
7539 return parseSetAtDirective();
7540 if (IdVal
== "arch")
7541 return parseSetArchDirective();
7542 if (IdVal
== "bopt") {
7543 Warning(Loc
, "'bopt' feature is unsupported");
7547 if (IdVal
== "nobopt") {
7548 // We're already running in nobopt mode, so nothing to do.
7553 return parseSetFpDirective();
7554 if (IdVal
== "oddspreg")
7555 return parseSetOddSPRegDirective();
7556 if (IdVal
== "nooddspreg")
7557 return parseSetNoOddSPRegDirective();
7559 return parseSetPopDirective();
7560 if (IdVal
== "push")
7561 return parseSetPushDirective();
7562 if (IdVal
== "reorder")
7563 return parseSetReorderDirective();
7564 if (IdVal
== "noreorder")
7565 return parseSetNoReorderDirective();
7566 if (IdVal
== "macro")
7567 return parseSetMacroDirective();
7568 if (IdVal
== "nomacro")
7569 return parseSetNoMacroDirective();
7570 if (IdVal
== "mips16")
7571 return parseSetMips16Directive();
7572 if (IdVal
== "nomips16")
7573 return parseSetNoMips16Directive();
7574 if (IdVal
== "nomicromips") {
7575 clearFeatureBits(Mips::FeatureMicroMips
, "micromips");
7576 getTargetStreamer().emitDirectiveSetNoMicroMips();
7577 getParser().eatToEndOfStatement();
7580 if (IdVal
== "micromips") {
7581 if (hasMips64r6()) {
7582 Error(Loc
, ".set micromips directive is not supported with MIPS64R6");
7585 return parseSetFeature(Mips::FeatureMicroMips
);
7587 if (IdVal
== "mips0")
7588 return parseSetMips0Directive();
7589 if (IdVal
== "mips1")
7590 return parseSetFeature(Mips::FeatureMips1
);
7591 if (IdVal
== "mips2")
7592 return parseSetFeature(Mips::FeatureMips2
);
7593 if (IdVal
== "mips3")
7594 return parseSetFeature(Mips::FeatureMips3
);
7595 if (IdVal
== "mips4")
7596 return parseSetFeature(Mips::FeatureMips4
);
7597 if (IdVal
== "mips5")
7598 return parseSetFeature(Mips::FeatureMips5
);
7599 if (IdVal
== "mips32")
7600 return parseSetFeature(Mips::FeatureMips32
);
7601 if (IdVal
== "mips32r2")
7602 return parseSetFeature(Mips::FeatureMips32r2
);
7603 if (IdVal
== "mips32r3")
7604 return parseSetFeature(Mips::FeatureMips32r3
);
7605 if (IdVal
== "mips32r5")
7606 return parseSetFeature(Mips::FeatureMips32r5
);
7607 if (IdVal
== "mips32r6")
7608 return parseSetFeature(Mips::FeatureMips32r6
);
7609 if (IdVal
== "mips64")
7610 return parseSetFeature(Mips::FeatureMips64
);
7611 if (IdVal
== "mips64r2")
7612 return parseSetFeature(Mips::FeatureMips64r2
);
7613 if (IdVal
== "mips64r3")
7614 return parseSetFeature(Mips::FeatureMips64r3
);
7615 if (IdVal
== "mips64r5")
7616 return parseSetFeature(Mips::FeatureMips64r5
);
7617 if (IdVal
== "mips64r6") {
7618 if (inMicroMipsMode()) {
7619 Error(Loc
, "MIPS64R6 is not supported with microMIPS");
7622 return parseSetFeature(Mips::FeatureMips64r6
);
7625 return parseSetFeature(Mips::FeatureDSP
);
7626 if (IdVal
== "dspr2")
7627 return parseSetFeature(Mips::FeatureDSPR2
);
7628 if (IdVal
== "nodsp")
7629 return parseSetNoDspDirective();
7631 return parseSetMsaDirective();
7632 if (IdVal
== "nomsa")
7633 return parseSetNoMsaDirective();
7635 return parseSetMtDirective();
7636 if (IdVal
== "nomt")
7637 return parseSetNoMtDirective();
7638 if (IdVal
== "softfloat")
7639 return parseSetSoftFloatDirective();
7640 if (IdVal
== "hardfloat")
7641 return parseSetHardFloatDirective();
7643 return parseSetFeature(Mips::FeatureCRC
);
7644 if (IdVal
== "nocrc")
7645 return parseSetNoCRCDirective();
7646 if (IdVal
== "virt")
7647 return parseSetFeature(Mips::FeatureVirt
);
7648 if (IdVal
== "novirt")
7649 return parseSetNoVirtDirective();
7650 if (IdVal
== "ginv")
7651 return parseSetFeature(Mips::FeatureGINV
);
7652 if (IdVal
== "noginv")
7653 return parseSetNoGINVDirective();
7655 // It is just an identifier, look for an assignment.
7656 return parseSetAssignment();
7659 /// parseDirectiveGpWord
7660 /// ::= .gpword local_sym
7661 bool MipsAsmParser::parseDirectiveGpWord() {
7662 MCAsmParser
&Parser
= getParser();
7663 const MCExpr
*Value
;
7664 // EmitGPRel32Value requires an expression, so we are using base class
7665 // method to evaluate the expression.
7666 if (getParser().parseExpression(Value
))
7668 getParser().getStreamer().EmitGPRel32Value(Value
);
7670 if (getLexer().isNot(AsmToken::EndOfStatement
))
7671 return Error(getLexer().getLoc(),
7672 "unexpected token, expected end of statement");
7673 Parser
.Lex(); // Eat EndOfStatement token.
7677 /// parseDirectiveGpDWord
7678 /// ::= .gpdword local_sym
7679 bool MipsAsmParser::parseDirectiveGpDWord() {
7680 MCAsmParser
&Parser
= getParser();
7681 const MCExpr
*Value
;
7682 // EmitGPRel64Value requires an expression, so we are using base class
7683 // method to evaluate the expression.
7684 if (getParser().parseExpression(Value
))
7686 getParser().getStreamer().EmitGPRel64Value(Value
);
7688 if (getLexer().isNot(AsmToken::EndOfStatement
))
7689 return Error(getLexer().getLoc(),
7690 "unexpected token, expected end of statement");
7691 Parser
.Lex(); // Eat EndOfStatement token.
7695 /// parseDirectiveDtpRelWord
7696 /// ::= .dtprelword tls_sym
7697 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7698 MCAsmParser
&Parser
= getParser();
7699 const MCExpr
*Value
;
7700 // EmitDTPRel32Value requires an expression, so we are using base class
7701 // method to evaluate the expression.
7702 if (getParser().parseExpression(Value
))
7704 getParser().getStreamer().EmitDTPRel32Value(Value
);
7706 if (getLexer().isNot(AsmToken::EndOfStatement
))
7707 return Error(getLexer().getLoc(),
7708 "unexpected token, expected end of statement");
7709 Parser
.Lex(); // Eat EndOfStatement token.
7713 /// parseDirectiveDtpRelDWord
7714 /// ::= .dtpreldword tls_sym
7715 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7716 MCAsmParser
&Parser
= getParser();
7717 const MCExpr
*Value
;
7718 // EmitDTPRel64Value requires an expression, so we are using base class
7719 // method to evaluate the expression.
7720 if (getParser().parseExpression(Value
))
7722 getParser().getStreamer().EmitDTPRel64Value(Value
);
7724 if (getLexer().isNot(AsmToken::EndOfStatement
))
7725 return Error(getLexer().getLoc(),
7726 "unexpected token, expected end of statement");
7727 Parser
.Lex(); // Eat EndOfStatement token.
7731 /// parseDirectiveTpRelWord
7732 /// ::= .tprelword tls_sym
7733 bool MipsAsmParser::parseDirectiveTpRelWord() {
7734 MCAsmParser
&Parser
= getParser();
7735 const MCExpr
*Value
;
7736 // EmitTPRel32Value requires an expression, so we are using base class
7737 // method to evaluate the expression.
7738 if (getParser().parseExpression(Value
))
7740 getParser().getStreamer().EmitTPRel32Value(Value
);
7742 if (getLexer().isNot(AsmToken::EndOfStatement
))
7743 return Error(getLexer().getLoc(),
7744 "unexpected token, expected end of statement");
7745 Parser
.Lex(); // Eat EndOfStatement token.
7749 /// parseDirectiveTpRelDWord
7750 /// ::= .tpreldword tls_sym
7751 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7752 MCAsmParser
&Parser
= getParser();
7753 const MCExpr
*Value
;
7754 // EmitTPRel64Value requires an expression, so we are using base class
7755 // method to evaluate the expression.
7756 if (getParser().parseExpression(Value
))
7758 getParser().getStreamer().EmitTPRel64Value(Value
);
7760 if (getLexer().isNot(AsmToken::EndOfStatement
))
7761 return Error(getLexer().getLoc(),
7762 "unexpected token, expected end of statement");
7763 Parser
.Lex(); // Eat EndOfStatement token.
7767 bool MipsAsmParser::parseDirectiveOption() {
7768 MCAsmParser
&Parser
= getParser();
7769 // Get the option token.
7770 AsmToken Tok
= Parser
.getTok();
7771 // At the moment only identifiers are supported.
7772 if (Tok
.isNot(AsmToken::Identifier
)) {
7773 return Error(Parser
.getTok().getLoc(),
7774 "unexpected token, expected identifier");
7777 StringRef Option
= Tok
.getIdentifier();
7779 if (Option
== "pic0") {
7780 // MipsAsmParser needs to know if the current PIC mode changes.
7781 IsPicEnabled
= false;
7783 getTargetStreamer().emitDirectiveOptionPic0();
7785 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
7786 return Error(Parser
.getTok().getLoc(),
7787 "unexpected token, expected end of statement");
7792 if (Option
== "pic2") {
7793 // MipsAsmParser needs to know if the current PIC mode changes.
7794 IsPicEnabled
= true;
7796 getTargetStreamer().emitDirectiveOptionPic2();
7798 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
7799 return Error(Parser
.getTok().getLoc(),
7800 "unexpected token, expected end of statement");
7806 Warning(Parser
.getTok().getLoc(),
7807 "unknown option, expected 'pic0' or 'pic2'");
7808 Parser
.eatToEndOfStatement();
7812 /// parseInsnDirective
7814 bool MipsAsmParser::parseInsnDirective() {
7815 // If this is not the end of the statement, report an error.
7816 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7817 reportParseError("unexpected token, expected end of statement");
7821 // The actual label marking happens in
7822 // MipsELFStreamer::createPendingLabelRelocs().
7823 getTargetStreamer().emitDirectiveInsn();
7825 getParser().Lex(); // Eat EndOfStatement token.
7829 /// parseRSectionDirective
7831 bool MipsAsmParser::parseRSectionDirective(StringRef Section
) {
7832 // If this is not the end of the statement, report an error.
7833 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7834 reportParseError("unexpected token, expected end of statement");
7838 MCSection
*ELFSection
= getContext().getELFSection(
7839 Section
, ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
7840 getParser().getStreamer().SwitchSection(ELFSection
);
7842 getParser().Lex(); // Eat EndOfStatement token.
7846 /// parseSSectionDirective
7849 bool MipsAsmParser::parseSSectionDirective(StringRef Section
, unsigned Type
) {
7850 // If this is not the end of the statement, report an error.
7851 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7852 reportParseError("unexpected token, expected end of statement");
7856 MCSection
*ELFSection
= getContext().getELFSection(
7857 Section
, Type
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
| ELF::SHF_MIPS_GPREL
);
7858 getParser().getStreamer().SwitchSection(ELFSection
);
7860 getParser().Lex(); // Eat EndOfStatement token.
7864 /// parseDirectiveModule
7865 /// ::= .module oddspreg
7866 /// ::= .module nooddspreg
7867 /// ::= .module fp=value
7868 /// ::= .module softfloat
7869 /// ::= .module hardfloat
7872 /// ::= .module nocrc
7873 /// ::= .module virt
7874 /// ::= .module novirt
7875 /// ::= .module ginv
7876 /// ::= .module noginv
7877 bool MipsAsmParser::parseDirectiveModule() {
7878 MCAsmParser
&Parser
= getParser();
7879 MCAsmLexer
&Lexer
= getLexer();
7880 SMLoc L
= Lexer
.getLoc();
7882 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7883 // TODO : get a better message.
7884 reportParseError(".module directive must appear before any code");
7889 if (Parser
.parseIdentifier(Option
)) {
7890 reportParseError("expected .module option identifier");
7894 if (Option
== "oddspreg") {
7895 clearModuleFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
7897 // Synchronize the abiflags information with the FeatureBits information we
7899 getTargetStreamer().updateABIInfo(*this);
7901 // If printing assembly, use the recently updated abiflags information.
7902 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7903 // emitted at the end).
7904 getTargetStreamer().emitDirectiveModuleOddSPReg();
7906 // If this is not the end of the statement, report an error.
7907 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7908 reportParseError("unexpected token, expected end of statement");
7912 return false; // parseDirectiveModule has finished successfully.
7913 } else if (Option
== "nooddspreg") {
7915 return Error(L
, "'.module nooddspreg' requires the O32 ABI");
7918 setModuleFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
7920 // Synchronize the abiflags information with the FeatureBits information we
7922 getTargetStreamer().updateABIInfo(*this);
7924 // If printing assembly, use the recently updated abiflags information.
7925 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7926 // emitted at the end).
7927 getTargetStreamer().emitDirectiveModuleOddSPReg();
7929 // If this is not the end of the statement, report an error.
7930 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7931 reportParseError("unexpected token, expected end of statement");
7935 return false; // parseDirectiveModule has finished successfully.
7936 } else if (Option
== "fp") {
7937 return parseDirectiveModuleFP();
7938 } else if (Option
== "softfloat") {
7939 setModuleFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7941 // Synchronize the ABI Flags information with the FeatureBits information we
7943 getTargetStreamer().updateABIInfo(*this);
7945 // If printing assembly, use the recently updated ABI Flags information.
7946 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7948 getTargetStreamer().emitDirectiveModuleSoftFloat();
7950 // If this is not the end of the statement, report an error.
7951 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7952 reportParseError("unexpected token, expected end of statement");
7956 return false; // parseDirectiveModule has finished successfully.
7957 } else if (Option
== "hardfloat") {
7958 clearModuleFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7960 // Synchronize the ABI Flags information with the FeatureBits information we
7962 getTargetStreamer().updateABIInfo(*this);
7964 // If printing assembly, use the recently updated ABI Flags information.
7965 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7967 getTargetStreamer().emitDirectiveModuleHardFloat();
7969 // If this is not the end of the statement, report an error.
7970 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7971 reportParseError("unexpected token, expected end of statement");
7975 return false; // parseDirectiveModule has finished successfully.
7976 } else if (Option
== "mt") {
7977 setModuleFeatureBits(Mips::FeatureMT
, "mt");
7979 // Synchronize the ABI Flags information with the FeatureBits information we
7981 getTargetStreamer().updateABIInfo(*this);
7983 // If printing assembly, use the recently updated ABI Flags information.
7984 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7986 getTargetStreamer().emitDirectiveModuleMT();
7988 // If this is not the end of the statement, report an error.
7989 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7990 reportParseError("unexpected token, expected end of statement");
7994 return false; // parseDirectiveModule has finished successfully.
7995 } else if (Option
== "crc") {
7996 setModuleFeatureBits(Mips::FeatureCRC
, "crc");
7998 // Synchronize the ABI Flags information with the FeatureBits information we
8000 getTargetStreamer().updateABIInfo(*this);
8002 // If printing assembly, use the recently updated ABI Flags information.
8003 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8005 getTargetStreamer().emitDirectiveModuleCRC();
8007 // If this is not the end of the statement, report an error.
8008 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8009 reportParseError("unexpected token, expected end of statement");
8013 return false; // parseDirectiveModule has finished successfully.
8014 } else if (Option
== "nocrc") {
8015 clearModuleFeatureBits(Mips::FeatureCRC
, "crc");
8017 // Synchronize the ABI Flags information with the FeatureBits information we
8019 getTargetStreamer().updateABIInfo(*this);
8021 // If printing assembly, use the recently updated ABI Flags information.
8022 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8024 getTargetStreamer().emitDirectiveModuleNoCRC();
8026 // If this is not the end of the statement, report an error.
8027 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8028 reportParseError("unexpected token, expected end of statement");
8032 return false; // parseDirectiveModule has finished successfully.
8033 } else if (Option
== "virt") {
8034 setModuleFeatureBits(Mips::FeatureVirt
, "virt");
8036 // Synchronize the ABI Flags information with the FeatureBits information we
8038 getTargetStreamer().updateABIInfo(*this);
8040 // If printing assembly, use the recently updated ABI Flags information.
8041 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8043 getTargetStreamer().emitDirectiveModuleVirt();
8045 // If this is not the end of the statement, report an error.
8046 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8047 reportParseError("unexpected token, expected end of statement");
8051 return false; // parseDirectiveModule has finished successfully.
8052 } else if (Option
== "novirt") {
8053 clearModuleFeatureBits(Mips::FeatureVirt
, "virt");
8055 // Synchronize the ABI Flags information with the FeatureBits information we
8057 getTargetStreamer().updateABIInfo(*this);
8059 // If printing assembly, use the recently updated ABI Flags information.
8060 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8062 getTargetStreamer().emitDirectiveModuleNoVirt();
8064 // If this is not the end of the statement, report an error.
8065 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8066 reportParseError("unexpected token, expected end of statement");
8070 return false; // parseDirectiveModule has finished successfully.
8071 } else if (Option
== "ginv") {
8072 setModuleFeatureBits(Mips::FeatureGINV
, "ginv");
8074 // Synchronize the ABI Flags information with the FeatureBits information we
8076 getTargetStreamer().updateABIInfo(*this);
8078 // If printing assembly, use the recently updated ABI Flags information.
8079 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8081 getTargetStreamer().emitDirectiveModuleGINV();
8083 // If this is not the end of the statement, report an error.
8084 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8085 reportParseError("unexpected token, expected end of statement");
8089 return false; // parseDirectiveModule has finished successfully.
8090 } else if (Option
== "noginv") {
8091 clearModuleFeatureBits(Mips::FeatureGINV
, "ginv");
8093 // Synchronize the ABI Flags information with the FeatureBits information we
8095 getTargetStreamer().updateABIInfo(*this);
8097 // If printing assembly, use the recently updated ABI Flags information.
8098 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8100 getTargetStreamer().emitDirectiveModuleNoGINV();
8102 // If this is not the end of the statement, report an error.
8103 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8104 reportParseError("unexpected token, expected end of statement");
8108 return false; // parseDirectiveModule has finished successfully.
8110 return Error(L
, "'" + Twine(Option
) + "' is not a valid .module option.");
8114 /// parseDirectiveModuleFP
8118 bool MipsAsmParser::parseDirectiveModuleFP() {
8119 MCAsmParser
&Parser
= getParser();
8120 MCAsmLexer
&Lexer
= getLexer();
8122 if (Lexer
.isNot(AsmToken::Equal
)) {
8123 reportParseError("unexpected token, expected equals sign '='");
8126 Parser
.Lex(); // Eat '=' token.
8128 MipsABIFlagsSection::FpABIKind FpABI
;
8129 if (!parseFpABIValue(FpABI
, ".module"))
8132 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8133 reportParseError("unexpected token, expected end of statement");
8137 // Synchronize the abiflags information with the FeatureBits information we
8139 getTargetStreamer().updateABIInfo(*this);
8141 // If printing assembly, use the recently updated abiflags information.
8142 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8143 // emitted at the end).
8144 getTargetStreamer().emitDirectiveModuleFP();
8146 Parser
.Lex(); // Consume the EndOfStatement.
8150 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind
&FpABI
,
8151 StringRef Directive
) {
8152 MCAsmParser
&Parser
= getParser();
8153 MCAsmLexer
&Lexer
= getLexer();
8154 bool ModuleLevelOptions
= Directive
== ".module";
8156 if (Lexer
.is(AsmToken::Identifier
)) {
8157 StringRef Value
= Parser
.getTok().getString();
8160 if (Value
!= "xx") {
8161 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8166 reportParseError("'" + Directive
+ " fp=xx' requires the O32 ABI");
8170 FpABI
= MipsABIFlagsSection::FpABIKind::XX
;
8171 if (ModuleLevelOptions
) {
8172 setModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8173 clearModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8175 setFeatureBits(Mips::FeatureFPXX
, "fpxx");
8176 clearFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8181 if (Lexer
.is(AsmToken::Integer
)) {
8182 unsigned Value
= Parser
.getTok().getIntVal();
8185 if (Value
!= 32 && Value
!= 64) {
8186 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8192 reportParseError("'" + Directive
+ " fp=32' requires the O32 ABI");
8196 FpABI
= MipsABIFlagsSection::FpABIKind::S32
;
8197 if (ModuleLevelOptions
) {
8198 clearModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8199 clearModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8201 clearFeatureBits(Mips::FeatureFPXX
, "fpxx");
8202 clearFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8205 FpABI
= MipsABIFlagsSection::FpABIKind::S64
;
8206 if (ModuleLevelOptions
) {
8207 clearModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8208 setModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8210 clearFeatureBits(Mips::FeatureFPXX
, "fpxx");
8211 setFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8221 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID
) {
8222 // This returns false if this function recognizes the directive
8223 // regardless of whether it is successfully handles or reports an
8224 // error. Otherwise it returns true to give the generic parser a
8225 // chance at recognizing it.
8227 MCAsmParser
&Parser
= getParser();
8228 StringRef IDVal
= DirectiveID
.getString();
8230 if (IDVal
== ".cpload") {
8231 parseDirectiveCpLoad(DirectiveID
.getLoc());
8234 if (IDVal
== ".cprestore") {
8235 parseDirectiveCpRestore(DirectiveID
.getLoc());
8238 if (IDVal
== ".cplocal") {
8239 parseDirectiveCpLocal(DirectiveID
.getLoc());
8242 if (IDVal
== ".ent") {
8243 StringRef SymbolName
;
8245 if (Parser
.parseIdentifier(SymbolName
)) {
8246 reportParseError("expected identifier after .ent");
8250 // There's an undocumented extension that allows an integer to
8251 // follow the name of the procedure which AFAICS is ignored by GAS.
8252 // Example: .ent foo,2
8253 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8254 if (getLexer().isNot(AsmToken::Comma
)) {
8255 // Even though we accept this undocumented extension for compatibility
8256 // reasons, the additional integer argument does not actually change
8257 // the behaviour of the '.ent' directive, so we would like to discourage
8258 // its use. We do this by not referring to the extended version in
8259 // error messages which are not directly related to its use.
8260 reportParseError("unexpected token, expected end of statement");
8263 Parser
.Lex(); // Eat the comma.
8264 const MCExpr
*DummyNumber
;
8265 int64_t DummyNumberVal
;
8266 // If the user was explicitly trying to use the extended version,
8267 // we still give helpful extension-related error messages.
8268 if (Parser
.parseExpression(DummyNumber
)) {
8269 reportParseError("expected number after comma");
8272 if (!DummyNumber
->evaluateAsAbsolute(DummyNumberVal
)) {
8273 reportParseError("expected an absolute expression after comma");
8278 // If this is not the end of the statement, report an error.
8279 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8280 reportParseError("unexpected token, expected end of statement");
8284 MCSymbol
*Sym
= getContext().getOrCreateSymbol(SymbolName
);
8286 getTargetStreamer().emitDirectiveEnt(*Sym
);
8288 IsCpRestoreSet
= false;
8292 if (IDVal
== ".end") {
8293 StringRef SymbolName
;
8295 if (Parser
.parseIdentifier(SymbolName
)) {
8296 reportParseError("expected identifier after .end");
8300 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8301 reportParseError("unexpected token, expected end of statement");
8305 if (CurrentFn
== nullptr) {
8306 reportParseError(".end used without .ent");
8310 if ((SymbolName
!= CurrentFn
->getName())) {
8311 reportParseError(".end symbol does not match .ent symbol");
8315 getTargetStreamer().emitDirectiveEnd(SymbolName
);
8316 CurrentFn
= nullptr;
8317 IsCpRestoreSet
= false;
8321 if (IDVal
== ".frame") {
8322 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8323 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> TmpReg
;
8324 OperandMatchResultTy ResTy
= parseAnyRegister(TmpReg
);
8325 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
8326 reportParseError("expected stack register");
8330 MipsOperand
&StackRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
8331 if (!StackRegOpnd
.isGPRAsmReg()) {
8332 reportParseError(StackRegOpnd
.getStartLoc(),
8333 "expected general purpose register");
8336 unsigned StackReg
= StackRegOpnd
.getGPR32Reg();
8338 if (Parser
.getTok().is(AsmToken::Comma
))
8341 reportParseError("unexpected token, expected comma");
8345 // Parse the frame size.
8346 const MCExpr
*FrameSize
;
8347 int64_t FrameSizeVal
;
8349 if (Parser
.parseExpression(FrameSize
)) {
8350 reportParseError("expected frame size value");
8354 if (!FrameSize
->evaluateAsAbsolute(FrameSizeVal
)) {
8355 reportParseError("frame size not an absolute expression");
8359 if (Parser
.getTok().is(AsmToken::Comma
))
8362 reportParseError("unexpected token, expected comma");
8366 // Parse the return register.
8368 ResTy
= parseAnyRegister(TmpReg
);
8369 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
8370 reportParseError("expected return register");
8374 MipsOperand
&ReturnRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
8375 if (!ReturnRegOpnd
.isGPRAsmReg()) {
8376 reportParseError(ReturnRegOpnd
.getStartLoc(),
8377 "expected general purpose register");
8381 // If this is not the end of the statement, report an error.
8382 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8383 reportParseError("unexpected token, expected end of statement");
8387 getTargetStreamer().emitFrame(StackReg
, FrameSizeVal
,
8388 ReturnRegOpnd
.getGPR32Reg());
8389 IsCpRestoreSet
= false;
8393 if (IDVal
== ".set") {
8394 parseDirectiveSet();
8398 if (IDVal
== ".mask" || IDVal
== ".fmask") {
8399 // .mask bitmask, frame_offset
8400 // bitmask: One bit for each register used.
8401 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8402 // first register is expected to be saved.
8404 // .mask 0x80000000, -4
8405 // .fmask 0x80000000, -4
8408 // Parse the bitmask
8409 const MCExpr
*BitMask
;
8412 if (Parser
.parseExpression(BitMask
)) {
8413 reportParseError("expected bitmask value");
8417 if (!BitMask
->evaluateAsAbsolute(BitMaskVal
)) {
8418 reportParseError("bitmask not an absolute expression");
8422 if (Parser
.getTok().is(AsmToken::Comma
))
8425 reportParseError("unexpected token, expected comma");
8429 // Parse the frame_offset
8430 const MCExpr
*FrameOffset
;
8431 int64_t FrameOffsetVal
;
8433 if (Parser
.parseExpression(FrameOffset
)) {
8434 reportParseError("expected frame offset value");
8438 if (!FrameOffset
->evaluateAsAbsolute(FrameOffsetVal
)) {
8439 reportParseError("frame offset not an absolute expression");
8443 // If this is not the end of the statement, report an error.
8444 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8445 reportParseError("unexpected token, expected end of statement");
8449 if (IDVal
== ".mask")
8450 getTargetStreamer().emitMask(BitMaskVal
, FrameOffsetVal
);
8452 getTargetStreamer().emitFMask(BitMaskVal
, FrameOffsetVal
);
8456 if (IDVal
== ".nan")
8457 return parseDirectiveNaN();
8459 if (IDVal
== ".gpword") {
8460 parseDirectiveGpWord();
8464 if (IDVal
== ".gpdword") {
8465 parseDirectiveGpDWord();
8469 if (IDVal
== ".dtprelword") {
8470 parseDirectiveDtpRelWord();
8474 if (IDVal
== ".dtpreldword") {
8475 parseDirectiveDtpRelDWord();
8479 if (IDVal
== ".tprelword") {
8480 parseDirectiveTpRelWord();
8484 if (IDVal
== ".tpreldword") {
8485 parseDirectiveTpRelDWord();
8489 if (IDVal
== ".option") {
8490 parseDirectiveOption();
8494 if (IDVal
== ".abicalls") {
8495 getTargetStreamer().emitDirectiveAbiCalls();
8496 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
8497 Error(Parser
.getTok().getLoc(),
8498 "unexpected token, expected end of statement");
8503 if (IDVal
== ".cpsetup") {
8504 parseDirectiveCPSetup();
8507 if (IDVal
== ".cpreturn") {
8508 parseDirectiveCPReturn();
8511 if (IDVal
== ".module") {
8512 parseDirectiveModule();
8515 if (IDVal
== ".llvm_internal_mips_reallow_module_directive") {
8516 parseInternalDirectiveReallowModule();
8519 if (IDVal
== ".insn") {
8520 parseInsnDirective();
8523 if (IDVal
== ".rdata") {
8524 parseRSectionDirective(".rodata");
8527 if (IDVal
== ".sbss") {
8528 parseSSectionDirective(IDVal
, ELF::SHT_NOBITS
);
8531 if (IDVal
== ".sdata") {
8532 parseSSectionDirective(IDVal
, ELF::SHT_PROGBITS
);
8539 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8540 // If this is not the end of the statement, report an error.
8541 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8542 reportParseError("unexpected token, expected end of statement");
8546 getTargetStreamer().reallowModuleDirective();
8548 getParser().Lex(); // Eat EndOfStatement token.
8552 extern "C" void LLVMInitializeMipsAsmParser() {
8553 RegisterMCAsmParser
<MipsAsmParser
> X(getTheMipsTarget());
8554 RegisterMCAsmParser
<MipsAsmParser
> Y(getTheMipselTarget());
8555 RegisterMCAsmParser
<MipsAsmParser
> A(getTheMips64Target());
8556 RegisterMCAsmParser
<MipsAsmParser
> B(getTheMips64elTarget());
8559 #define GET_REGISTER_MATCHER
8560 #define GET_MATCHER_IMPLEMENTATION
8561 #define GET_MNEMONIC_SPELL_CHECKER
8562 #include "MipsGenAsmMatcher.inc"
8564 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic
, unsigned VariantID
) {
8565 // Find the appropriate table for this asm variant.
8566 const MatchEntry
*Start
, *End
;
8567 switch (VariantID
) {
8568 default: llvm_unreachable("invalid variant!");
8569 case 0: Start
= std::begin(MatchTable0
); End
= std::end(MatchTable0
); break;
8571 // Search the table.
8572 auto MnemonicRange
= std::equal_range(Start
, End
, Mnemonic
, LessOpcode());
8573 return MnemonicRange
.first
!= MnemonicRange
.second
;