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 uint32_t ImmOp32
= covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64
));
3327 return loadImmediate(ImmOp32
, FirstReg
, Mips::NoRegister
, true, false, IDLoc
,
3331 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst
&Inst
, SMLoc IDLoc
,
3333 const MCSubtargetInfo
*STI
) {
3334 MipsTargetStreamer
&TOut
= getTargetStreamer();
3335 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3336 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3337 "Invalid instruction operand.");
3339 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3340 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3342 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3344 uint32_t ImmOp32
= covertDoubleImmToSingleImm(ImmOp64
);
3346 unsigned TmpReg
= Mips::ZERO
;
3348 TmpReg
= getATReg(IDLoc
);
3353 if (Lo_32(ImmOp64
) == 0) {
3354 if (TmpReg
!= Mips::ZERO
&& loadImmediate(ImmOp32
, TmpReg
, Mips::NoRegister
,
3355 true, false, IDLoc
, Out
, STI
))
3357 TOut
.emitRR(Mips::MTC1
, FirstReg
, TmpReg
, IDLoc
, STI
);
3361 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3362 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3363 // where appropriate.
3364 MCSection
*ReadOnlySection
=
3365 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3367 MCSymbol
*Sym
= getContext().createTempSymbol();
3368 const MCExpr
*LoSym
=
3369 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3370 const MipsMCExpr
*LoExpr
=
3371 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3373 getStreamer().SwitchSection(ReadOnlySection
);
3374 getStreamer().EmitLabel(Sym
, IDLoc
);
3375 getStreamer().EmitIntValue(ImmOp32
, 4);
3376 getStreamer().SwitchSection(CS
);
3378 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3380 TOut
.emitRRX(Mips::LWC1
, FirstReg
, TmpReg
, MCOperand::createExpr(LoExpr
),
3385 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst
&Inst
, SMLoc IDLoc
,
3387 const MCSubtargetInfo
*STI
) {
3388 MipsTargetStreamer
&TOut
= getTargetStreamer();
3389 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3390 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3391 "Invalid instruction operand.");
3393 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3394 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3396 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3398 if (Lo_32(ImmOp64
) == 0) {
3400 if (loadImmediate(ImmOp64
, FirstReg
, Mips::NoRegister
, false, false,
3404 if (loadImmediate(Hi_32(ImmOp64
), FirstReg
, Mips::NoRegister
, true, false,
3408 if (loadImmediate(0, nextReg(FirstReg
), Mips::NoRegister
, true, false,
3415 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3416 MCSection
*ReadOnlySection
=
3417 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3419 MCSymbol
*Sym
= getContext().createTempSymbol();
3420 const MCExpr
*LoSym
=
3421 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3422 const MipsMCExpr
*LoExpr
=
3423 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3425 getStreamer().SwitchSection(ReadOnlySection
);
3426 getStreamer().EmitLabel(Sym
, IDLoc
);
3427 getStreamer().EmitValueToAlignment(8);
3428 getStreamer().EmitIntValue(ImmOp64
, 8);
3429 getStreamer().SwitchSection(CS
);
3431 unsigned TmpReg
= getATReg(IDLoc
);
3435 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3438 TOut
.emitRRX(isABI_N64() ? Mips::DADDiu
: Mips::ADDiu
, TmpReg
, TmpReg
,
3439 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3442 TOut
.emitRRI(Mips::LD
, FirstReg
, TmpReg
, 0, IDLoc
, STI
);
3444 TOut
.emitRRI(Mips::LW
, FirstReg
, TmpReg
, 0, IDLoc
, STI
);
3445 TOut
.emitRRI(Mips::LW
, nextReg(FirstReg
), TmpReg
, 4, IDLoc
, STI
);
3450 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst
&Inst
, bool Is64FPU
,
3451 SMLoc IDLoc
, MCStreamer
&Out
,
3452 const MCSubtargetInfo
*STI
) {
3453 MipsTargetStreamer
&TOut
= getTargetStreamer();
3454 assert(Inst
.getNumOperands() == 2 && "Invalid operand count");
3455 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isImm() &&
3456 "Invalid instruction operand.");
3458 unsigned FirstReg
= Inst
.getOperand(0).getReg();
3459 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
3461 ImmOp64
= convertIntToDoubleImm(ImmOp64
);
3463 unsigned TmpReg
= Mips::ZERO
;
3465 TmpReg
= getATReg(IDLoc
);
3470 if ((Lo_32(ImmOp64
) == 0) &&
3471 !((Hi_32(ImmOp64
) & 0xffff0000) && (Hi_32(ImmOp64
) & 0x0000ffff))) {
3473 if (TmpReg
!= Mips::ZERO
&&
3474 loadImmediate(ImmOp64
, TmpReg
, Mips::NoRegister
, false, false, IDLoc
,
3477 TOut
.emitRR(Mips::DMTC1
, FirstReg
, TmpReg
, IDLoc
, STI
);
3481 if (TmpReg
!= Mips::ZERO
&&
3482 loadImmediate(Hi_32(ImmOp64
), TmpReg
, Mips::NoRegister
, true, false,
3486 if (hasMips32r2()) {
3487 TOut
.emitRR(Mips::MTC1
, FirstReg
, Mips::ZERO
, IDLoc
, STI
);
3488 TOut
.emitRRR(Mips::MTHC1_D32
, FirstReg
, FirstReg
, TmpReg
, IDLoc
, STI
);
3490 TOut
.emitRR(Mips::MTC1
, nextReg(FirstReg
), TmpReg
, IDLoc
, STI
);
3491 TOut
.emitRR(Mips::MTC1
, FirstReg
, Mips::ZERO
, IDLoc
, STI
);
3496 MCSection
*CS
= getStreamer().getCurrentSectionOnly();
3497 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3498 // where appropriate.
3499 MCSection
*ReadOnlySection
=
3500 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
3502 MCSymbol
*Sym
= getContext().createTempSymbol();
3503 const MCExpr
*LoSym
=
3504 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
3505 const MipsMCExpr
*LoExpr
=
3506 MipsMCExpr::create(MipsMCExpr::MEK_LO
, LoSym
, getContext());
3508 getStreamer().SwitchSection(ReadOnlySection
);
3509 getStreamer().EmitLabel(Sym
, IDLoc
);
3510 getStreamer().EmitValueToAlignment(8);
3511 getStreamer().EmitIntValue(ImmOp64
, 8);
3512 getStreamer().SwitchSection(CS
);
3514 if (emitPartialAddress(TOut
, IDLoc
, Sym
))
3517 TOut
.emitRRX(Is64FPU
? Mips::LDC164
: Mips::LDC1
, FirstReg
, TmpReg
,
3518 MCOperand::createExpr(LoExpr
), IDLoc
, STI
);
3523 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst
&Inst
, SMLoc IDLoc
,
3525 const MCSubtargetInfo
*STI
) {
3526 MipsTargetStreamer
&TOut
= getTargetStreamer();
3528 assert(getInstDesc(Inst
.getOpcode()).getNumOperands() == 1 &&
3529 "unexpected number of operands");
3531 MCOperand Offset
= Inst
.getOperand(0);
3532 if (Offset
.isExpr()) {
3534 Inst
.setOpcode(Mips::BEQ_MM
);
3535 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3536 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3537 Inst
.addOperand(MCOperand::createExpr(Offset
.getExpr()));
3539 assert(Offset
.isImm() && "expected immediate operand kind");
3540 if (isInt
<11>(Offset
.getImm())) {
3541 // If offset fits into 11 bits then this instruction becomes microMIPS
3542 // 16-bit unconditional branch instruction.
3543 if (inMicroMipsMode())
3544 Inst
.setOpcode(hasMips32r6() ? Mips::BC16_MMR6
: Mips::B16_MM
);
3546 if (!isInt
<17>(Offset
.getImm()))
3547 return Error(IDLoc
, "branch target out of range");
3548 if (offsetToAlignment(Offset
.getImm(), Align(2)))
3549 return Error(IDLoc
, "branch to misaligned address");
3551 Inst
.setOpcode(Mips::BEQ_MM
);
3552 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3553 Inst
.addOperand(MCOperand::createReg(Mips::ZERO
));
3554 Inst
.addOperand(MCOperand::createImm(Offset
.getImm()));
3557 Out
.EmitInstruction(Inst
, *STI
);
3559 // If .set reorder is active and branch instruction has a delay slot,
3560 // emit a NOP after it.
3561 const MCInstrDesc
&MCID
= getInstDesc(Inst
.getOpcode());
3562 if (MCID
.hasDelaySlot() && AssemblerOptions
.back()->isReorder())
3563 TOut
.emitEmptyDelaySlot(true, IDLoc
, STI
);
3568 bool MipsAsmParser::expandBranchImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
3569 const MCSubtargetInfo
*STI
) {
3570 MipsTargetStreamer
&TOut
= getTargetStreamer();
3571 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
3572 assert(DstRegOp
.isReg() && "expected register operand kind");
3574 const MCOperand
&ImmOp
= Inst
.getOperand(1);
3575 assert(ImmOp
.isImm() && "expected immediate operand kind");
3577 const MCOperand
&MemOffsetOp
= Inst
.getOperand(2);
3578 assert((MemOffsetOp
.isImm() || MemOffsetOp
.isExpr()) &&
3579 "expected immediate or expression operand");
3581 bool IsLikely
= false;
3583 unsigned OpCode
= 0;
3584 switch(Inst
.getOpcode()) {
3591 case Mips::BEQLImmMacro
:
3592 OpCode
= Mips::BEQL
;
3595 case Mips::BNELImmMacro
:
3596 OpCode
= Mips::BNEL
;
3600 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3604 int64_t ImmValue
= ImmOp
.getImm();
3605 if (ImmValue
== 0) {
3607 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), Mips::ZERO
,
3608 MCOperand::createExpr(MemOffsetOp
.getExpr()), IDLoc
, STI
);
3609 TOut
.emitRRI(Mips::SLL
, Mips::ZERO
, Mips::ZERO
, 0, IDLoc
, STI
);
3611 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), Mips::ZERO
, MemOffsetOp
, IDLoc
,
3614 warnIfNoMacro(IDLoc
);
3616 unsigned ATReg
= getATReg(IDLoc
);
3620 if (loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, !isGP64bit(), true,
3625 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), ATReg
,
3626 MCOperand::createExpr(MemOffsetOp
.getExpr()), IDLoc
, STI
);
3627 TOut
.emitRRI(Mips::SLL
, Mips::ZERO
, Mips::ZERO
, 0, IDLoc
, STI
);
3629 TOut
.emitRRX(OpCode
, DstRegOp
.getReg(), ATReg
, MemOffsetOp
, IDLoc
, STI
);
3634 void MipsAsmParser::expandMemInst(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
3635 const MCSubtargetInfo
*STI
, bool IsLoad
) {
3636 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
3637 assert(DstRegOp
.isReg() && "expected register operand kind");
3638 const MCOperand
&BaseRegOp
= Inst
.getOperand(1);
3639 assert(BaseRegOp
.isReg() && "expected register operand kind");
3641 MipsTargetStreamer
&TOut
= getTargetStreamer();
3642 unsigned DstReg
= DstRegOp
.getReg();
3643 unsigned BaseReg
= BaseRegOp
.getReg();
3644 unsigned TmpReg
= DstReg
;
3646 const MCInstrDesc
&Desc
= getInstDesc(Inst
.getOpcode());
3647 int16_t DstRegClass
= Desc
.OpInfo
[0].RegClass
;
3648 unsigned DstRegClassID
=
3649 getContext().getRegisterInfo()->getRegClass(DstRegClass
).getID();
3650 bool IsGPR
= (DstRegClassID
== Mips::GPR32RegClassID
) ||
3651 (DstRegClassID
== Mips::GPR64RegClassID
);
3653 if (!IsLoad
|| !IsGPR
|| (BaseReg
== DstReg
)) {
3654 // At this point we need AT to perform the expansions
3655 // and we exit if it is not available.
3656 TmpReg
= getATReg(IDLoc
);
3661 if (Inst
.getNumOperands() > 3) {
3662 const MCOperand
&BaseRegOp
= Inst
.getOperand(2);
3663 assert(BaseRegOp
.isReg() && "expected register operand kind");
3664 const MCOperand
&ExprOp
= Inst
.getOperand(3);
3665 assert(ExprOp
.isExpr() && "expected expression oprand kind");
3667 unsigned BaseReg
= BaseRegOp
.getReg();
3668 const MCExpr
*ExprOffset
= ExprOp
.getExpr();
3670 MCOperand LoOperand
= MCOperand::createExpr(
3671 MipsMCExpr::create(MipsMCExpr::MEK_LO
, ExprOffset
, getContext()));
3672 MCOperand HiOperand
= MCOperand::createExpr(
3673 MipsMCExpr::create(MipsMCExpr::MEK_HI
, ExprOffset
, getContext()));
3674 TOut
.emitSCWithSymOffset(Inst
.getOpcode(), DstReg
, BaseReg
, HiOperand
,
3675 LoOperand
, TmpReg
, IDLoc
, STI
);
3679 const MCOperand
&OffsetOp
= Inst
.getOperand(2);
3681 if (OffsetOp
.isImm()) {
3682 int64_t LoOffset
= OffsetOp
.getImm() & 0xffff;
3683 int64_t HiOffset
= OffsetOp
.getImm() & ~0xffff;
3685 // If msb of LoOffset is 1(negative number) we must increment
3686 // HiOffset to account for the sign-extension of the low part.
3687 if (LoOffset
& 0x8000)
3688 HiOffset
+= 0x10000;
3690 bool IsLargeOffset
= HiOffset
!= 0;
3692 if (IsLargeOffset
) {
3693 bool Is32BitImm
= (HiOffset
>> 32) == 0;
3694 if (loadImmediate(HiOffset
, TmpReg
, Mips::NoRegister
, Is32BitImm
, true,
3699 if (BaseReg
!= Mips::ZERO
&& BaseReg
!= Mips::ZERO_64
)
3700 TOut
.emitRRR(isGP64bit() ? Mips::DADDu
: Mips::ADDu
, TmpReg
, TmpReg
,
3701 BaseReg
, IDLoc
, STI
);
3702 TOut
.emitRRI(Inst
.getOpcode(), DstReg
, TmpReg
, LoOffset
, IDLoc
, STI
);
3706 if (OffsetOp
.isExpr()) {
3709 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3710 // do not exceed 16-bit.
3711 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3712 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3715 if (!OffsetOp
.getExpr()->evaluateAsRelocatable(Res
, nullptr, nullptr)) {
3716 Error(IDLoc
, "expected relocatable expression");
3719 if (Res
.getSymB() != nullptr) {
3720 Error(IDLoc
, "expected relocatable expression with only one symbol");
3724 loadAndAddSymbolAddress(Res
.getSymA(), TmpReg
, BaseReg
,
3725 !ABI
.ArePtrs64bit(), IDLoc
, Out
, STI
);
3726 TOut
.emitRRI(Inst
.getOpcode(), DstReg
, TmpReg
, Res
.getConstant(), IDLoc
,
3729 // FIXME: Implement 64-bit case.
3730 // 1) lw $8, sym => lui $8, %hi(sym)
3731 // lw $8, %lo(sym)($8)
3732 // 2) sw $8, sym => lui $at, %hi(sym)
3733 // sw $8, %lo(sym)($at)
3734 const MCExpr
*ExprOffset
= OffsetOp
.getExpr();
3735 MCOperand LoOperand
= MCOperand::createExpr(
3736 MipsMCExpr::create(MipsMCExpr::MEK_LO
, ExprOffset
, getContext()));
3737 MCOperand HiOperand
= MCOperand::createExpr(
3738 MipsMCExpr::create(MipsMCExpr::MEK_HI
, ExprOffset
, getContext()));
3740 // Generate the base address in TmpReg.
3741 TOut
.emitRX(Mips::LUi
, TmpReg
, HiOperand
, IDLoc
, STI
);
3742 if (BaseReg
!= Mips::ZERO
)
3743 TOut
.emitRRR(Mips::ADDu
, TmpReg
, TmpReg
, BaseReg
, IDLoc
, STI
);
3744 // Emit the load or store with the adjusted base and offset.
3745 TOut
.emitRRX(Inst
.getOpcode(), DstReg
, TmpReg
, LoOperand
, IDLoc
, STI
);
3750 llvm_unreachable("unexpected operand type");
3753 bool MipsAsmParser::expandLoadStoreMultiple(MCInst
&Inst
, SMLoc IDLoc
,
3755 const MCSubtargetInfo
*STI
) {
3756 unsigned OpNum
= Inst
.getNumOperands();
3757 unsigned Opcode
= Inst
.getOpcode();
3758 unsigned NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM32_MM
: Mips::LWM32_MM
;
3760 assert(Inst
.getOperand(OpNum
- 1).isImm() &&
3761 Inst
.getOperand(OpNum
- 2).isReg() &&
3762 Inst
.getOperand(OpNum
- 3).isReg() && "Invalid instruction operand.");
3764 if (OpNum
< 8 && Inst
.getOperand(OpNum
- 1).getImm() <= 60 &&
3765 Inst
.getOperand(OpNum
- 1).getImm() >= 0 &&
3766 (Inst
.getOperand(OpNum
- 2).getReg() == Mips::SP
||
3767 Inst
.getOperand(OpNum
- 2).getReg() == Mips::SP_64
) &&
3768 (Inst
.getOperand(OpNum
- 3).getReg() == Mips::RA
||
3769 Inst
.getOperand(OpNum
- 3).getReg() == Mips::RA_64
)) {
3770 // It can be implemented as SWM16 or LWM16 instruction.
3771 if (inMicroMipsMode() && hasMips32r6())
3772 NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM16_MMR6
: Mips::LWM16_MMR6
;
3774 NewOpcode
= Opcode
== Mips::SWM_MM
? Mips::SWM16_MM
: Mips::LWM16_MM
;
3777 Inst
.setOpcode(NewOpcode
);
3778 Out
.EmitInstruction(Inst
, *STI
);
3782 bool MipsAsmParser::expandCondBranches(MCInst
&Inst
, SMLoc IDLoc
,
3784 const MCSubtargetInfo
*STI
) {
3785 MipsTargetStreamer
&TOut
= getTargetStreamer();
3786 bool EmittedNoMacroWarning
= false;
3787 unsigned PseudoOpcode
= Inst
.getOpcode();
3788 unsigned SrcReg
= Inst
.getOperand(0).getReg();
3789 const MCOperand
&TrgOp
= Inst
.getOperand(1);
3790 const MCExpr
*OffsetExpr
= Inst
.getOperand(2).getExpr();
3792 unsigned ZeroSrcOpcode
, ZeroTrgOpcode
;
3793 bool ReverseOrderSLT
, IsUnsigned
, IsLikely
, AcceptsEquality
;
3797 TrgReg
= TrgOp
.getReg();
3798 else if (TrgOp
.isImm()) {
3799 warnIfNoMacro(IDLoc
);
3800 EmittedNoMacroWarning
= true;
3802 TrgReg
= getATReg(IDLoc
);
3806 switch(PseudoOpcode
) {
3808 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3809 case Mips::BLTImmMacro
:
3810 PseudoOpcode
= Mips::BLT
;
3812 case Mips::BLEImmMacro
:
3813 PseudoOpcode
= Mips::BLE
;
3815 case Mips::BGEImmMacro
:
3816 PseudoOpcode
= Mips::BGE
;
3818 case Mips::BGTImmMacro
:
3819 PseudoOpcode
= Mips::BGT
;
3821 case Mips::BLTUImmMacro
:
3822 PseudoOpcode
= Mips::BLTU
;
3824 case Mips::BLEUImmMacro
:
3825 PseudoOpcode
= Mips::BLEU
;
3827 case Mips::BGEUImmMacro
:
3828 PseudoOpcode
= Mips::BGEU
;
3830 case Mips::BGTUImmMacro
:
3831 PseudoOpcode
= Mips::BGTU
;
3833 case Mips::BLTLImmMacro
:
3834 PseudoOpcode
= Mips::BLTL
;
3836 case Mips::BLELImmMacro
:
3837 PseudoOpcode
= Mips::BLEL
;
3839 case Mips::BGELImmMacro
:
3840 PseudoOpcode
= Mips::BGEL
;
3842 case Mips::BGTLImmMacro
:
3843 PseudoOpcode
= Mips::BGTL
;
3845 case Mips::BLTULImmMacro
:
3846 PseudoOpcode
= Mips::BLTUL
;
3848 case Mips::BLEULImmMacro
:
3849 PseudoOpcode
= Mips::BLEUL
;
3851 case Mips::BGEULImmMacro
:
3852 PseudoOpcode
= Mips::BGEUL
;
3854 case Mips::BGTULImmMacro
:
3855 PseudoOpcode
= Mips::BGTUL
;
3859 if (loadImmediate(TrgOp
.getImm(), TrgReg
, Mips::NoRegister
, !isGP64bit(),
3860 false, IDLoc
, Out
, STI
))
3864 switch (PseudoOpcode
) {
3869 AcceptsEquality
= false;
3870 ReverseOrderSLT
= false;
3872 ((PseudoOpcode
== Mips::BLTU
) || (PseudoOpcode
== Mips::BLTUL
));
3873 IsLikely
= ((PseudoOpcode
== Mips::BLTL
) || (PseudoOpcode
== Mips::BLTUL
));
3874 ZeroSrcOpcode
= Mips::BGTZ
;
3875 ZeroTrgOpcode
= Mips::BLTZ
;
3881 AcceptsEquality
= true;
3882 ReverseOrderSLT
= true;
3884 ((PseudoOpcode
== Mips::BLEU
) || (PseudoOpcode
== Mips::BLEUL
));
3885 IsLikely
= ((PseudoOpcode
== Mips::BLEL
) || (PseudoOpcode
== Mips::BLEUL
));
3886 ZeroSrcOpcode
= Mips::BGEZ
;
3887 ZeroTrgOpcode
= Mips::BLEZ
;
3893 AcceptsEquality
= true;
3894 ReverseOrderSLT
= false;
3896 ((PseudoOpcode
== Mips::BGEU
) || (PseudoOpcode
== Mips::BGEUL
));
3897 IsLikely
= ((PseudoOpcode
== Mips::BGEL
) || (PseudoOpcode
== Mips::BGEUL
));
3898 ZeroSrcOpcode
= Mips::BLEZ
;
3899 ZeroTrgOpcode
= Mips::BGEZ
;
3905 AcceptsEquality
= false;
3906 ReverseOrderSLT
= true;
3908 ((PseudoOpcode
== Mips::BGTU
) || (PseudoOpcode
== Mips::BGTUL
));
3909 IsLikely
= ((PseudoOpcode
== Mips::BGTL
) || (PseudoOpcode
== Mips::BGTUL
));
3910 ZeroSrcOpcode
= Mips::BLTZ
;
3911 ZeroTrgOpcode
= Mips::BGTZ
;
3914 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3917 bool IsTrgRegZero
= (TrgReg
== Mips::ZERO
);
3918 bool IsSrcRegZero
= (SrcReg
== Mips::ZERO
);
3919 if (IsSrcRegZero
&& IsTrgRegZero
) {
3920 // FIXME: All of these Opcode-specific if's are needed for compatibility
3921 // with GAS' behaviour. However, they may not generate the most efficient
3922 // code in some circumstances.
3923 if (PseudoOpcode
== Mips::BLT
) {
3924 TOut
.emitRX(Mips::BLTZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3928 if (PseudoOpcode
== Mips::BLE
) {
3929 TOut
.emitRX(Mips::BLEZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3931 Warning(IDLoc
, "branch is always taken");
3934 if (PseudoOpcode
== Mips::BGE
) {
3935 TOut
.emitRX(Mips::BGEZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3937 Warning(IDLoc
, "branch is always taken");
3940 if (PseudoOpcode
== Mips::BGT
) {
3941 TOut
.emitRX(Mips::BGTZ
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
),
3945 if (PseudoOpcode
== Mips::BGTU
) {
3946 TOut
.emitRRX(Mips::BNE
, Mips::ZERO
, Mips::ZERO
,
3947 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
3950 if (AcceptsEquality
) {
3951 // If both registers are $0 and the pseudo-branch accepts equality, it
3952 // will always be taken, so we emit an unconditional branch.
3953 TOut
.emitRRX(Mips::BEQ
, Mips::ZERO
, Mips::ZERO
,
3954 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
3955 Warning(IDLoc
, "branch is always taken");
3958 // If both registers are $0 and the pseudo-branch does not accept
3959 // equality, it will never be taken, so we don't have to emit anything.
3962 if (IsSrcRegZero
|| IsTrgRegZero
) {
3963 if ((IsSrcRegZero
&& PseudoOpcode
== Mips::BGTU
) ||
3964 (IsTrgRegZero
&& PseudoOpcode
== Mips::BLTU
)) {
3965 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3966 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3967 // the pseudo-branch will never be taken, so we don't emit anything.
3968 // This only applies to unsigned pseudo-branches.
3971 if ((IsSrcRegZero
&& PseudoOpcode
== Mips::BLEU
) ||
3972 (IsTrgRegZero
&& PseudoOpcode
== Mips::BGEU
)) {
3973 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3974 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3975 // the pseudo-branch will always be taken, so we emit an unconditional
3977 // This only applies to unsigned pseudo-branches.
3978 TOut
.emitRRX(Mips::BEQ
, Mips::ZERO
, Mips::ZERO
,
3979 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
3980 Warning(IDLoc
, "branch is always taken");
3984 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3985 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3986 // the pseudo-branch will be taken only when the non-zero register is
3987 // different from 0, so we emit a BNEZ.
3989 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3990 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3991 // the pseudo-branch will be taken only when the non-zero register is
3992 // equal to 0, so we emit a BEQZ.
3994 // Because only BLEU and BGEU branch on equality, we can use the
3995 // AcceptsEquality variable to decide when to emit the BEQZ.
3996 TOut
.emitRRX(AcceptsEquality
? Mips::BEQ
: Mips::BNE
,
3997 IsSrcRegZero
? TrgReg
: SrcReg
, Mips::ZERO
,
3998 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4001 // If we have a signed pseudo-branch and one of the registers is $0,
4002 // we can use an appropriate compare-to-zero branch. We select which one
4003 // to use in the switch statement above.
4004 TOut
.emitRX(IsSrcRegZero
? ZeroSrcOpcode
: ZeroTrgOpcode
,
4005 IsSrcRegZero
? TrgReg
: SrcReg
,
4006 MCOperand::createExpr(OffsetExpr
), IDLoc
, STI
);
4010 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4011 // expansions. If it is not available, we return.
4012 unsigned ATRegNum
= getATReg(IDLoc
);
4016 if (!EmittedNoMacroWarning
)
4017 warnIfNoMacro(IDLoc
);
4019 // SLT fits well with 2 of our 4 pseudo-branches:
4020 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4021 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4022 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4023 // This is accomplished by using a BNEZ with the result of the SLT.
4025 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4026 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4027 // Because only BGE and BLE branch on equality, we can use the
4028 // AcceptsEquality variable to decide when to emit the BEQZ.
4029 // Note that the order of the SLT arguments doesn't change between
4032 // The same applies to the unsigned variants, except that SLTu is used
4034 TOut
.emitRRR(IsUnsigned
? Mips::SLTu
: Mips::SLT
, ATRegNum
,
4035 ReverseOrderSLT
? TrgReg
: SrcReg
,
4036 ReverseOrderSLT
? SrcReg
: TrgReg
, IDLoc
, STI
);
4038 TOut
.emitRRX(IsLikely
? (AcceptsEquality
? Mips::BEQL
: Mips::BNEL
)
4039 : (AcceptsEquality
? Mips::BEQ
: Mips::BNE
),
4040 ATRegNum
, Mips::ZERO
, MCOperand::createExpr(OffsetExpr
), IDLoc
,
4045 // Expand a integer division macro.
4047 // Notably we don't have to emit a warning when encountering $rt as the $zero
4048 // register, or 0 as an immediate. processInstruction() has already done that.
4050 // The destination register can only be $zero when expanding (S)DivIMacro or
4053 bool MipsAsmParser::expandDivRem(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4054 const MCSubtargetInfo
*STI
, const bool IsMips64
,
4055 const bool Signed
) {
4056 MipsTargetStreamer
&TOut
= getTargetStreamer();
4058 warnIfNoMacro(IDLoc
);
4060 const MCOperand
&RdRegOp
= Inst
.getOperand(0);
4061 assert(RdRegOp
.isReg() && "expected register operand kind");
4062 unsigned RdReg
= RdRegOp
.getReg();
4064 const MCOperand
&RsRegOp
= Inst
.getOperand(1);
4065 assert(RsRegOp
.isReg() && "expected register operand kind");
4066 unsigned RsReg
= RsRegOp
.getReg();
4071 const MCOperand
&RtOp
= Inst
.getOperand(2);
4072 assert((RtOp
.isReg() || RtOp
.isImm()) &&
4073 "expected register or immediate operand kind");
4075 RtReg
= RtOp
.getReg();
4077 ImmValue
= RtOp
.getImm();
4084 DivOp
= Signed
? Mips::DSDIV
: Mips::DUDIV
;
4085 ZeroReg
= Mips::ZERO_64
;
4088 DivOp
= Signed
? Mips::SDIV
: Mips::UDIV
;
4089 ZeroReg
= Mips::ZERO
;
4093 bool UseTraps
= useTraps();
4095 unsigned Opcode
= Inst
.getOpcode();
4096 bool isDiv
= Opcode
== Mips::SDivMacro
|| Opcode
== Mips::SDivIMacro
||
4097 Opcode
== Mips::UDivMacro
|| Opcode
== Mips::UDivIMacro
||
4098 Opcode
== Mips::DSDivMacro
|| Opcode
== Mips::DSDivIMacro
||
4099 Opcode
== Mips::DUDivMacro
|| Opcode
== Mips::DUDivIMacro
;
4101 bool isRem
= Opcode
== Mips::SRemMacro
|| Opcode
== Mips::SRemIMacro
||
4102 Opcode
== Mips::URemMacro
|| Opcode
== Mips::URemIMacro
||
4103 Opcode
== Mips::DSRemMacro
|| Opcode
== Mips::DSRemIMacro
||
4104 Opcode
== Mips::DURemMacro
|| Opcode
== Mips::DURemIMacro
;
4107 unsigned ATReg
= getATReg(IDLoc
);
4111 if (ImmValue
== 0) {
4113 TOut
.emitRRI(Mips::TEQ
, ZeroReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4115 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4119 if (isRem
&& (ImmValue
== 1 || (Signed
&& (ImmValue
== -1)))) {
4120 TOut
.emitRRR(Mips::OR
, RdReg
, ZeroReg
, ZeroReg
, IDLoc
, STI
);
4122 } else if (isDiv
&& ImmValue
== 1) {
4123 TOut
.emitRRR(Mips::OR
, RdReg
, RsReg
, Mips::ZERO
, IDLoc
, STI
);
4125 } else if (isDiv
&& Signed
&& ImmValue
== -1) {
4126 TOut
.emitRRR(SubOp
, RdReg
, ZeroReg
, RsReg
, IDLoc
, STI
);
4129 if (loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4130 false, Inst
.getLoc(), Out
, STI
))
4132 TOut
.emitRR(DivOp
, RsReg
, ATReg
, IDLoc
, STI
);
4133 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4139 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4140 // break, insert the trap/break and exit. This gives a different result to
4141 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4142 // are handled equivalently. As the observed behaviour is the same, we're ok.
4143 if (RtReg
== Mips::ZERO
|| RtReg
== Mips::ZERO_64
) {
4145 TOut
.emitRRI(Mips::TEQ
, ZeroReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4148 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4152 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4153 // not expand to macro sequence.
4154 if (isRem
&& (RdReg
== Mips::ZERO
|| RdReg
== Mips::ZERO_64
)) {
4155 TOut
.emitRR(DivOp
, RsReg
, RtReg
, IDLoc
, STI
);
4159 // Temporary label for first branch traget
4160 MCContext
&Context
= TOut
.getStreamer().getContext();
4165 TOut
.emitRRI(Mips::TEQ
, RtReg
, ZeroReg
, 0x7, IDLoc
, STI
);
4167 // Branch to the li instruction.
4168 BrTarget
= Context
.createTempSymbol();
4169 LabelOp
= MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
4170 TOut
.emitRRX(Mips::BNE
, RtReg
, ZeroReg
, LabelOp
, IDLoc
, STI
);
4173 TOut
.emitRR(DivOp
, RsReg
, RtReg
, IDLoc
, STI
);
4176 TOut
.emitII(Mips::BREAK
, 0x7, 0, IDLoc
, STI
);
4180 TOut
.getStreamer().EmitLabel(BrTarget
);
4182 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4186 unsigned ATReg
= getATReg(IDLoc
);
4191 TOut
.getStreamer().EmitLabel(BrTarget
);
4193 TOut
.emitRRI(Mips::ADDiu
, ATReg
, ZeroReg
, -1, IDLoc
, STI
);
4195 // Temporary label for the second branch target.
4196 MCSymbol
*BrTargetEnd
= Context
.createTempSymbol();
4197 MCOperand LabelOpEnd
=
4198 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd
, Context
));
4200 // Branch to the mflo instruction.
4201 TOut
.emitRRX(Mips::BNE
, RtReg
, ATReg
, LabelOpEnd
, IDLoc
, STI
);
4204 TOut
.emitRRI(Mips::ADDiu
, ATReg
, ZeroReg
, 1, IDLoc
, STI
);
4205 TOut
.emitDSLL(ATReg
, ATReg
, 63, IDLoc
, STI
);
4207 TOut
.emitRI(Mips::LUi
, ATReg
, (uint16_t)0x8000, IDLoc
, STI
);
4211 TOut
.emitRRI(Mips::TEQ
, RsReg
, ATReg
, 0x6, IDLoc
, STI
);
4213 // Branch to the mflo instruction.
4214 TOut
.emitRRX(Mips::BNE
, RsReg
, ATReg
, LabelOpEnd
, IDLoc
, STI
);
4215 TOut
.emitNop(IDLoc
, STI
);
4216 TOut
.emitII(Mips::BREAK
, 0x6, 0, IDLoc
, STI
);
4219 TOut
.getStreamer().EmitLabel(BrTargetEnd
);
4220 TOut
.emitR(isDiv
? Mips::MFLO
: Mips::MFHI
, RdReg
, IDLoc
, STI
);
4224 bool MipsAsmParser::expandTrunc(MCInst
&Inst
, bool IsDouble
, bool Is64FPU
,
4225 SMLoc IDLoc
, MCStreamer
&Out
,
4226 const MCSubtargetInfo
*STI
) {
4227 MipsTargetStreamer
&TOut
= getTargetStreamer();
4229 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4230 assert(Inst
.getOperand(0).isReg() && Inst
.getOperand(1).isReg() &&
4231 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
4233 unsigned FirstReg
= Inst
.getOperand(0).getReg();
4234 unsigned SecondReg
= Inst
.getOperand(1).getReg();
4235 unsigned ThirdReg
= Inst
.getOperand(2).getReg();
4237 if (hasMips1() && !hasMips2()) {
4238 unsigned ATReg
= getATReg(IDLoc
);
4241 TOut
.emitRR(Mips::CFC1
, ThirdReg
, Mips::RA
, IDLoc
, STI
);
4242 TOut
.emitRR(Mips::CFC1
, ThirdReg
, Mips::RA
, IDLoc
, STI
);
4243 TOut
.emitNop(IDLoc
, STI
);
4244 TOut
.emitRRI(Mips::ORi
, ATReg
, ThirdReg
, 0x3, IDLoc
, STI
);
4245 TOut
.emitRRI(Mips::XORi
, ATReg
, ATReg
, 0x2, IDLoc
, STI
);
4246 TOut
.emitRR(Mips::CTC1
, Mips::RA
, ATReg
, IDLoc
, STI
);
4247 TOut
.emitNop(IDLoc
, STI
);
4248 TOut
.emitRR(IsDouble
? (Is64FPU
? Mips::CVT_W_D64
: Mips::CVT_W_D32
)
4250 FirstReg
, SecondReg
, IDLoc
, STI
);
4251 TOut
.emitRR(Mips::CTC1
, Mips::RA
, ThirdReg
, IDLoc
, STI
);
4252 TOut
.emitNop(IDLoc
, STI
);
4256 TOut
.emitRR(IsDouble
? (Is64FPU
? Mips::TRUNC_W_D64
: Mips::TRUNC_W_D32
)
4258 FirstReg
, SecondReg
, IDLoc
, STI
);
4263 bool MipsAsmParser::expandUlh(MCInst
&Inst
, bool Signed
, SMLoc IDLoc
,
4264 MCStreamer
&Out
, const MCSubtargetInfo
*STI
) {
4265 if (hasMips32r6() || hasMips64r6()) {
4266 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4269 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4270 assert(DstRegOp
.isReg() && "expected register operand kind");
4271 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4272 assert(SrcRegOp
.isReg() && "expected register operand kind");
4273 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4274 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4276 MipsTargetStreamer
&TOut
= getTargetStreamer();
4277 unsigned DstReg
= DstRegOp
.getReg();
4278 unsigned SrcReg
= SrcRegOp
.getReg();
4279 int64_t OffsetValue
= OffsetImmOp
.getImm();
4281 // NOTE: We always need AT for ULHU, as it is always used as the source
4282 // register for one of the LBu's.
4283 warnIfNoMacro(IDLoc
);
4284 unsigned ATReg
= getATReg(IDLoc
);
4288 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 1) && isInt
<16>(OffsetValue
));
4289 if (IsLargeOffset
) {
4290 if (loadImmediate(OffsetValue
, ATReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4295 int64_t FirstOffset
= IsLargeOffset
? 0 : OffsetValue
;
4296 int64_t SecondOffset
= IsLargeOffset
? 1 : (OffsetValue
+ 1);
4298 std::swap(FirstOffset
, SecondOffset
);
4300 unsigned FirstLbuDstReg
= IsLargeOffset
? DstReg
: ATReg
;
4301 unsigned SecondLbuDstReg
= IsLargeOffset
? ATReg
: DstReg
;
4303 unsigned LbuSrcReg
= IsLargeOffset
? ATReg
: SrcReg
;
4304 unsigned SllReg
= IsLargeOffset
? DstReg
: ATReg
;
4306 TOut
.emitRRI(Signed
? Mips::LB
: Mips::LBu
, FirstLbuDstReg
, LbuSrcReg
,
4307 FirstOffset
, IDLoc
, STI
);
4308 TOut
.emitRRI(Mips::LBu
, SecondLbuDstReg
, LbuSrcReg
, SecondOffset
, IDLoc
, STI
);
4309 TOut
.emitRRI(Mips::SLL
, SllReg
, SllReg
, 8, IDLoc
, STI
);
4310 TOut
.emitRRR(Mips::OR
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
4315 bool MipsAsmParser::expandUsh(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4316 const MCSubtargetInfo
*STI
) {
4317 if (hasMips32r6() || hasMips64r6()) {
4318 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4321 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4322 assert(DstRegOp
.isReg() && "expected register operand kind");
4323 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4324 assert(SrcRegOp
.isReg() && "expected register operand kind");
4325 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4326 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4328 MipsTargetStreamer
&TOut
= getTargetStreamer();
4329 unsigned DstReg
= DstRegOp
.getReg();
4330 unsigned SrcReg
= SrcRegOp
.getReg();
4331 int64_t OffsetValue
= OffsetImmOp
.getImm();
4333 warnIfNoMacro(IDLoc
);
4334 unsigned ATReg
= getATReg(IDLoc
);
4338 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 1) && isInt
<16>(OffsetValue
));
4339 if (IsLargeOffset
) {
4340 if (loadImmediate(OffsetValue
, ATReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4345 int64_t FirstOffset
= IsLargeOffset
? 1 : (OffsetValue
+ 1);
4346 int64_t SecondOffset
= IsLargeOffset
? 0 : OffsetValue
;
4348 std::swap(FirstOffset
, SecondOffset
);
4350 if (IsLargeOffset
) {
4351 TOut
.emitRRI(Mips::SB
, DstReg
, ATReg
, FirstOffset
, IDLoc
, STI
);
4352 TOut
.emitRRI(Mips::SRL
, DstReg
, DstReg
, 8, IDLoc
, STI
);
4353 TOut
.emitRRI(Mips::SB
, DstReg
, ATReg
, SecondOffset
, IDLoc
, STI
);
4354 TOut
.emitRRI(Mips::LBu
, ATReg
, ATReg
, 0, IDLoc
, STI
);
4355 TOut
.emitRRI(Mips::SLL
, DstReg
, DstReg
, 8, IDLoc
, STI
);
4356 TOut
.emitRRR(Mips::OR
, DstReg
, DstReg
, ATReg
, IDLoc
, STI
);
4358 TOut
.emitRRI(Mips::SB
, DstReg
, SrcReg
, FirstOffset
, IDLoc
, STI
);
4359 TOut
.emitRRI(Mips::SRL
, ATReg
, DstReg
, 8, IDLoc
, STI
);
4360 TOut
.emitRRI(Mips::SB
, ATReg
, SrcReg
, SecondOffset
, IDLoc
, STI
);
4366 bool MipsAsmParser::expandUxw(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4367 const MCSubtargetInfo
*STI
) {
4368 if (hasMips32r6() || hasMips64r6()) {
4369 return Error(IDLoc
, "instruction not supported on mips32r6 or mips64r6");
4372 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
4373 assert(DstRegOp
.isReg() && "expected register operand kind");
4374 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
4375 assert(SrcRegOp
.isReg() && "expected register operand kind");
4376 const MCOperand
&OffsetImmOp
= Inst
.getOperand(2);
4377 assert(OffsetImmOp
.isImm() && "expected immediate operand kind");
4379 MipsTargetStreamer
&TOut
= getTargetStreamer();
4380 unsigned DstReg
= DstRegOp
.getReg();
4381 unsigned SrcReg
= SrcRegOp
.getReg();
4382 int64_t OffsetValue
= OffsetImmOp
.getImm();
4384 // Compute left/right load/store offsets.
4385 bool IsLargeOffset
= !(isInt
<16>(OffsetValue
+ 3) && isInt
<16>(OffsetValue
));
4386 int64_t LxlOffset
= IsLargeOffset
? 0 : OffsetValue
;
4387 int64_t LxrOffset
= IsLargeOffset
? 3 : (OffsetValue
+ 3);
4389 std::swap(LxlOffset
, LxrOffset
);
4391 bool IsLoadInst
= (Inst
.getOpcode() == Mips::Ulw
);
4392 bool DoMove
= IsLoadInst
&& (SrcReg
== DstReg
) && !IsLargeOffset
;
4393 unsigned TmpReg
= SrcReg
;
4394 if (IsLargeOffset
|| DoMove
) {
4395 warnIfNoMacro(IDLoc
);
4396 TmpReg
= getATReg(IDLoc
);
4401 if (IsLargeOffset
) {
4402 if (loadImmediate(OffsetValue
, TmpReg
, SrcReg
, !ABI
.ArePtrs64bit(), true,
4408 std::swap(DstReg
, TmpReg
);
4410 unsigned XWL
= IsLoadInst
? Mips::LWL
: Mips::SWL
;
4411 unsigned XWR
= IsLoadInst
? Mips::LWR
: Mips::SWR
;
4412 TOut
.emitRRI(XWL
, DstReg
, TmpReg
, LxlOffset
, IDLoc
, STI
);
4413 TOut
.emitRRI(XWR
, DstReg
, TmpReg
, LxrOffset
, IDLoc
, STI
);
4416 TOut
.emitRRR(Mips::OR
, TmpReg
, DstReg
, Mips::ZERO
, IDLoc
, STI
);
4421 bool MipsAsmParser::expandSge(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4422 const MCSubtargetInfo
*STI
) {
4423 MipsTargetStreamer
&TOut
= getTargetStreamer();
4425 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4426 assert(Inst
.getOperand(0).isReg() &&
4427 Inst
.getOperand(1).isReg() &&
4428 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
4430 unsigned DstReg
= Inst
.getOperand(0).getReg();
4431 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4432 unsigned OpReg
= Inst
.getOperand(2).getReg();
4435 warnIfNoMacro(IDLoc
);
4437 switch (Inst
.getOpcode()) {
4442 OpCode
= Mips::SLTu
;
4445 llvm_unreachable("unexpected 'sge' opcode");
4448 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4449 TOut
.emitRRR(OpCode
, DstReg
, SrcReg
, OpReg
, IDLoc
, STI
);
4450 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4455 bool MipsAsmParser::expandSgeImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4456 const MCSubtargetInfo
*STI
) {
4457 MipsTargetStreamer
&TOut
= getTargetStreamer();
4459 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4460 assert(Inst
.getOperand(0).isReg() &&
4461 Inst
.getOperand(1).isReg() &&
4462 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4464 unsigned DstReg
= Inst
.getOperand(0).getReg();
4465 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4466 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4467 unsigned OpRegCode
, OpImmCode
;
4469 warnIfNoMacro(IDLoc
);
4471 switch (Inst
.getOpcode()) {
4473 case Mips::SGEImm64
:
4474 OpRegCode
= Mips::SLT
;
4475 OpImmCode
= Mips::SLTi
;
4478 case Mips::SGEUImm64
:
4479 OpRegCode
= Mips::SLTu
;
4480 OpImmCode
= Mips::SLTiu
;
4483 llvm_unreachable("unexpected 'sge' opcode with immediate");
4486 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4487 if (isInt
<16>(ImmValue
)) {
4488 // Use immediate version of STL.
4489 TOut
.emitRRI(OpImmCode
, DstReg
, SrcReg
, ImmValue
, IDLoc
, STI
);
4490 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4492 unsigned ImmReg
= DstReg
;
4493 if (DstReg
== SrcReg
) {
4494 unsigned ATReg
= getATReg(Inst
.getLoc());
4500 if (loadImmediate(ImmValue
, ImmReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4501 false, IDLoc
, Out
, STI
))
4504 TOut
.emitRRR(OpRegCode
, DstReg
, SrcReg
, ImmReg
, IDLoc
, STI
);
4505 TOut
.emitRRI(Mips::XORi
, DstReg
, DstReg
, 1, IDLoc
, STI
);
4511 bool MipsAsmParser::expandSgtImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4512 const MCSubtargetInfo
*STI
) {
4513 MipsTargetStreamer
&TOut
= getTargetStreamer();
4515 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4516 assert(Inst
.getOperand(0).isReg() &&
4517 Inst
.getOperand(1).isReg() &&
4518 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4520 unsigned DstReg
= Inst
.getOperand(0).getReg();
4521 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4522 unsigned ImmReg
= DstReg
;
4523 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4526 warnIfNoMacro(IDLoc
);
4528 switch (Inst
.getOpcode()) {
4530 case Mips::SGTImm64
:
4534 case Mips::SGTUImm64
:
4535 OpCode
= Mips::SLTu
;
4538 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4541 if (DstReg
== SrcReg
) {
4542 unsigned ATReg
= getATReg(Inst
.getLoc());
4548 if (loadImmediate(ImmValue
, ImmReg
, Mips::NoRegister
, isInt
<32>(ImmValue
),
4549 false, IDLoc
, Out
, STI
))
4552 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4553 TOut
.emitRRR(OpCode
, DstReg
, ImmReg
, SrcReg
, IDLoc
, STI
);
4558 bool MipsAsmParser::expandAliasImmediate(MCInst
&Inst
, SMLoc IDLoc
,
4560 const MCSubtargetInfo
*STI
) {
4561 MipsTargetStreamer
&TOut
= getTargetStreamer();
4563 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
4564 assert(Inst
.getOperand(0).isReg() &&
4565 Inst
.getOperand(1).isReg() &&
4566 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
4568 unsigned ATReg
= Mips::NoRegister
;
4569 unsigned FinalDstReg
= Mips::NoRegister
;
4570 unsigned DstReg
= Inst
.getOperand(0).getReg();
4571 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4572 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4574 bool Is32Bit
= isInt
<32>(ImmValue
) || (!isGP64bit() && isUInt
<32>(ImmValue
));
4576 unsigned FinalOpcode
= Inst
.getOpcode();
4578 if (DstReg
== SrcReg
) {
4579 ATReg
= getATReg(Inst
.getLoc());
4582 FinalDstReg
= DstReg
;
4586 if (!loadImmediate(ImmValue
, DstReg
, Mips::NoRegister
, Is32Bit
, false,
4587 Inst
.getLoc(), Out
, STI
)) {
4588 switch (FinalOpcode
) {
4590 llvm_unreachable("unimplemented expansion");
4592 FinalOpcode
= Mips::ADD
;
4595 FinalOpcode
= Mips::ADDu
;
4598 FinalOpcode
= Mips::AND
;
4601 FinalOpcode
= Mips::NOR
;
4604 FinalOpcode
= Mips::OR
;
4607 FinalOpcode
= Mips::SLT
;
4610 FinalOpcode
= Mips::SLTu
;
4613 FinalOpcode
= Mips::XOR
;
4616 FinalOpcode
= Mips::ADD_MM
;
4618 case Mips::ADDiu_MM
:
4619 FinalOpcode
= Mips::ADDu_MM
;
4622 FinalOpcode
= Mips::AND_MM
;
4625 FinalOpcode
= Mips::OR_MM
;
4628 FinalOpcode
= Mips::SLT_MM
;
4630 case Mips::SLTiu_MM
:
4631 FinalOpcode
= Mips::SLTu_MM
;
4634 FinalOpcode
= Mips::XOR_MM
;
4637 FinalOpcode
= Mips::AND64
;
4639 case Mips::NORImm64
:
4640 FinalOpcode
= Mips::NOR64
;
4643 FinalOpcode
= Mips::OR64
;
4645 case Mips::SLTImm64
:
4646 FinalOpcode
= Mips::SLT64
;
4648 case Mips::SLTUImm64
:
4649 FinalOpcode
= Mips::SLTu64
;
4652 FinalOpcode
= Mips::XOR64
;
4656 if (FinalDstReg
== Mips::NoRegister
)
4657 TOut
.emitRRR(FinalOpcode
, DstReg
, DstReg
, SrcReg
, IDLoc
, STI
);
4659 TOut
.emitRRR(FinalOpcode
, FinalDstReg
, FinalDstReg
, DstReg
, IDLoc
, STI
);
4665 bool MipsAsmParser::expandRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4666 const MCSubtargetInfo
*STI
) {
4667 MipsTargetStreamer
&TOut
= getTargetStreamer();
4668 unsigned ATReg
= Mips::NoRegister
;
4669 unsigned DReg
= Inst
.getOperand(0).getReg();
4670 unsigned SReg
= Inst
.getOperand(1).getReg();
4671 unsigned TReg
= Inst
.getOperand(2).getReg();
4672 unsigned TmpReg
= DReg
;
4674 unsigned FirstShift
= Mips::NOP
;
4675 unsigned SecondShift
= Mips::NOP
;
4677 if (hasMips32r2()) {
4679 TmpReg
= getATReg(Inst
.getLoc());
4684 if (Inst
.getOpcode() == Mips::ROL
) {
4685 TOut
.emitRRR(Mips::SUBu
, TmpReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4686 TOut
.emitRRR(Mips::ROTRV
, DReg
, SReg
, TmpReg
, Inst
.getLoc(), STI
);
4690 if (Inst
.getOpcode() == Mips::ROR
) {
4691 TOut
.emitRRR(Mips::ROTRV
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4699 switch (Inst
.getOpcode()) {
4701 llvm_unreachable("unexpected instruction opcode");
4703 FirstShift
= Mips::SRLV
;
4704 SecondShift
= Mips::SLLV
;
4707 FirstShift
= Mips::SLLV
;
4708 SecondShift
= Mips::SRLV
;
4712 ATReg
= getATReg(Inst
.getLoc());
4716 TOut
.emitRRR(Mips::SUBu
, ATReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4717 TOut
.emitRRR(FirstShift
, ATReg
, SReg
, ATReg
, Inst
.getLoc(), STI
);
4718 TOut
.emitRRR(SecondShift
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4719 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4727 bool MipsAsmParser::expandRotationImm(MCInst
&Inst
, SMLoc IDLoc
,
4729 const MCSubtargetInfo
*STI
) {
4730 MipsTargetStreamer
&TOut
= getTargetStreamer();
4731 unsigned ATReg
= Mips::NoRegister
;
4732 unsigned DReg
= Inst
.getOperand(0).getReg();
4733 unsigned SReg
= Inst
.getOperand(1).getReg();
4734 int64_t ImmValue
= Inst
.getOperand(2).getImm();
4736 unsigned FirstShift
= Mips::NOP
;
4737 unsigned SecondShift
= Mips::NOP
;
4739 if (hasMips32r2()) {
4740 if (Inst
.getOpcode() == Mips::ROLImm
) {
4741 uint64_t MaxShift
= 32;
4742 uint64_t ShiftValue
= ImmValue
;
4744 ShiftValue
= MaxShift
- ImmValue
;
4745 TOut
.emitRRI(Mips::ROTR
, DReg
, SReg
, ShiftValue
, Inst
.getLoc(), STI
);
4749 if (Inst
.getOpcode() == Mips::RORImm
) {
4750 TOut
.emitRRI(Mips::ROTR
, DReg
, SReg
, ImmValue
, Inst
.getLoc(), STI
);
4758 if (ImmValue
== 0) {
4759 TOut
.emitRRI(Mips::SRL
, DReg
, SReg
, 0, Inst
.getLoc(), STI
);
4763 switch (Inst
.getOpcode()) {
4765 llvm_unreachable("unexpected instruction opcode");
4767 FirstShift
= Mips::SLL
;
4768 SecondShift
= Mips::SRL
;
4771 FirstShift
= Mips::SRL
;
4772 SecondShift
= Mips::SLL
;
4776 ATReg
= getATReg(Inst
.getLoc());
4780 TOut
.emitRRI(FirstShift
, ATReg
, SReg
, ImmValue
, Inst
.getLoc(), STI
);
4781 TOut
.emitRRI(SecondShift
, DReg
, SReg
, 32 - ImmValue
, Inst
.getLoc(), STI
);
4782 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4790 bool MipsAsmParser::expandDRotation(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4791 const MCSubtargetInfo
*STI
) {
4792 MipsTargetStreamer
&TOut
= getTargetStreamer();
4793 unsigned ATReg
= Mips::NoRegister
;
4794 unsigned DReg
= Inst
.getOperand(0).getReg();
4795 unsigned SReg
= Inst
.getOperand(1).getReg();
4796 unsigned TReg
= Inst
.getOperand(2).getReg();
4797 unsigned TmpReg
= DReg
;
4799 unsigned FirstShift
= Mips::NOP
;
4800 unsigned SecondShift
= Mips::NOP
;
4802 if (hasMips64r2()) {
4803 if (TmpReg
== SReg
) {
4804 TmpReg
= getATReg(Inst
.getLoc());
4809 if (Inst
.getOpcode() == Mips::DROL
) {
4810 TOut
.emitRRR(Mips::DSUBu
, TmpReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4811 TOut
.emitRRR(Mips::DROTRV
, DReg
, SReg
, TmpReg
, Inst
.getLoc(), STI
);
4815 if (Inst
.getOpcode() == Mips::DROR
) {
4816 TOut
.emitRRR(Mips::DROTRV
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4824 switch (Inst
.getOpcode()) {
4826 llvm_unreachable("unexpected instruction opcode");
4828 FirstShift
= Mips::DSRLV
;
4829 SecondShift
= Mips::DSLLV
;
4832 FirstShift
= Mips::DSLLV
;
4833 SecondShift
= Mips::DSRLV
;
4837 ATReg
= getATReg(Inst
.getLoc());
4841 TOut
.emitRRR(Mips::DSUBu
, ATReg
, Mips::ZERO
, TReg
, Inst
.getLoc(), STI
);
4842 TOut
.emitRRR(FirstShift
, ATReg
, SReg
, ATReg
, Inst
.getLoc(), STI
);
4843 TOut
.emitRRR(SecondShift
, DReg
, SReg
, TReg
, Inst
.getLoc(), STI
);
4844 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4852 bool MipsAsmParser::expandDRotationImm(MCInst
&Inst
, SMLoc IDLoc
,
4854 const MCSubtargetInfo
*STI
) {
4855 MipsTargetStreamer
&TOut
= getTargetStreamer();
4856 unsigned ATReg
= Mips::NoRegister
;
4857 unsigned DReg
= Inst
.getOperand(0).getReg();
4858 unsigned SReg
= Inst
.getOperand(1).getReg();
4859 int64_t ImmValue
= Inst
.getOperand(2).getImm() % 64;
4861 unsigned FirstShift
= Mips::NOP
;
4862 unsigned SecondShift
= Mips::NOP
;
4866 if (hasMips64r2()) {
4867 unsigned FinalOpcode
= Mips::NOP
;
4869 FinalOpcode
= Mips::DROTR
;
4870 else if (ImmValue
% 32 == 0)
4871 FinalOpcode
= Mips::DROTR32
;
4872 else if ((ImmValue
>= 1) && (ImmValue
<= 32)) {
4873 if (Inst
.getOpcode() == Mips::DROLImm
)
4874 FinalOpcode
= Mips::DROTR32
;
4876 FinalOpcode
= Mips::DROTR
;
4877 } else if (ImmValue
>= 33) {
4878 if (Inst
.getOpcode() == Mips::DROLImm
)
4879 FinalOpcode
= Mips::DROTR
;
4881 FinalOpcode
= Mips::DROTR32
;
4884 uint64_t ShiftValue
= ImmValue
% 32;
4885 if (Inst
.getOpcode() == Mips::DROLImm
)
4886 ShiftValue
= (32 - ImmValue
% 32) % 32;
4888 TOut
.emitRRI(FinalOpcode
, DReg
, SReg
, ShiftValue
, Inst
.getLoc(), STI
);
4894 if (ImmValue
== 0) {
4895 TOut
.emitRRI(Mips::DSRL
, DReg
, SReg
, 0, Inst
.getLoc(), STI
);
4899 switch (Inst
.getOpcode()) {
4901 llvm_unreachable("unexpected instruction opcode");
4903 if ((ImmValue
>= 1) && (ImmValue
<= 31)) {
4904 FirstShift
= Mips::DSLL
;
4905 SecondShift
= Mips::DSRL32
;
4907 if (ImmValue
== 32) {
4908 FirstShift
= Mips::DSLL32
;
4909 SecondShift
= Mips::DSRL32
;
4911 if ((ImmValue
>= 33) && (ImmValue
<= 63)) {
4912 FirstShift
= Mips::DSLL32
;
4913 SecondShift
= Mips::DSRL
;
4917 if ((ImmValue
>= 1) && (ImmValue
<= 31)) {
4918 FirstShift
= Mips::DSRL
;
4919 SecondShift
= Mips::DSLL32
;
4921 if (ImmValue
== 32) {
4922 FirstShift
= Mips::DSRL32
;
4923 SecondShift
= Mips::DSLL32
;
4925 if ((ImmValue
>= 33) && (ImmValue
<= 63)) {
4926 FirstShift
= Mips::DSRL32
;
4927 SecondShift
= Mips::DSLL
;
4932 ATReg
= getATReg(Inst
.getLoc());
4936 TOut
.emitRRI(FirstShift
, ATReg
, SReg
, ImmValue
% 32, Inst
.getLoc(), STI
);
4937 TOut
.emitRRI(SecondShift
, DReg
, SReg
, (32 - ImmValue
% 32) % 32,
4938 Inst
.getLoc(), STI
);
4939 TOut
.emitRRR(Mips::OR
, DReg
, DReg
, ATReg
, Inst
.getLoc(), STI
);
4947 bool MipsAsmParser::expandAbs(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4948 const MCSubtargetInfo
*STI
) {
4949 MipsTargetStreamer
&TOut
= getTargetStreamer();
4950 unsigned FirstRegOp
= Inst
.getOperand(0).getReg();
4951 unsigned SecondRegOp
= Inst
.getOperand(1).getReg();
4953 TOut
.emitRI(Mips::BGEZ
, SecondRegOp
, 8, IDLoc
, STI
);
4954 if (FirstRegOp
!= SecondRegOp
)
4955 TOut
.emitRRR(Mips::ADDu
, FirstRegOp
, SecondRegOp
, Mips::ZERO
, IDLoc
, STI
);
4957 TOut
.emitEmptyDelaySlot(false, IDLoc
, STI
);
4958 TOut
.emitRRR(Mips::SUB
, FirstRegOp
, Mips::ZERO
, SecondRegOp
, IDLoc
, STI
);
4963 bool MipsAsmParser::expandMulImm(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4964 const MCSubtargetInfo
*STI
) {
4965 MipsTargetStreamer
&TOut
= getTargetStreamer();
4966 unsigned ATReg
= Mips::NoRegister
;
4967 unsigned DstReg
= Inst
.getOperand(0).getReg();
4968 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4969 int32_t ImmValue
= Inst
.getOperand(2).getImm();
4971 ATReg
= getATReg(IDLoc
);
4975 loadImmediate(ImmValue
, ATReg
, Mips::NoRegister
, true, false, IDLoc
, Out
,
4978 TOut
.emitRR(Inst
.getOpcode() == Mips::MULImmMacro
? Mips::MULT
: Mips::DMULT
,
4979 SrcReg
, ATReg
, IDLoc
, STI
);
4981 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
4986 bool MipsAsmParser::expandMulO(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
4987 const MCSubtargetInfo
*STI
) {
4988 MipsTargetStreamer
&TOut
= getTargetStreamer();
4989 unsigned ATReg
= Mips::NoRegister
;
4990 unsigned DstReg
= Inst
.getOperand(0).getReg();
4991 unsigned SrcReg
= Inst
.getOperand(1).getReg();
4992 unsigned TmpReg
= Inst
.getOperand(2).getReg();
4994 ATReg
= getATReg(Inst
.getLoc());
4998 TOut
.emitRR(Inst
.getOpcode() == Mips::MULOMacro
? Mips::MULT
: Mips::DMULT
,
4999 SrcReg
, TmpReg
, IDLoc
, STI
);
5001 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5003 TOut
.emitRRI(Inst
.getOpcode() == Mips::MULOMacro
? Mips::SRA
: Mips::DSRA32
,
5004 DstReg
, DstReg
, 0x1F, IDLoc
, STI
);
5006 TOut
.emitR(Mips::MFHI
, ATReg
, IDLoc
, STI
);
5009 TOut
.emitRRI(Mips::TNE
, DstReg
, ATReg
, 6, IDLoc
, STI
);
5011 MCContext
& Context
= TOut
.getStreamer().getContext();
5012 MCSymbol
* BrTarget
= Context
.createTempSymbol();
5014 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
5016 TOut
.emitRRX(Mips::BEQ
, DstReg
, ATReg
, LabelOp
, IDLoc
, STI
);
5017 if (AssemblerOptions
.back()->isReorder())
5018 TOut
.emitNop(IDLoc
, STI
);
5019 TOut
.emitII(Mips::BREAK
, 6, 0, IDLoc
, STI
);
5021 TOut
.getStreamer().EmitLabel(BrTarget
);
5023 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5028 bool MipsAsmParser::expandMulOU(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5029 const MCSubtargetInfo
*STI
) {
5030 MipsTargetStreamer
&TOut
= getTargetStreamer();
5031 unsigned ATReg
= Mips::NoRegister
;
5032 unsigned DstReg
= Inst
.getOperand(0).getReg();
5033 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5034 unsigned TmpReg
= Inst
.getOperand(2).getReg();
5036 ATReg
= getATReg(IDLoc
);
5040 TOut
.emitRR(Inst
.getOpcode() == Mips::MULOUMacro
? Mips::MULTu
: Mips::DMULTu
,
5041 SrcReg
, TmpReg
, IDLoc
, STI
);
5043 TOut
.emitR(Mips::MFHI
, ATReg
, IDLoc
, STI
);
5044 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5046 TOut
.emitRRI(Mips::TNE
, ATReg
, Mips::ZERO
, 6, IDLoc
, STI
);
5048 MCContext
& Context
= TOut
.getStreamer().getContext();
5049 MCSymbol
* BrTarget
= Context
.createTempSymbol();
5051 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget
, Context
));
5053 TOut
.emitRRX(Mips::BEQ
, ATReg
, Mips::ZERO
, LabelOp
, IDLoc
, STI
);
5054 if (AssemblerOptions
.back()->isReorder())
5055 TOut
.emitNop(IDLoc
, STI
);
5056 TOut
.emitII(Mips::BREAK
, 6, 0, IDLoc
, STI
);
5058 TOut
.getStreamer().EmitLabel(BrTarget
);
5064 bool MipsAsmParser::expandDMULMacro(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5065 const MCSubtargetInfo
*STI
) {
5066 MipsTargetStreamer
&TOut
= getTargetStreamer();
5067 unsigned DstReg
= Inst
.getOperand(0).getReg();
5068 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5069 unsigned TmpReg
= Inst
.getOperand(2).getReg();
5071 TOut
.emitRR(Mips::DMULTu
, SrcReg
, TmpReg
, IDLoc
, STI
);
5072 TOut
.emitR(Mips::MFLO
, DstReg
, IDLoc
, STI
);
5077 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5078 // lw $<reg+1>>, offset+4($reg2)'
5079 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5080 // sw $<reg+1>>, offset+4($reg2)'
5082 bool MipsAsmParser::expandLoadStoreDMacro(MCInst
&Inst
, SMLoc IDLoc
,
5084 const MCSubtargetInfo
*STI
,
5089 warnIfNoMacro(IDLoc
);
5091 MipsTargetStreamer
&TOut
= getTargetStreamer();
5092 unsigned Opcode
= IsLoad
? Mips::LW
: Mips::SW
;
5093 unsigned FirstReg
= Inst
.getOperand(0).getReg();
5094 unsigned SecondReg
= nextReg(FirstReg
);
5095 unsigned BaseReg
= Inst
.getOperand(1).getReg();
5099 warnIfRegIndexIsAT(FirstReg
, IDLoc
);
5101 assert(Inst
.getOperand(2).isImm() &&
5102 "Offset for load macro is not immediate!");
5104 MCOperand
&FirstOffset
= Inst
.getOperand(2);
5105 signed NextOffset
= FirstOffset
.getImm() + 4;
5106 MCOperand SecondOffset
= MCOperand::createImm(NextOffset
);
5108 if (!isInt
<16>(FirstOffset
.getImm()) || !isInt
<16>(NextOffset
))
5111 // For loads, clobber the base register with the second load instead of the
5112 // first if the BaseReg == FirstReg.
5113 if (FirstReg
!= BaseReg
|| !IsLoad
) {
5114 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5115 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5117 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5118 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5125 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5126 // swc1 $<reg>, offset+4($reg2)'
5127 // or if little endian to 'swc1 $<reg>, offset($reg2);
5128 // swc1 $<reg+1>, offset+4($reg2)'
5130 bool MipsAsmParser::expandStoreDM1Macro(MCInst
&Inst
, SMLoc IDLoc
,
5132 const MCSubtargetInfo
*STI
) {
5136 warnIfNoMacro(IDLoc
);
5138 MipsTargetStreamer
&TOut
= getTargetStreamer();
5139 unsigned Opcode
= Mips::SWC1
;
5140 unsigned FirstReg
= Inst
.getOperand(0).getReg();
5141 unsigned SecondReg
= nextReg(FirstReg
);
5142 unsigned BaseReg
= Inst
.getOperand(1).getReg();
5146 warnIfRegIndexIsAT(FirstReg
, IDLoc
);
5148 assert(Inst
.getOperand(2).isImm() &&
5149 "Offset for macro is not immediate!");
5151 MCOperand
&FirstOffset
= Inst
.getOperand(2);
5152 signed NextOffset
= FirstOffset
.getImm() + 4;
5153 MCOperand SecondOffset
= MCOperand::createImm(NextOffset
);
5155 if (!isInt
<16>(FirstOffset
.getImm()) || !isInt
<16>(NextOffset
))
5158 if (!IsLittleEndian
)
5159 std::swap(FirstReg
, SecondReg
);
5161 TOut
.emitRRX(Opcode
, FirstReg
, BaseReg
, FirstOffset
, IDLoc
, STI
);
5162 TOut
.emitRRX(Opcode
, SecondReg
, BaseReg
, SecondOffset
, IDLoc
, STI
);
5167 bool MipsAsmParser::expandSeq(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5168 const MCSubtargetInfo
*STI
) {
5169 MipsTargetStreamer
&TOut
= getTargetStreamer();
5171 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5172 assert(Inst
.getOperand(0).isReg() &&
5173 Inst
.getOperand(1).isReg() &&
5174 Inst
.getOperand(2).isReg() && "Invalid instruction operand.");
5176 unsigned DstReg
= Inst
.getOperand(0).getReg();
5177 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5178 unsigned OpReg
= Inst
.getOperand(2).getReg();
5180 warnIfNoMacro(IDLoc
);
5182 if (SrcReg
!= Mips::ZERO
&& OpReg
!= Mips::ZERO
) {
5183 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, OpReg
, IDLoc
, STI
);
5184 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5188 unsigned Reg
= SrcReg
== Mips::ZERO
? OpReg
: SrcReg
;
5189 TOut
.emitRRI(Mips::SLTiu
, DstReg
, Reg
, 1, IDLoc
, STI
);
5193 bool MipsAsmParser::expandSeqI(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5194 const MCSubtargetInfo
*STI
) {
5195 MipsTargetStreamer
&TOut
= getTargetStreamer();
5197 assert(Inst
.getNumOperands() == 3 && "Invalid operand count");
5198 assert(Inst
.getOperand(0).isReg() &&
5199 Inst
.getOperand(1).isReg() &&
5200 Inst
.getOperand(2).isImm() && "Invalid instruction operand.");
5202 unsigned DstReg
= Inst
.getOperand(0).getReg();
5203 unsigned SrcReg
= Inst
.getOperand(1).getReg();
5204 int64_t Imm
= Inst
.getOperand(2).getImm();
5206 warnIfNoMacro(IDLoc
);
5209 TOut
.emitRRI(Mips::SLTiu
, DstReg
, SrcReg
, 1, IDLoc
, STI
);
5213 if (SrcReg
== Mips::ZERO
) {
5214 Warning(IDLoc
, "comparison is always false");
5215 TOut
.emitRRR(isGP64bit() ? Mips::DADDu
: Mips::ADDu
,
5216 DstReg
, SrcReg
, SrcReg
, IDLoc
, STI
);
5221 if (Imm
> -0x8000 && Imm
< 0) {
5223 Opc
= isGP64bit() ? Mips::DADDiu
: Mips::ADDiu
;
5228 if (!isUInt
<16>(Imm
)) {
5229 unsigned ATReg
= getATReg(IDLoc
);
5233 if (loadImmediate(Imm
, ATReg
, Mips::NoRegister
, true, isGP64bit(), IDLoc
,
5237 TOut
.emitRRR(Mips::XOR
, DstReg
, SrcReg
, ATReg
, IDLoc
, STI
);
5238 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5242 TOut
.emitRRI(Opc
, DstReg
, SrcReg
, Imm
, IDLoc
, STI
);
5243 TOut
.emitRRI(Mips::SLTiu
, DstReg
, DstReg
, 1, IDLoc
, STI
);
5247 // Map the DSP accumulator and control register to the corresponding gpr
5248 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5249 // do not map the DSP registers contigously to gpr registers.
5250 static unsigned getRegisterForMxtrDSP(MCInst
&Inst
, bool IsMFDSP
) {
5251 switch (Inst
.getOpcode()) {
5254 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5264 llvm_unreachable("Unknown register for 'mttr' alias!");
5268 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5278 llvm_unreachable("Unknown register for 'mttr' alias!");
5282 switch (Inst
.getOperand(IsMFDSP
? 1 : 0).getReg()) {
5292 llvm_unreachable("Unknown register for 'mttr' alias!");
5298 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5302 // Map the floating point register operand to the corresponding register
5304 static unsigned getRegisterForMxtrFP(MCInst
&Inst
, bool IsMFTC1
) {
5305 switch (Inst
.getOperand(IsMFTC1
? 1 : 0).getReg()) {
5306 case Mips::F0
: return Mips::ZERO
;
5307 case Mips::F1
: return Mips::AT
;
5308 case Mips::F2
: return Mips::V0
;
5309 case Mips::F3
: return Mips::V1
;
5310 case Mips::F4
: return Mips::A0
;
5311 case Mips::F5
: return Mips::A1
;
5312 case Mips::F6
: return Mips::A2
;
5313 case Mips::F7
: return Mips::A3
;
5314 case Mips::F8
: return Mips::T0
;
5315 case Mips::F9
: return Mips::T1
;
5316 case Mips::F10
: return Mips::T2
;
5317 case Mips::F11
: return Mips::T3
;
5318 case Mips::F12
: return Mips::T4
;
5319 case Mips::F13
: return Mips::T5
;
5320 case Mips::F14
: return Mips::T6
;
5321 case Mips::F15
: return Mips::T7
;
5322 case Mips::F16
: return Mips::S0
;
5323 case Mips::F17
: return Mips::S1
;
5324 case Mips::F18
: return Mips::S2
;
5325 case Mips::F19
: return Mips::S3
;
5326 case Mips::F20
: return Mips::S4
;
5327 case Mips::F21
: return Mips::S5
;
5328 case Mips::F22
: return Mips::S6
;
5329 case Mips::F23
: return Mips::S7
;
5330 case Mips::F24
: return Mips::T8
;
5331 case Mips::F25
: return Mips::T9
;
5332 case Mips::F26
: return Mips::K0
;
5333 case Mips::F27
: return Mips::K1
;
5334 case Mips::F28
: return Mips::GP
;
5335 case Mips::F29
: return Mips::SP
;
5336 case Mips::F30
: return Mips::FP
;
5337 case Mips::F31
: return Mips::RA
;
5338 default: llvm_unreachable("Unknown register for mttc1 alias!");
5342 // Map the coprocessor operand the corresponding gpr register operand.
5343 static unsigned getRegisterForMxtrC0(MCInst
&Inst
, bool IsMFTC0
) {
5344 switch (Inst
.getOperand(IsMFTC0
? 1 : 0).getReg()) {
5345 case Mips::COP00
: return Mips::ZERO
;
5346 case Mips::COP01
: return Mips::AT
;
5347 case Mips::COP02
: return Mips::V0
;
5348 case Mips::COP03
: return Mips::V1
;
5349 case Mips::COP04
: return Mips::A0
;
5350 case Mips::COP05
: return Mips::A1
;
5351 case Mips::COP06
: return Mips::A2
;
5352 case Mips::COP07
: return Mips::A3
;
5353 case Mips::COP08
: return Mips::T0
;
5354 case Mips::COP09
: return Mips::T1
;
5355 case Mips::COP010
: return Mips::T2
;
5356 case Mips::COP011
: return Mips::T3
;
5357 case Mips::COP012
: return Mips::T4
;
5358 case Mips::COP013
: return Mips::T5
;
5359 case Mips::COP014
: return Mips::T6
;
5360 case Mips::COP015
: return Mips::T7
;
5361 case Mips::COP016
: return Mips::S0
;
5362 case Mips::COP017
: return Mips::S1
;
5363 case Mips::COP018
: return Mips::S2
;
5364 case Mips::COP019
: return Mips::S3
;
5365 case Mips::COP020
: return Mips::S4
;
5366 case Mips::COP021
: return Mips::S5
;
5367 case Mips::COP022
: return Mips::S6
;
5368 case Mips::COP023
: return Mips::S7
;
5369 case Mips::COP024
: return Mips::T8
;
5370 case Mips::COP025
: return Mips::T9
;
5371 case Mips::COP026
: return Mips::K0
;
5372 case Mips::COP027
: return Mips::K1
;
5373 case Mips::COP028
: return Mips::GP
;
5374 case Mips::COP029
: return Mips::SP
;
5375 case Mips::COP030
: return Mips::FP
;
5376 case Mips::COP031
: return Mips::RA
;
5377 default: llvm_unreachable("Unknown register for mttc0 alias!");
5381 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5382 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5383 bool MipsAsmParser::expandMXTRAlias(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
5384 const MCSubtargetInfo
*STI
) {
5385 MipsTargetStreamer
&TOut
= getTargetStreamer();
5390 bool IsMFTR
= false;
5391 switch (Inst
.getOpcode()) {
5397 rd
= getRegisterForMxtrC0(Inst
, IsMFTR
);
5398 sel
= Inst
.getOperand(2).getImm();
5404 rd
= Inst
.getOperand(IsMFTR
? 1 : 0).getReg();
5416 rd
= getRegisterForMxtrDSP(Inst
, IsMFTR
);
5424 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5431 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5438 rd
= getRegisterForMxtrFP(Inst
, IsMFTR
);
5442 unsigned Op0
= IsMFTR
? Inst
.getOperand(0).getReg() : rd
;
5445 : (Inst
.getOpcode() != Mips::MTTDSP
? Inst
.getOperand(1).getReg()
5446 : Inst
.getOperand(0).getReg());
5448 TOut
.emitRRIII(IsMFTR
? Mips::MFTR
: Mips::MTTR
, Op0
, Op1
, u
, sel
, h
, IDLoc
,
5454 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst
&Inst
,
5455 const OperandVector
&Operands
) {
5456 switch (Inst
.getOpcode()) {
5458 return Match_Success
;
5461 if (static_cast<MipsOperand
&>(*Operands
[1])
5462 .isValidForTie(static_cast<MipsOperand
&>(*Operands
[2])))
5463 return Match_Success
;
5464 return Match_RequiresSameSrcAndDst
;
5468 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst
&Inst
) {
5469 switch (Inst
.getOpcode()) {
5470 // As described by the MIPSR6 spec, daui must not use the zero operand for
5471 // its source operand.
5473 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
5474 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
5475 return Match_RequiresNoZeroRegister
;
5476 return Match_Success
;
5477 // As described by the Mips32r2 spec, the registers Rd and Rs for
5478 // jalr.hb must be different.
5479 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5480 // and registers Rd and Base for microMIPS lwp instruction
5482 case Mips::JALR_HB64
:
5483 case Mips::JALRC_HB_MMR6
:
5484 case Mips::JALRC_MMR6
:
5485 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(1).getReg())
5486 return Match_RequiresDifferentSrcAndDst
;
5487 return Match_Success
;
5489 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(2).getReg())
5490 return Match_RequiresDifferentSrcAndDst
;
5491 return Match_Success
;
5493 if (Inst
.getOperand(0).getImm() != 0 && !hasMips32())
5494 return Match_NonZeroOperandForSync
;
5495 return Match_Success
;
5500 if (Inst
.getOperand(2).getImm() != 0 && !hasMips32())
5501 return Match_NonZeroOperandForMTCX
;
5502 return Match_Success
;
5503 // As described the MIPSR6 spec, the compact branches that compare registers
5505 // a) Not use the zero register.
5506 // b) Not use the same register twice.
5507 // c) rs < rt for bnec, beqc.
5508 // NB: For this case, the encoding will swap the operands as their
5509 // ordering doesn't matter. GAS performs this transformation too.
5510 // Hence, that constraint does not have to be enforced.
5512 // The compact branches that branch iff the signed addition of two registers
5513 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5514 // operand swapping. They do not have restriction of using the zero register.
5515 case Mips::BLEZC
: case Mips::BLEZC_MMR6
:
5516 case Mips::BGEZC
: case Mips::BGEZC_MMR6
:
5517 case Mips::BGTZC
: case Mips::BGTZC_MMR6
:
5518 case Mips::BLTZC
: case Mips::BLTZC_MMR6
:
5519 case Mips::BEQZC
: case Mips::BEQZC_MMR6
:
5520 case Mips::BNEZC
: case Mips::BNEZC_MMR6
:
5527 if (Inst
.getOperand(0).getReg() == Mips::ZERO
||
5528 Inst
.getOperand(0).getReg() == Mips::ZERO_64
)
5529 return Match_RequiresNoZeroRegister
;
5530 return Match_Success
;
5531 case Mips::BGEC
: case Mips::BGEC_MMR6
:
5532 case Mips::BLTC
: case Mips::BLTC_MMR6
:
5533 case Mips::BGEUC
: case Mips::BGEUC_MMR6
:
5534 case Mips::BLTUC
: case Mips::BLTUC_MMR6
:
5535 case Mips::BEQC
: case Mips::BEQC_MMR6
:
5536 case Mips::BNEC
: case Mips::BNEC_MMR6
:
5543 if (Inst
.getOperand(0).getReg() == Mips::ZERO
||
5544 Inst
.getOperand(0).getReg() == Mips::ZERO_64
)
5545 return Match_RequiresNoZeroRegister
;
5546 if (Inst
.getOperand(1).getReg() == Mips::ZERO
||
5547 Inst
.getOperand(1).getReg() == Mips::ZERO_64
)
5548 return Match_RequiresNoZeroRegister
;
5549 if (Inst
.getOperand(0).getReg() == Inst
.getOperand(1).getReg())
5550 return Match_RequiresDifferentOperands
;
5551 return Match_Success
;
5553 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5554 "Operands must be immediates for dins!");
5555 const signed Pos
= Inst
.getOperand(2).getImm();
5556 const signed Size
= Inst
.getOperand(3).getImm();
5557 if ((0 > (Pos
+ Size
)) || ((Pos
+ Size
) > 32))
5558 return Match_RequiresPosSizeRange0_32
;
5559 return Match_Success
;
5563 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5564 "Operands must be immediates for dinsm/dinsu!");
5565 const signed Pos
= Inst
.getOperand(2).getImm();
5566 const signed Size
= Inst
.getOperand(3).getImm();
5567 if ((32 >= (Pos
+ Size
)) || ((Pos
+ Size
) > 64))
5568 return Match_RequiresPosSizeRange33_64
;
5569 return Match_Success
;
5572 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5573 "Operands must be immediates for DEXTM!");
5574 const signed Pos
= Inst
.getOperand(2).getImm();
5575 const signed Size
= Inst
.getOperand(3).getImm();
5576 if ((1 > (Pos
+ Size
)) || ((Pos
+ Size
) > 63))
5577 return Match_RequiresPosSizeUImm6
;
5578 return Match_Success
;
5582 assert(Inst
.getOperand(2).isImm() && Inst
.getOperand(3).isImm() &&
5583 "Operands must be immediates for dextm/dextu!");
5584 const signed Pos
= Inst
.getOperand(2).getImm();
5585 const signed Size
= Inst
.getOperand(3).getImm();
5586 if ((32 > (Pos
+ Size
)) || ((Pos
+ Size
) > 64))
5587 return Match_RequiresPosSizeRange33_64
;
5588 return Match_Success
;
5590 case Mips::CRC32B
: case Mips::CRC32CB
:
5591 case Mips::CRC32H
: case Mips::CRC32CH
:
5592 case Mips::CRC32W
: case Mips::CRC32CW
:
5593 case Mips::CRC32D
: case Mips::CRC32CD
:
5594 if (Inst
.getOperand(0).getReg() != Inst
.getOperand(2).getReg())
5595 return Match_RequiresSameSrcAndDst
;
5596 return Match_Success
;
5599 uint64_t TSFlags
= getInstDesc(Inst
.getOpcode()).TSFlags
;
5600 if ((TSFlags
& MipsII::HasFCCRegOperand
) &&
5601 (Inst
.getOperand(0).getReg() != Mips::FCC0
) && !hasEightFccRegisters())
5602 return Match_NoFCCRegisterForCurrentISA
;
5604 return Match_Success
;
5608 static SMLoc
RefineErrorLoc(const SMLoc Loc
, const OperandVector
&Operands
,
5609 uint64_t ErrorInfo
) {
5610 if (ErrorInfo
!= ~0ULL && ErrorInfo
< Operands
.size()) {
5611 SMLoc ErrorLoc
= Operands
[ErrorInfo
]->getStartLoc();
5612 if (ErrorLoc
== SMLoc())
5619 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
5620 OperandVector
&Operands
,
5622 uint64_t &ErrorInfo
,
5623 bool MatchingInlineAsm
) {
5625 unsigned MatchResult
=
5626 MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
);
5628 switch (MatchResult
) {
5630 if (processInstruction(Inst
, IDLoc
, Out
, STI
))
5633 case Match_MissingFeature
:
5634 Error(IDLoc
, "instruction requires a CPU feature not currently enabled");
5636 case Match_InvalidOperand
: {
5637 SMLoc ErrorLoc
= IDLoc
;
5638 if (ErrorInfo
!= ~0ULL) {
5639 if (ErrorInfo
>= Operands
.size())
5640 return Error(IDLoc
, "too few operands for instruction");
5642 ErrorLoc
= Operands
[ErrorInfo
]->getStartLoc();
5643 if (ErrorLoc
== SMLoc())
5647 return Error(ErrorLoc
, "invalid operand for instruction");
5649 case Match_NonZeroOperandForSync
:
5651 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5652 case Match_NonZeroOperandForMTCX
:
5653 return Error(IDLoc
, "selector must be zero for pre-MIPS32 ISAs");
5654 case Match_MnemonicFail
:
5655 return Error(IDLoc
, "invalid instruction");
5656 case Match_RequiresDifferentSrcAndDst
:
5657 return Error(IDLoc
, "source and destination must be different");
5658 case Match_RequiresDifferentOperands
:
5659 return Error(IDLoc
, "registers must be different");
5660 case Match_RequiresNoZeroRegister
:
5661 return Error(IDLoc
, "invalid operand ($zero) for instruction");
5662 case Match_RequiresSameSrcAndDst
:
5663 return Error(IDLoc
, "source and destination must match");
5664 case Match_NoFCCRegisterForCurrentISA
:
5665 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5666 "non-zero fcc register doesn't exist in current ISA level");
5668 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
), "expected '0'");
5670 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5671 "expected 1-bit unsigned immediate");
5673 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5674 "expected 2-bit unsigned immediate");
5676 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5677 "expected immediate in range 1 .. 4");
5679 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5680 "expected 3-bit unsigned immediate");
5682 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5683 "expected 4-bit unsigned immediate");
5685 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5686 "expected 4-bit signed immediate");
5688 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5689 "expected 5-bit unsigned immediate");
5691 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5692 "expected 5-bit signed immediate");
5694 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5695 "expected immediate in range 1 .. 32");
5696 case Match_UImm5_32
:
5697 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5698 "expected immediate in range 32 .. 63");
5699 case Match_UImm5_33
:
5700 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5701 "expected immediate in range 33 .. 64");
5702 case Match_UImm5_0_Report_UImm6
:
5703 // This is used on UImm5 operands that have a corresponding UImm5_32
5704 // operand to avoid confusing the user.
5705 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5706 "expected 6-bit unsigned immediate");
5707 case Match_UImm5_Lsl2
:
5708 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5709 "expected both 7-bit unsigned immediate and multiple of 4");
5710 case Match_UImmRange2_64
:
5711 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5712 "expected immediate in range 2 .. 64");
5714 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5715 "expected 6-bit unsigned immediate");
5716 case Match_UImm6_Lsl2
:
5717 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5718 "expected both 8-bit unsigned immediate and multiple of 4");
5720 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5721 "expected 6-bit signed immediate");
5723 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5724 "expected 7-bit unsigned immediate");
5725 case Match_UImm7_N1
:
5726 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5727 "expected immediate in range -1 .. 126");
5728 case Match_SImm7_Lsl2
:
5729 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5730 "expected both 9-bit signed immediate and multiple of 4");
5732 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5733 "expected 8-bit unsigned immediate");
5734 case Match_UImm10_0
:
5735 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5736 "expected 10-bit unsigned immediate");
5737 case Match_SImm10_0
:
5738 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5739 "expected 10-bit signed immediate");
5740 case Match_SImm11_0
:
5741 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5742 "expected 11-bit signed immediate");
5744 case Match_UImm16_Relaxed
:
5745 case Match_UImm16_AltRelaxed
:
5746 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5747 "expected 16-bit unsigned immediate");
5749 case Match_SImm16_Relaxed
:
5750 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5751 "expected 16-bit signed immediate");
5752 case Match_SImm19_Lsl2
:
5753 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5754 "expected both 19-bit signed immediate and multiple of 4");
5755 case Match_UImm20_0
:
5756 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5757 "expected 20-bit unsigned immediate");
5758 case Match_UImm26_0
:
5759 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5760 "expected 26-bit unsigned immediate");
5762 case Match_SImm32_Relaxed
:
5763 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5764 "expected 32-bit signed immediate");
5765 case Match_UImm32_Coerced
:
5766 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5767 "expected 32-bit immediate");
5768 case Match_MemSImm9
:
5769 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5770 "expected memory with 9-bit signed offset");
5771 case Match_MemSImm10
:
5772 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5773 "expected memory with 10-bit signed offset");
5774 case Match_MemSImm10Lsl1
:
5775 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5776 "expected memory with 11-bit signed offset and multiple of 2");
5777 case Match_MemSImm10Lsl2
:
5778 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5779 "expected memory with 12-bit signed offset and multiple of 4");
5780 case Match_MemSImm10Lsl3
:
5781 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5782 "expected memory with 13-bit signed offset and multiple of 8");
5783 case Match_MemSImm11
:
5784 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5785 "expected memory with 11-bit signed offset");
5786 case Match_MemSImm12
:
5787 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5788 "expected memory with 12-bit signed offset");
5789 case Match_MemSImm16
:
5790 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5791 "expected memory with 16-bit signed offset");
5792 case Match_MemSImmPtr
:
5793 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
5794 "expected memory with 32-bit signed offset");
5795 case Match_RequiresPosSizeRange0_32
: {
5796 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
5797 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
5798 return Error(ErrorStart
, "size plus position are not in the range 0 .. 32",
5799 SMRange(ErrorStart
, ErrorEnd
));
5801 case Match_RequiresPosSizeUImm6
: {
5802 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
5803 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
5804 return Error(ErrorStart
, "size plus position are not in the range 1 .. 63",
5805 SMRange(ErrorStart
, ErrorEnd
));
5807 case Match_RequiresPosSizeRange33_64
: {
5808 SMLoc ErrorStart
= Operands
[3]->getStartLoc();
5809 SMLoc ErrorEnd
= Operands
[4]->getEndLoc();
5810 return Error(ErrorStart
, "size plus position are not in the range 33 .. 64",
5811 SMRange(ErrorStart
, ErrorEnd
));
5815 llvm_unreachable("Implement any new match types added!");
5818 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex
, SMLoc Loc
) {
5819 if (RegIndex
!= 0 && AssemblerOptions
.back()->getATRegIndex() == RegIndex
)
5820 Warning(Loc
, "used $at (currently $" + Twine(RegIndex
) +
5821 ") without \".set noat\"");
5824 void MipsAsmParser::warnIfNoMacro(SMLoc Loc
) {
5825 if (!AssemblerOptions
.back()->isMacro())
5826 Warning(Loc
, "macro instruction expanded into multiple instructions");
5829 void MipsAsmParser::ConvertXWPOperands(MCInst
&Inst
,
5830 const OperandVector
&Operands
) {
5832 (Inst
.getOpcode() == Mips::LWP_MM
|| Inst
.getOpcode() == Mips::SWP_MM
) &&
5833 "Unexpected instruction!");
5834 ((MipsOperand
&)*Operands
[1]).addGPR32ZeroAsmRegOperands(Inst
, 1);
5835 int NextReg
= nextReg(((MipsOperand
&)*Operands
[1]).getGPR32Reg());
5836 Inst
.addOperand(MCOperand::createReg(NextReg
));
5837 ((MipsOperand
&)*Operands
[2]).addMemOperands(Inst
, 2);
5841 MipsAsmParser::printWarningWithFixIt(const Twine
&Msg
, const Twine
&FixMsg
,
5842 SMRange Range
, bool ShowColors
) {
5843 getSourceManager().PrintMessage(Range
.Start
, SourceMgr::DK_Warning
, Msg
,
5844 Range
, SMFixIt(Range
, FixMsg
),
5848 int MipsAsmParser::matchCPURegisterName(StringRef Name
) {
5851 CC
= StringSwitch
<unsigned>(Name
)
5853 .Cases("at", "AT", 1)
5887 if (!(isABI_N32() || isABI_N64()))
5890 if (12 <= CC
&& CC
<= 15) {
5891 // Name is one of t4-t7
5892 AsmToken RegTok
= getLexer().peekTok();
5893 SMRange RegRange
= RegTok
.getLocRange();
5895 StringRef FixedName
= StringSwitch
<StringRef
>(Name
)
5901 assert(FixedName
!= "" && "Register name is not one of t4-t7.");
5903 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5904 "Did you mean $" + FixedName
+ "?", RegRange
);
5907 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5908 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5909 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5910 if (8 <= CC
&& CC
<= 11)
5914 CC
= StringSwitch
<unsigned>(Name
)
5926 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name
) {
5929 CC
= StringSwitch
<unsigned>(Name
)
5930 .Case("hwr_cpunum", 0)
5931 .Case("hwr_synci_step", 1)
5933 .Case("hwr_ccres", 3)
5934 .Case("hwr_ulr", 29)
5940 int MipsAsmParser::matchFPURegisterName(StringRef Name
) {
5941 if (Name
[0] == 'f') {
5942 StringRef NumString
= Name
.substr(1);
5944 if (NumString
.getAsInteger(10, IntVal
))
5945 return -1; // This is not an integer.
5946 if (IntVal
> 31) // Maximum index for fpu register.
5953 int MipsAsmParser::matchFCCRegisterName(StringRef Name
) {
5954 if (Name
.startswith("fcc")) {
5955 StringRef NumString
= Name
.substr(3);
5957 if (NumString
.getAsInteger(10, IntVal
))
5958 return -1; // This is not an integer.
5959 if (IntVal
> 7) // There are only 8 fcc registers.
5966 int MipsAsmParser::matchACRegisterName(StringRef Name
) {
5967 if (Name
.startswith("ac")) {
5968 StringRef NumString
= Name
.substr(2);
5970 if (NumString
.getAsInteger(10, IntVal
))
5971 return -1; // This is not an integer.
5972 if (IntVal
> 3) // There are only 3 acc registers.
5979 int MipsAsmParser::matchMSA128RegisterName(StringRef Name
) {
5982 if (Name
.front() != 'w' || Name
.drop_front(1).getAsInteger(10, IntVal
))
5991 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name
) {
5994 CC
= StringSwitch
<unsigned>(Name
)
5997 .Case("msaaccess", 2)
5999 .Case("msamodify", 4)
6000 .Case("msarequest", 5)
6002 .Case("msaunmap", 7)
6008 bool MipsAsmParser::canUseATReg() {
6009 return AssemblerOptions
.back()->getATRegIndex() != 0;
6012 unsigned MipsAsmParser::getATReg(SMLoc Loc
) {
6013 unsigned ATIndex
= AssemblerOptions
.back()->getATRegIndex();
6015 reportParseError(Loc
,
6016 "pseudo-instruction requires $at, which is not available");
6019 unsigned AT
= getReg(
6020 (isGP64bit()) ? Mips::GPR64RegClassID
: Mips::GPR32RegClassID
, ATIndex
);
6024 unsigned MipsAsmParser::getReg(int RC
, int RegNo
) {
6025 return *(getContext().getRegisterInfo()->getRegClass(RC
).begin() + RegNo
);
6028 bool MipsAsmParser::parseOperand(OperandVector
&Operands
, StringRef Mnemonic
) {
6029 MCAsmParser
&Parser
= getParser();
6030 LLVM_DEBUG(dbgs() << "parseOperand\n");
6032 // Check if the current operand has a custom associated parser, if so, try to
6033 // custom parse the operand, or fallback to the general approach.
6034 OperandMatchResultTy ResTy
= MatchOperandParserImpl(Operands
, Mnemonic
);
6035 if (ResTy
== MatchOperand_Success
)
6037 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6038 // there was a match, but an error occurred, in which case, just return that
6039 // the operand parsing failed.
6040 if (ResTy
== MatchOperand_ParseFail
)
6043 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6045 switch (getLexer().getKind()) {
6046 case AsmToken::Dollar
: {
6047 // Parse the register.
6048 SMLoc S
= Parser
.getTok().getLoc();
6050 // Almost all registers have been parsed by custom parsers. There is only
6051 // one exception to this. $zero (and it's alias $0) will reach this point
6052 // for div, divu, and similar instructions because it is not an operand
6053 // to the instruction definition but an explicit register. Special case
6054 // this situation for now.
6055 if (parseAnyRegister(Operands
) != MatchOperand_NoMatch
)
6058 // Maybe it is a symbol reference.
6059 StringRef Identifier
;
6060 if (Parser
.parseIdentifier(Identifier
))
6063 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6064 MCSymbol
*Sym
= getContext().getOrCreateSymbol("$" + Identifier
);
6065 // Otherwise create a symbol reference.
6067 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
6069 Operands
.push_back(MipsOperand::CreateImm(Res
, S
, E
, *this));
6073 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6076 SMLoc S
= Parser
.getTok().getLoc(); // Start location of the operand.
6077 if (getParser().parseExpression(Expr
))
6080 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6082 Operands
.push_back(MipsOperand::CreateImm(Expr
, S
, E
, *this));
6085 } // switch(getLexer().getKind())
6089 bool MipsAsmParser::isEvaluated(const MCExpr
*Expr
) {
6090 switch (Expr
->getKind()) {
6091 case MCExpr::Constant
:
6093 case MCExpr::SymbolRef
:
6094 return (cast
<MCSymbolRefExpr
>(Expr
)->getKind() != MCSymbolRefExpr::VK_None
);
6095 case MCExpr::Binary
: {
6096 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Expr
);
6097 if (!isEvaluated(BE
->getLHS()))
6099 return isEvaluated(BE
->getRHS());
6102 return isEvaluated(cast
<MCUnaryExpr
>(Expr
)->getSubExpr());
6103 case MCExpr::Target
:
6109 bool MipsAsmParser::ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
,
6111 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Operands
;
6112 OperandMatchResultTy ResTy
= parseAnyRegister(Operands
);
6113 if (ResTy
== MatchOperand_Success
) {
6114 assert(Operands
.size() == 1);
6115 MipsOperand
&Operand
= static_cast<MipsOperand
&>(*Operands
.front());
6116 StartLoc
= Operand
.getStartLoc();
6117 EndLoc
= Operand
.getEndLoc();
6119 // AFAIK, we only support numeric registers and named GPR's in CFI
6121 // Don't worry about eating tokens before failing. Using an unrecognised
6122 // register is a parse error.
6123 if (Operand
.isGPRAsmReg()) {
6124 // Resolve to GPR32 or GPR64 appropriately.
6125 RegNo
= isGP64bit() ? Operand
.getGPR64Reg() : Operand
.getGPR32Reg();
6128 return (RegNo
== (unsigned)-1);
6131 assert(Operands
.size() == 0);
6132 return (RegNo
== (unsigned)-1);
6135 bool MipsAsmParser::parseMemOffset(const MCExpr
*&Res
, bool isParenExpr
) {
6139 return getParser().parseParenExprOfDepth(0, Res
, S
);
6140 return getParser().parseExpression(Res
);
6143 OperandMatchResultTy
6144 MipsAsmParser::parseMemOperand(OperandVector
&Operands
) {
6145 MCAsmParser
&Parser
= getParser();
6146 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6147 const MCExpr
*IdVal
= nullptr;
6149 bool isParenExpr
= false;
6150 OperandMatchResultTy Res
= MatchOperand_NoMatch
;
6151 // First operand is the offset.
6152 S
= Parser
.getTok().getLoc();
6154 if (getLexer().getKind() == AsmToken::LParen
) {
6159 if (getLexer().getKind() != AsmToken::Dollar
) {
6160 if (parseMemOffset(IdVal
, isParenExpr
))
6161 return MatchOperand_ParseFail
;
6163 const AsmToken
&Tok
= Parser
.getTok(); // Get the next token.
6164 if (Tok
.isNot(AsmToken::LParen
)) {
6165 MipsOperand
&Mnemonic
= static_cast<MipsOperand
&>(*Operands
[0]);
6166 if (Mnemonic
.getToken() == "la" || Mnemonic
.getToken() == "dla") {
6168 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6169 Operands
.push_back(MipsOperand::CreateImm(IdVal
, S
, E
, *this));
6170 return MatchOperand_Success
;
6172 if (Tok
.is(AsmToken::EndOfStatement
)) {
6174 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6176 // Zero register assumed, add a memory operand with ZERO as its base.
6177 // "Base" will be managed by k_Memory.
6178 auto Base
= MipsOperand::createGPRReg(
6179 0, "0", getContext().getRegisterInfo(), S
, E
, *this);
6181 MipsOperand::CreateMem(std::move(Base
), IdVal
, S
, E
, *this));
6182 return MatchOperand_Success
;
6184 MCBinaryExpr::Opcode Opcode
;
6185 // GAS and LLVM treat comparison operators different. GAS will generate -1
6186 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6187 // highly unlikely to be found in a memory offset expression, we don't
6189 switch (Tok
.getKind()) {
6190 case AsmToken::Plus
:
6191 Opcode
= MCBinaryExpr::Add
;
6194 case AsmToken::Minus
:
6195 Opcode
= MCBinaryExpr::Sub
;
6198 case AsmToken::Star
:
6199 Opcode
= MCBinaryExpr::Mul
;
6202 case AsmToken::Pipe
:
6203 Opcode
= MCBinaryExpr::Or
;
6207 Opcode
= MCBinaryExpr::And
;
6210 case AsmToken::LessLess
:
6211 Opcode
= MCBinaryExpr::Shl
;
6214 case AsmToken::GreaterGreater
:
6215 Opcode
= MCBinaryExpr::LShr
;
6218 case AsmToken::Caret
:
6219 Opcode
= MCBinaryExpr::Xor
;
6222 case AsmToken::Slash
:
6223 Opcode
= MCBinaryExpr::Div
;
6226 case AsmToken::Percent
:
6227 Opcode
= MCBinaryExpr::Mod
;
6231 Error(Parser
.getTok().getLoc(), "'(' or expression expected");
6232 return MatchOperand_ParseFail
;
6234 const MCExpr
* NextExpr
;
6235 if (getParser().parseExpression(NextExpr
))
6236 return MatchOperand_ParseFail
;
6237 IdVal
= MCBinaryExpr::create(Opcode
, IdVal
, NextExpr
, getContext());
6240 Parser
.Lex(); // Eat the '(' token.
6243 Res
= parseAnyRegister(Operands
);
6244 if (Res
!= MatchOperand_Success
)
6247 if (Parser
.getTok().isNot(AsmToken::RParen
)) {
6248 Error(Parser
.getTok().getLoc(), "')' expected");
6249 return MatchOperand_ParseFail
;
6252 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6254 Parser
.Lex(); // Eat the ')' token.
6257 IdVal
= MCConstantExpr::create(0, getContext());
6259 // Replace the register operand with the memory operand.
6260 std::unique_ptr
<MipsOperand
> op(
6261 static_cast<MipsOperand
*>(Operands
.back().release()));
6262 // Remove the register from the operands.
6263 // "op" will be managed by k_Memory.
6264 Operands
.pop_back();
6265 // Add the memory operand.
6266 if (const MCBinaryExpr
*BE
= dyn_cast
<MCBinaryExpr
>(IdVal
)) {
6268 if (IdVal
->evaluateAsAbsolute(Imm
))
6269 IdVal
= MCConstantExpr::create(Imm
, getContext());
6270 else if (BE
->getLHS()->getKind() != MCExpr::SymbolRef
)
6271 IdVal
= MCBinaryExpr::create(BE
->getOpcode(), BE
->getRHS(), BE
->getLHS(),
6275 Operands
.push_back(MipsOperand::CreateMem(std::move(op
), IdVal
, S
, E
, *this));
6276 return MatchOperand_Success
;
6279 bool MipsAsmParser::searchSymbolAlias(OperandVector
&Operands
) {
6280 MCAsmParser
&Parser
= getParser();
6281 MCSymbol
*Sym
= getContext().lookupSymbol(Parser
.getTok().getIdentifier());
6285 SMLoc S
= Parser
.getTok().getLoc();
6286 if (Sym
->isVariable()) {
6287 const MCExpr
*Expr
= Sym
->getVariableValue();
6288 if (Expr
->getKind() == MCExpr::SymbolRef
) {
6289 const MCSymbolRefExpr
*Ref
= static_cast<const MCSymbolRefExpr
*>(Expr
);
6290 StringRef DefSymbol
= Ref
->getSymbol().getName();
6291 if (DefSymbol
.startswith("$")) {
6292 OperandMatchResultTy ResTy
=
6293 matchAnyRegisterNameWithoutDollar(Operands
, DefSymbol
.substr(1), S
);
6294 if (ResTy
== MatchOperand_Success
) {
6298 if (ResTy
== MatchOperand_ParseFail
)
6299 llvm_unreachable("Should never ParseFail");
6302 } else if (Sym
->isUnset()) {
6303 // If symbol is unset, it might be created in the `parseSetAssignment`
6304 // routine as an alias for a numeric register name.
6305 // Lookup in the aliases list.
6306 auto Entry
= RegisterSets
.find(Sym
->getName());
6307 if (Entry
!= RegisterSets
.end()) {
6308 OperandMatchResultTy ResTy
=
6309 matchAnyRegisterWithoutDollar(Operands
, Entry
->getValue(), S
);
6310 if (ResTy
== MatchOperand_Success
) {
6320 OperandMatchResultTy
6321 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector
&Operands
,
6322 StringRef Identifier
,
6324 int Index
= matchCPURegisterName(Identifier
);
6326 Operands
.push_back(MipsOperand::createGPRReg(
6327 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6328 getLexer().getLoc(), *this));
6329 return MatchOperand_Success
;
6332 Index
= matchHWRegsRegisterName(Identifier
);
6334 Operands
.push_back(MipsOperand::createHWRegsReg(
6335 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6336 getLexer().getLoc(), *this));
6337 return MatchOperand_Success
;
6340 Index
= matchFPURegisterName(Identifier
);
6342 Operands
.push_back(MipsOperand::createFGRReg(
6343 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6344 getLexer().getLoc(), *this));
6345 return MatchOperand_Success
;
6348 Index
= matchFCCRegisterName(Identifier
);
6350 Operands
.push_back(MipsOperand::createFCCReg(
6351 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6352 getLexer().getLoc(), *this));
6353 return MatchOperand_Success
;
6356 Index
= matchACRegisterName(Identifier
);
6358 Operands
.push_back(MipsOperand::createACCReg(
6359 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6360 getLexer().getLoc(), *this));
6361 return MatchOperand_Success
;
6364 Index
= matchMSA128RegisterName(Identifier
);
6366 Operands
.push_back(MipsOperand::createMSA128Reg(
6367 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6368 getLexer().getLoc(), *this));
6369 return MatchOperand_Success
;
6372 Index
= matchMSA128CtrlRegisterName(Identifier
);
6374 Operands
.push_back(MipsOperand::createMSACtrlReg(
6375 Index
, Identifier
, getContext().getRegisterInfo(), S
,
6376 getLexer().getLoc(), *this));
6377 return MatchOperand_Success
;
6380 return MatchOperand_NoMatch
;
6383 OperandMatchResultTy
6384 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector
&Operands
,
6385 const AsmToken
&Token
, SMLoc S
) {
6386 if (Token
.is(AsmToken::Identifier
)) {
6387 LLVM_DEBUG(dbgs() << ".. identifier\n");
6388 StringRef Identifier
= Token
.getIdentifier();
6389 OperandMatchResultTy ResTy
=
6390 matchAnyRegisterNameWithoutDollar(Operands
, Identifier
, S
);
6392 } else if (Token
.is(AsmToken::Integer
)) {
6393 LLVM_DEBUG(dbgs() << ".. integer\n");
6394 int64_t RegNum
= Token
.getIntVal();
6395 if (RegNum
< 0 || RegNum
> 31) {
6396 // Show the error, but treat invalid register
6397 // number as a normal one to continue parsing
6398 // and catch other possible errors.
6399 Error(getLexer().getLoc(), "invalid register number");
6401 Operands
.push_back(MipsOperand::createNumericReg(
6402 RegNum
, Token
.getString(), getContext().getRegisterInfo(), S
,
6403 Token
.getLoc(), *this));
6404 return MatchOperand_Success
;
6407 LLVM_DEBUG(dbgs() << Token
.getKind() << "\n");
6409 return MatchOperand_NoMatch
;
6412 OperandMatchResultTy
6413 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector
&Operands
, SMLoc S
) {
6414 auto Token
= getLexer().peekTok(false);
6415 return matchAnyRegisterWithoutDollar(Operands
, Token
, S
);
6418 OperandMatchResultTy
6419 MipsAsmParser::parseAnyRegister(OperandVector
&Operands
) {
6420 MCAsmParser
&Parser
= getParser();
6421 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6423 auto Token
= Parser
.getTok();
6425 SMLoc S
= Token
.getLoc();
6427 if (Token
.isNot(AsmToken::Dollar
)) {
6428 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6429 if (Token
.is(AsmToken::Identifier
)) {
6430 if (searchSymbolAlias(Operands
))
6431 return MatchOperand_Success
;
6433 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6434 return MatchOperand_NoMatch
;
6436 LLVM_DEBUG(dbgs() << ".. $\n");
6438 OperandMatchResultTy ResTy
= matchAnyRegisterWithoutDollar(Operands
, S
);
6439 if (ResTy
== MatchOperand_Success
) {
6441 Parser
.Lex(); // identifier
6446 OperandMatchResultTy
6447 MipsAsmParser::parseJumpTarget(OperandVector
&Operands
) {
6448 MCAsmParser
&Parser
= getParser();
6449 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6451 SMLoc S
= getLexer().getLoc();
6453 // Registers are a valid target and have priority over symbols.
6454 OperandMatchResultTy ResTy
= parseAnyRegister(Operands
);
6455 if (ResTy
!= MatchOperand_NoMatch
)
6458 // Integers and expressions are acceptable
6459 const MCExpr
*Expr
= nullptr;
6460 if (Parser
.parseExpression(Expr
)) {
6461 // We have no way of knowing if a symbol was consumed so we must ParseFail
6462 return MatchOperand_ParseFail
;
6465 MipsOperand::CreateImm(Expr
, S
, getLexer().getLoc(), *this));
6466 return MatchOperand_Success
;
6469 OperandMatchResultTy
6470 MipsAsmParser::parseInvNum(OperandVector
&Operands
) {
6471 MCAsmParser
&Parser
= getParser();
6472 const MCExpr
*IdVal
;
6473 // If the first token is '$' we may have register operand. We have to reject
6474 // cases where it is not a register. Complicating the matter is that
6475 // register names are not reserved across all ABIs.
6476 // Peek past the dollar to see if it's a register name for this ABI.
6477 SMLoc S
= Parser
.getTok().getLoc();
6478 if (Parser
.getTok().is(AsmToken::Dollar
)) {
6479 return matchCPURegisterName(Parser
.getLexer().peekTok().getString()) == -1
6480 ? MatchOperand_ParseFail
6481 : MatchOperand_NoMatch
;
6483 if (getParser().parseExpression(IdVal
))
6484 return MatchOperand_ParseFail
;
6485 const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(IdVal
);
6487 return MatchOperand_NoMatch
;
6488 int64_t Val
= MCE
->getValue();
6489 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
6490 Operands
.push_back(MipsOperand::CreateImm(
6491 MCConstantExpr::create(0 - Val
, getContext()), S
, E
, *this));
6492 return MatchOperand_Success
;
6495 OperandMatchResultTy
6496 MipsAsmParser::parseRegisterList(OperandVector
&Operands
) {
6497 MCAsmParser
&Parser
= getParser();
6498 SmallVector
<unsigned, 10> Regs
;
6500 unsigned PrevReg
= Mips::NoRegister
;
6501 bool RegRange
= false;
6502 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 8> TmpOperands
;
6504 if (Parser
.getTok().isNot(AsmToken::Dollar
))
6505 return MatchOperand_ParseFail
;
6507 SMLoc S
= Parser
.getTok().getLoc();
6508 while (parseAnyRegister(TmpOperands
) == MatchOperand_Success
) {
6509 SMLoc E
= getLexer().getLoc();
6510 MipsOperand
&Reg
= static_cast<MipsOperand
&>(*TmpOperands
.back());
6511 RegNo
= isGP64bit() ? Reg
.getGPR64Reg() : Reg
.getGPR32Reg();
6513 // Remove last register operand because registers from register range
6514 // should be inserted first.
6515 if ((isGP64bit() && RegNo
== Mips::RA_64
) ||
6516 (!isGP64bit() && RegNo
== Mips::RA
)) {
6517 Regs
.push_back(RegNo
);
6519 unsigned TmpReg
= PrevReg
+ 1;
6520 while (TmpReg
<= RegNo
) {
6521 if ((((TmpReg
< Mips::S0
) || (TmpReg
> Mips::S7
)) && !isGP64bit()) ||
6522 (((TmpReg
< Mips::S0_64
) || (TmpReg
> Mips::S7_64
)) &&
6524 Error(E
, "invalid register operand");
6525 return MatchOperand_ParseFail
;
6529 Regs
.push_back(TmpReg
++);
6535 if ((PrevReg
== Mips::NoRegister
) &&
6536 ((isGP64bit() && (RegNo
!= Mips::S0_64
) && (RegNo
!= Mips::RA_64
)) ||
6537 (!isGP64bit() && (RegNo
!= Mips::S0
) && (RegNo
!= Mips::RA
)))) {
6538 Error(E
, "$16 or $31 expected");
6539 return MatchOperand_ParseFail
;
6540 } else if (!(((RegNo
== Mips::FP
|| RegNo
== Mips::RA
||
6541 (RegNo
>= Mips::S0
&& RegNo
<= Mips::S7
)) &&
6543 ((RegNo
== Mips::FP_64
|| RegNo
== Mips::RA_64
||
6544 (RegNo
>= Mips::S0_64
&& RegNo
<= Mips::S7_64
)) &&
6546 Error(E
, "invalid register operand");
6547 return MatchOperand_ParseFail
;
6548 } else if ((PrevReg
!= Mips::NoRegister
) && (RegNo
!= PrevReg
+ 1) &&
6549 ((RegNo
!= Mips::FP
&& RegNo
!= Mips::RA
&& !isGP64bit()) ||
6550 (RegNo
!= Mips::FP_64
&& RegNo
!= Mips::RA_64
&&
6552 Error(E
, "consecutive register numbers expected");
6553 return MatchOperand_ParseFail
;
6556 Regs
.push_back(RegNo
);
6559 if (Parser
.getTok().is(AsmToken::Minus
))
6562 if (!Parser
.getTok().isNot(AsmToken::Minus
) &&
6563 !Parser
.getTok().isNot(AsmToken::Comma
)) {
6564 Error(E
, "',' or '-' expected");
6565 return MatchOperand_ParseFail
;
6568 Lex(); // Consume comma or minus
6569 if (Parser
.getTok().isNot(AsmToken::Dollar
))
6575 SMLoc E
= Parser
.getTok().getLoc();
6576 Operands
.push_back(MipsOperand::CreateRegList(Regs
, S
, E
, *this));
6577 parseMemOperand(Operands
);
6578 return MatchOperand_Success
;
6581 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6583 /// ::= '(', register, ')'
6584 /// handle it before we iterate so we don't get tripped up by the lack of
6586 bool MipsAsmParser::parseParenSuffix(StringRef Name
, OperandVector
&Operands
) {
6587 MCAsmParser
&Parser
= getParser();
6588 if (getLexer().is(AsmToken::LParen
)) {
6590 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6592 if (parseOperand(Operands
, Name
)) {
6593 SMLoc Loc
= getLexer().getLoc();
6594 return Error(Loc
, "unexpected token in argument list");
6596 if (Parser
.getTok().isNot(AsmToken::RParen
)) {
6597 SMLoc Loc
= getLexer().getLoc();
6598 return Error(Loc
, "unexpected token, expected ')'");
6601 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6607 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6608 /// either one of these.
6609 /// ::= '[', register, ']'
6610 /// ::= '[', integer, ']'
6611 /// handle it before we iterate so we don't get tripped up by the lack of
6613 bool MipsAsmParser::parseBracketSuffix(StringRef Name
,
6614 OperandVector
&Operands
) {
6615 MCAsmParser
&Parser
= getParser();
6616 if (getLexer().is(AsmToken::LBrac
)) {
6618 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6620 if (parseOperand(Operands
, Name
)) {
6621 SMLoc Loc
= getLexer().getLoc();
6622 return Error(Loc
, "unexpected token in argument list");
6624 if (Parser
.getTok().isNot(AsmToken::RBrac
)) {
6625 SMLoc Loc
= getLexer().getLoc();
6626 return Error(Loc
, "unexpected token, expected ']'");
6629 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6635 static std::string
MipsMnemonicSpellCheck(StringRef S
, const FeatureBitset
&FBS
,
6636 unsigned VariantID
= 0);
6638 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
6639 SMLoc NameLoc
, OperandVector
&Operands
) {
6640 MCAsmParser
&Parser
= getParser();
6641 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6643 // We have reached first instruction, module directive are now forbidden.
6644 getTargetStreamer().forbidModuleDirective();
6646 // Check if we have valid mnemonic
6647 if (!mnemonicIsValid(Name
, 0)) {
6648 FeatureBitset FBS
= ComputeAvailableFeatures(getSTI().getFeatureBits());
6649 std::string Suggestion
= MipsMnemonicSpellCheck(Name
, FBS
);
6650 return Error(NameLoc
, "unknown instruction" + Suggestion
);
6652 // First operand in MCInst is instruction mnemonic.
6653 Operands
.push_back(MipsOperand::CreateToken(Name
, NameLoc
, *this));
6655 // Read the remaining operands.
6656 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6657 // Read the first operand.
6658 if (parseOperand(Operands
, Name
)) {
6659 SMLoc Loc
= getLexer().getLoc();
6660 return Error(Loc
, "unexpected token in argument list");
6662 if (getLexer().is(AsmToken::LBrac
) && parseBracketSuffix(Name
, Operands
))
6664 // AFAIK, parenthesis suffixes are never on the first operand
6666 while (getLexer().is(AsmToken::Comma
)) {
6667 Parser
.Lex(); // Eat the comma.
6668 // Parse and remember the operand.
6669 if (parseOperand(Operands
, Name
)) {
6670 SMLoc Loc
= getLexer().getLoc();
6671 return Error(Loc
, "unexpected token in argument list");
6673 // Parse bracket and parenthesis suffixes before we iterate
6674 if (getLexer().is(AsmToken::LBrac
)) {
6675 if (parseBracketSuffix(Name
, Operands
))
6677 } else if (getLexer().is(AsmToken::LParen
) &&
6678 parseParenSuffix(Name
, Operands
))
6682 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6683 SMLoc Loc
= getLexer().getLoc();
6684 return Error(Loc
, "unexpected token in argument list");
6686 Parser
.Lex(); // Consume the EndOfStatement.
6690 // FIXME: Given that these have the same name, these should both be
6691 // consistent on affecting the Parser.
6692 bool MipsAsmParser::reportParseError(Twine ErrorMsg
) {
6693 SMLoc Loc
= getLexer().getLoc();
6694 return Error(Loc
, ErrorMsg
);
6697 bool MipsAsmParser::reportParseError(SMLoc Loc
, Twine ErrorMsg
) {
6698 return Error(Loc
, ErrorMsg
);
6701 bool MipsAsmParser::parseSetNoAtDirective() {
6702 MCAsmParser
&Parser
= getParser();
6703 // Line should look like: ".set noat".
6705 // Set the $at register to $0.
6706 AssemblerOptions
.back()->setATRegIndex(0);
6708 Parser
.Lex(); // Eat "noat".
6710 // If this is not the end of the statement, report an error.
6711 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6712 reportParseError("unexpected token, expected end of statement");
6716 getTargetStreamer().emitDirectiveSetNoAt();
6717 Parser
.Lex(); // Consume the EndOfStatement.
6721 bool MipsAsmParser::parseSetAtDirective() {
6722 // Line can be: ".set at", which sets $at to $1
6723 // or ".set at=$reg", which sets $at to $reg.
6724 MCAsmParser
&Parser
= getParser();
6725 Parser
.Lex(); // Eat "at".
6727 if (getLexer().is(AsmToken::EndOfStatement
)) {
6728 // No register was specified, so we set $at to $1.
6729 AssemblerOptions
.back()->setATRegIndex(1);
6731 getTargetStreamer().emitDirectiveSetAt();
6732 Parser
.Lex(); // Consume the EndOfStatement.
6736 if (getLexer().isNot(AsmToken::Equal
)) {
6737 reportParseError("unexpected token, expected equals sign");
6740 Parser
.Lex(); // Eat "=".
6742 if (getLexer().isNot(AsmToken::Dollar
)) {
6743 if (getLexer().is(AsmToken::EndOfStatement
)) {
6744 reportParseError("no register specified");
6747 reportParseError("unexpected token, expected dollar sign '$'");
6751 Parser
.Lex(); // Eat "$".
6753 // Find out what "reg" is.
6755 const AsmToken
&Reg
= Parser
.getTok();
6756 if (Reg
.is(AsmToken::Identifier
)) {
6757 AtRegNo
= matchCPURegisterName(Reg
.getIdentifier());
6758 } else if (Reg
.is(AsmToken::Integer
)) {
6759 AtRegNo
= Reg
.getIntVal();
6761 reportParseError("unexpected token, expected identifier or integer");
6765 // Check if $reg is a valid register. If it is, set $at to $reg.
6766 if (!AssemblerOptions
.back()->setATRegIndex(AtRegNo
)) {
6767 reportParseError("invalid register");
6770 Parser
.Lex(); // Eat "reg".
6772 // If this is not the end of the statement, report an error.
6773 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6774 reportParseError("unexpected token, expected end of statement");
6778 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo
);
6780 Parser
.Lex(); // Consume the EndOfStatement.
6784 bool MipsAsmParser::parseSetReorderDirective() {
6785 MCAsmParser
&Parser
= getParser();
6787 // If this is not the end of the statement, report an error.
6788 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6789 reportParseError("unexpected token, expected end of statement");
6792 AssemblerOptions
.back()->setReorder();
6793 getTargetStreamer().emitDirectiveSetReorder();
6794 Parser
.Lex(); // Consume the EndOfStatement.
6798 bool MipsAsmParser::parseSetNoReorderDirective() {
6799 MCAsmParser
&Parser
= getParser();
6801 // If this is not the end of the statement, report an error.
6802 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6803 reportParseError("unexpected token, expected end of statement");
6806 AssemblerOptions
.back()->setNoReorder();
6807 getTargetStreamer().emitDirectiveSetNoReorder();
6808 Parser
.Lex(); // Consume the EndOfStatement.
6812 bool MipsAsmParser::parseSetMacroDirective() {
6813 MCAsmParser
&Parser
= getParser();
6815 // If this is not the end of the statement, report an error.
6816 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6817 reportParseError("unexpected token, expected end of statement");
6820 AssemblerOptions
.back()->setMacro();
6821 getTargetStreamer().emitDirectiveSetMacro();
6822 Parser
.Lex(); // Consume the EndOfStatement.
6826 bool MipsAsmParser::parseSetNoMacroDirective() {
6827 MCAsmParser
&Parser
= getParser();
6829 // If this is not the end of the statement, report an error.
6830 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6831 reportParseError("unexpected token, expected end of statement");
6834 if (AssemblerOptions
.back()->isReorder()) {
6835 reportParseError("`noreorder' must be set before `nomacro'");
6838 AssemblerOptions
.back()->setNoMacro();
6839 getTargetStreamer().emitDirectiveSetNoMacro();
6840 Parser
.Lex(); // Consume the EndOfStatement.
6844 bool MipsAsmParser::parseSetMsaDirective() {
6845 MCAsmParser
&Parser
= getParser();
6848 // If this is not the end of the statement, report an error.
6849 if (getLexer().isNot(AsmToken::EndOfStatement
))
6850 return reportParseError("unexpected token, expected end of statement");
6852 setFeatureBits(Mips::FeatureMSA
, "msa");
6853 getTargetStreamer().emitDirectiveSetMsa();
6857 bool MipsAsmParser::parseSetNoMsaDirective() {
6858 MCAsmParser
&Parser
= getParser();
6861 // If this is not the end of the statement, report an error.
6862 if (getLexer().isNot(AsmToken::EndOfStatement
))
6863 return reportParseError("unexpected token, expected end of statement");
6865 clearFeatureBits(Mips::FeatureMSA
, "msa");
6866 getTargetStreamer().emitDirectiveSetNoMsa();
6870 bool MipsAsmParser::parseSetNoDspDirective() {
6871 MCAsmParser
&Parser
= getParser();
6872 Parser
.Lex(); // Eat "nodsp".
6874 // If this is not the end of the statement, report an error.
6875 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6876 reportParseError("unexpected token, expected end of statement");
6880 clearFeatureBits(Mips::FeatureDSP
, "dsp");
6881 getTargetStreamer().emitDirectiveSetNoDsp();
6885 bool MipsAsmParser::parseSetMips16Directive() {
6886 MCAsmParser
&Parser
= getParser();
6887 Parser
.Lex(); // Eat "mips16".
6889 // If this is not the end of the statement, report an error.
6890 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6891 reportParseError("unexpected token, expected end of statement");
6895 setFeatureBits(Mips::FeatureMips16
, "mips16");
6896 getTargetStreamer().emitDirectiveSetMips16();
6897 Parser
.Lex(); // Consume the EndOfStatement.
6901 bool MipsAsmParser::parseSetNoMips16Directive() {
6902 MCAsmParser
&Parser
= getParser();
6903 Parser
.Lex(); // Eat "nomips16".
6905 // If this is not the end of the statement, report an error.
6906 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6907 reportParseError("unexpected token, expected end of statement");
6911 clearFeatureBits(Mips::FeatureMips16
, "mips16");
6912 getTargetStreamer().emitDirectiveSetNoMips16();
6913 Parser
.Lex(); // Consume the EndOfStatement.
6917 bool MipsAsmParser::parseSetFpDirective() {
6918 MCAsmParser
&Parser
= getParser();
6919 MipsABIFlagsSection::FpABIKind FpAbiVal
;
6920 // Line can be: .set fp=32
6923 Parser
.Lex(); // Eat fp token
6924 AsmToken Tok
= Parser
.getTok();
6925 if (Tok
.isNot(AsmToken::Equal
)) {
6926 reportParseError("unexpected token, expected equals sign '='");
6929 Parser
.Lex(); // Eat '=' token.
6930 Tok
= Parser
.getTok();
6932 if (!parseFpABIValue(FpAbiVal
, ".set"))
6935 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6936 reportParseError("unexpected token, expected end of statement");
6939 getTargetStreamer().emitDirectiveSetFp(FpAbiVal
);
6940 Parser
.Lex(); // Consume the EndOfStatement.
6944 bool MipsAsmParser::parseSetOddSPRegDirective() {
6945 MCAsmParser
&Parser
= getParser();
6947 Parser
.Lex(); // Eat "oddspreg".
6948 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6949 reportParseError("unexpected token, expected end of statement");
6953 clearFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
6954 getTargetStreamer().emitDirectiveSetOddSPReg();
6958 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6959 MCAsmParser
&Parser
= getParser();
6961 Parser
.Lex(); // Eat "nooddspreg".
6962 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6963 reportParseError("unexpected token, expected end of statement");
6967 setFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
6968 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6972 bool MipsAsmParser::parseSetMtDirective() {
6973 MCAsmParser
&Parser
= getParser();
6974 Parser
.Lex(); // Eat "mt".
6976 // If this is not the end of the statement, report an error.
6977 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6978 reportParseError("unexpected token, expected end of statement");
6982 setFeatureBits(Mips::FeatureMT
, "mt");
6983 getTargetStreamer().emitDirectiveSetMt();
6984 Parser
.Lex(); // Consume the EndOfStatement.
6988 bool MipsAsmParser::parseSetNoMtDirective() {
6989 MCAsmParser
&Parser
= getParser();
6990 Parser
.Lex(); // Eat "nomt".
6992 // If this is not the end of the statement, report an error.
6993 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
6994 reportParseError("unexpected token, expected end of statement");
6998 clearFeatureBits(Mips::FeatureMT
, "mt");
7000 getTargetStreamer().emitDirectiveSetNoMt();
7001 Parser
.Lex(); // Consume the EndOfStatement.
7005 bool MipsAsmParser::parseSetNoCRCDirective() {
7006 MCAsmParser
&Parser
= getParser();
7007 Parser
.Lex(); // Eat "nocrc".
7009 // If this is not the end of the statement, report an error.
7010 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7011 reportParseError("unexpected token, expected end of statement");
7015 clearFeatureBits(Mips::FeatureCRC
, "crc");
7017 getTargetStreamer().emitDirectiveSetNoCRC();
7018 Parser
.Lex(); // Consume the EndOfStatement.
7022 bool MipsAsmParser::parseSetNoVirtDirective() {
7023 MCAsmParser
&Parser
= getParser();
7024 Parser
.Lex(); // Eat "novirt".
7026 // If this is not the end of the statement, report an error.
7027 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7028 reportParseError("unexpected token, expected end of statement");
7032 clearFeatureBits(Mips::FeatureVirt
, "virt");
7034 getTargetStreamer().emitDirectiveSetNoVirt();
7035 Parser
.Lex(); // Consume the EndOfStatement.
7039 bool MipsAsmParser::parseSetNoGINVDirective() {
7040 MCAsmParser
&Parser
= getParser();
7041 Parser
.Lex(); // Eat "noginv".
7043 // If this is not the end of the statement, report an error.
7044 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7045 reportParseError("unexpected token, expected end of statement");
7049 clearFeatureBits(Mips::FeatureGINV
, "ginv");
7051 getTargetStreamer().emitDirectiveSetNoGINV();
7052 Parser
.Lex(); // Consume the EndOfStatement.
7056 bool MipsAsmParser::parseSetPopDirective() {
7057 MCAsmParser
&Parser
= getParser();
7058 SMLoc Loc
= getLexer().getLoc();
7061 if (getLexer().isNot(AsmToken::EndOfStatement
))
7062 return reportParseError("unexpected token, expected end of statement");
7064 // Always keep an element on the options "stack" to prevent the user
7065 // from changing the initial options. This is how we remember them.
7066 if (AssemblerOptions
.size() == 2)
7067 return reportParseError(Loc
, ".set pop with no .set push");
7069 MCSubtargetInfo
&STI
= copySTI();
7070 AssemblerOptions
.pop_back();
7071 setAvailableFeatures(
7072 ComputeAvailableFeatures(AssemblerOptions
.back()->getFeatures()));
7073 STI
.setFeatureBits(AssemblerOptions
.back()->getFeatures());
7075 getTargetStreamer().emitDirectiveSetPop();
7079 bool MipsAsmParser::parseSetPushDirective() {
7080 MCAsmParser
&Parser
= getParser();
7082 if (getLexer().isNot(AsmToken::EndOfStatement
))
7083 return reportParseError("unexpected token, expected end of statement");
7085 // Create a copy of the current assembler options environment and push it.
7086 AssemblerOptions
.push_back(
7087 std::make_unique
<MipsAssemblerOptions
>(AssemblerOptions
.back().get()));
7089 getTargetStreamer().emitDirectiveSetPush();
7093 bool MipsAsmParser::parseSetSoftFloatDirective() {
7094 MCAsmParser
&Parser
= getParser();
7096 if (getLexer().isNot(AsmToken::EndOfStatement
))
7097 return reportParseError("unexpected token, expected end of statement");
7099 setFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7100 getTargetStreamer().emitDirectiveSetSoftFloat();
7104 bool MipsAsmParser::parseSetHardFloatDirective() {
7105 MCAsmParser
&Parser
= getParser();
7107 if (getLexer().isNot(AsmToken::EndOfStatement
))
7108 return reportParseError("unexpected token, expected end of statement");
7110 clearFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7111 getTargetStreamer().emitDirectiveSetHardFloat();
7115 bool MipsAsmParser::parseSetAssignment() {
7117 MCAsmParser
&Parser
= getParser();
7119 if (Parser
.parseIdentifier(Name
))
7120 return reportParseError("expected identifier after .set");
7122 if (getLexer().isNot(AsmToken::Comma
))
7123 return reportParseError("unexpected token, expected comma");
7126 if (getLexer().is(AsmToken::Dollar
) &&
7127 getLexer().peekTok().is(AsmToken::Integer
)) {
7128 // Parse assignment of a numeric register:
7130 Parser
.Lex(); // Eat $.
7131 RegisterSets
[Name
] = Parser
.getTok();
7132 Parser
.Lex(); // Eat identifier.
7133 getContext().getOrCreateSymbol(Name
);
7138 const MCExpr
*Value
;
7139 if (MCParserUtils::parseAssignmentExpression(Name
, /* allow_redef */ true,
7140 Parser
, Sym
, Value
))
7142 Sym
->setVariableValue(Value
);
7147 bool MipsAsmParser::parseSetMips0Directive() {
7148 MCAsmParser
&Parser
= getParser();
7150 if (getLexer().isNot(AsmToken::EndOfStatement
))
7151 return reportParseError("unexpected token, expected end of statement");
7153 // Reset assembler options to their initial values.
7154 MCSubtargetInfo
&STI
= copySTI();
7155 setAvailableFeatures(
7156 ComputeAvailableFeatures(AssemblerOptions
.front()->getFeatures()));
7157 STI
.setFeatureBits(AssemblerOptions
.front()->getFeatures());
7158 AssemblerOptions
.back()->setFeatures(AssemblerOptions
.front()->getFeatures());
7160 getTargetStreamer().emitDirectiveSetMips0();
7164 bool MipsAsmParser::parseSetArchDirective() {
7165 MCAsmParser
&Parser
= getParser();
7167 if (getLexer().isNot(AsmToken::Equal
))
7168 return reportParseError("unexpected token, expected equals sign");
7172 if (Parser
.parseIdentifier(Arch
))
7173 return reportParseError("expected arch identifier");
7175 StringRef ArchFeatureName
=
7176 StringSwitch
<StringRef
>(Arch
)
7177 .Case("mips1", "mips1")
7178 .Case("mips2", "mips2")
7179 .Case("mips3", "mips3")
7180 .Case("mips4", "mips4")
7181 .Case("mips5", "mips5")
7182 .Case("mips32", "mips32")
7183 .Case("mips32r2", "mips32r2")
7184 .Case("mips32r3", "mips32r3")
7185 .Case("mips32r5", "mips32r5")
7186 .Case("mips32r6", "mips32r6")
7187 .Case("mips64", "mips64")
7188 .Case("mips64r2", "mips64r2")
7189 .Case("mips64r3", "mips64r3")
7190 .Case("mips64r5", "mips64r5")
7191 .Case("mips64r6", "mips64r6")
7192 .Case("octeon", "cnmips")
7193 .Case("r4000", "mips3") // This is an implementation of Mips3.
7196 if (ArchFeatureName
.empty())
7197 return reportParseError("unsupported architecture");
7199 if (ArchFeatureName
== "mips64r6" && inMicroMipsMode())
7200 return reportParseError("mips64r6 does not support microMIPS");
7202 selectArch(ArchFeatureName
);
7203 getTargetStreamer().emitDirectiveSetArch(Arch
);
7207 bool MipsAsmParser::parseSetFeature(uint64_t Feature
) {
7208 MCAsmParser
&Parser
= getParser();
7210 if (getLexer().isNot(AsmToken::EndOfStatement
))
7211 return reportParseError("unexpected token, expected end of statement");
7215 llvm_unreachable("Unimplemented feature");
7216 case Mips::FeatureDSP
:
7217 setFeatureBits(Mips::FeatureDSP
, "dsp");
7218 getTargetStreamer().emitDirectiveSetDsp();
7220 case Mips::FeatureDSPR2
:
7221 setFeatureBits(Mips::FeatureDSPR2
, "dspr2");
7222 getTargetStreamer().emitDirectiveSetDspr2();
7224 case Mips::FeatureMicroMips
:
7225 setFeatureBits(Mips::FeatureMicroMips
, "micromips");
7226 getTargetStreamer().emitDirectiveSetMicroMips();
7228 case Mips::FeatureMips1
:
7229 selectArch("mips1");
7230 getTargetStreamer().emitDirectiveSetMips1();
7232 case Mips::FeatureMips2
:
7233 selectArch("mips2");
7234 getTargetStreamer().emitDirectiveSetMips2();
7236 case Mips::FeatureMips3
:
7237 selectArch("mips3");
7238 getTargetStreamer().emitDirectiveSetMips3();
7240 case Mips::FeatureMips4
:
7241 selectArch("mips4");
7242 getTargetStreamer().emitDirectiveSetMips4();
7244 case Mips::FeatureMips5
:
7245 selectArch("mips5");
7246 getTargetStreamer().emitDirectiveSetMips5();
7248 case Mips::FeatureMips32
:
7249 selectArch("mips32");
7250 getTargetStreamer().emitDirectiveSetMips32();
7252 case Mips::FeatureMips32r2
:
7253 selectArch("mips32r2");
7254 getTargetStreamer().emitDirectiveSetMips32R2();
7256 case Mips::FeatureMips32r3
:
7257 selectArch("mips32r3");
7258 getTargetStreamer().emitDirectiveSetMips32R3();
7260 case Mips::FeatureMips32r5
:
7261 selectArch("mips32r5");
7262 getTargetStreamer().emitDirectiveSetMips32R5();
7264 case Mips::FeatureMips32r6
:
7265 selectArch("mips32r6");
7266 getTargetStreamer().emitDirectiveSetMips32R6();
7268 case Mips::FeatureMips64
:
7269 selectArch("mips64");
7270 getTargetStreamer().emitDirectiveSetMips64();
7272 case Mips::FeatureMips64r2
:
7273 selectArch("mips64r2");
7274 getTargetStreamer().emitDirectiveSetMips64R2();
7276 case Mips::FeatureMips64r3
:
7277 selectArch("mips64r3");
7278 getTargetStreamer().emitDirectiveSetMips64R3();
7280 case Mips::FeatureMips64r5
:
7281 selectArch("mips64r5");
7282 getTargetStreamer().emitDirectiveSetMips64R5();
7284 case Mips::FeatureMips64r6
:
7285 selectArch("mips64r6");
7286 getTargetStreamer().emitDirectiveSetMips64R6();
7288 case Mips::FeatureCRC
:
7289 setFeatureBits(Mips::FeatureCRC
, "crc");
7290 getTargetStreamer().emitDirectiveSetCRC();
7292 case Mips::FeatureVirt
:
7293 setFeatureBits(Mips::FeatureVirt
, "virt");
7294 getTargetStreamer().emitDirectiveSetVirt();
7296 case Mips::FeatureGINV
:
7297 setFeatureBits(Mips::FeatureGINV
, "ginv");
7298 getTargetStreamer().emitDirectiveSetGINV();
7304 bool MipsAsmParser::eatComma(StringRef ErrorStr
) {
7305 MCAsmParser
&Parser
= getParser();
7306 if (getLexer().isNot(AsmToken::Comma
)) {
7307 SMLoc Loc
= getLexer().getLoc();
7308 return Error(Loc
, ErrorStr
);
7311 Parser
.Lex(); // Eat the comma.
7315 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7316 // In this class, it is only used for .cprestore.
7317 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7318 // MipsTargetELFStreamer and MipsAsmParser.
7319 bool MipsAsmParser::isPicAndNotNxxAbi() {
7320 return inPicMode() && !(isABI_N32() || isABI_N64());
7323 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc
) {
7324 if (AssemblerOptions
.back()->isReorder())
7325 Warning(Loc
, ".cpload should be inside a noreorder section");
7327 if (inMips16Mode()) {
7328 reportParseError(".cpload is not supported in Mips16 mode");
7332 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Reg
;
7333 OperandMatchResultTy ResTy
= parseAnyRegister(Reg
);
7334 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
7335 reportParseError("expected register containing function address");
7339 MipsOperand
&RegOpnd
= static_cast<MipsOperand
&>(*Reg
[0]);
7340 if (!RegOpnd
.isGPRAsmReg()) {
7341 reportParseError(RegOpnd
.getStartLoc(), "invalid register");
7345 // If this is not the end of the statement, report an error.
7346 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7347 reportParseError("unexpected token, expected end of statement");
7351 getTargetStreamer().emitDirectiveCpLoad(RegOpnd
.getGPR32Reg());
7355 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc
) {
7356 if (!isABI_N32() && !isABI_N64()) {
7357 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7361 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> Reg
;
7362 OperandMatchResultTy ResTy
= parseAnyRegister(Reg
);
7363 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
7364 reportParseError("expected register containing global pointer");
7368 MipsOperand
&RegOpnd
= static_cast<MipsOperand
&>(*Reg
[0]);
7369 if (!RegOpnd
.isGPRAsmReg()) {
7370 reportParseError(RegOpnd
.getStartLoc(), "invalid register");
7374 // If this is not the end of the statement, report an error.
7375 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7376 reportParseError("unexpected token, expected end of statement");
7379 getParser().Lex(); // Consume the EndOfStatement.
7381 unsigned NewReg
= RegOpnd
.getGPR32Reg();
7385 getTargetStreamer().emitDirectiveCpLocal(NewReg
);
7389 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc
) {
7390 MCAsmParser
&Parser
= getParser();
7392 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7393 // is used in non-PIC mode.
7395 if (inMips16Mode()) {
7396 reportParseError(".cprestore is not supported in Mips16 mode");
7400 // Get the stack offset value.
7401 const MCExpr
*StackOffset
;
7402 int64_t StackOffsetVal
;
7403 if (Parser
.parseExpression(StackOffset
)) {
7404 reportParseError("expected stack offset value");
7408 if (!StackOffset
->evaluateAsAbsolute(StackOffsetVal
)) {
7409 reportParseError("stack offset is not an absolute expression");
7413 if (StackOffsetVal
< 0) {
7414 Warning(Loc
, ".cprestore with negative stack offset has no effect");
7415 IsCpRestoreSet
= false;
7417 IsCpRestoreSet
= true;
7418 CpRestoreOffset
= StackOffsetVal
;
7421 // If this is not the end of the statement, report an error.
7422 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7423 reportParseError("unexpected token, expected end of statement");
7427 if (!getTargetStreamer().emitDirectiveCpRestore(
7428 CpRestoreOffset
, [&]() { return getATReg(Loc
); }, Loc
, STI
))
7430 Parser
.Lex(); // Consume the EndOfStatement.
7434 bool MipsAsmParser::parseDirectiveCPSetup() {
7435 MCAsmParser
&Parser
= getParser();
7438 bool SaveIsReg
= true;
7440 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> TmpReg
;
7441 OperandMatchResultTy ResTy
= parseAnyRegister(TmpReg
);
7442 if (ResTy
== MatchOperand_NoMatch
) {
7443 reportParseError("expected register containing function address");
7447 MipsOperand
&FuncRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
7448 if (!FuncRegOpnd
.isGPRAsmReg()) {
7449 reportParseError(FuncRegOpnd
.getStartLoc(), "invalid register");
7453 FuncReg
= FuncRegOpnd
.getGPR32Reg();
7456 if (!eatComma("unexpected token, expected comma"))
7459 ResTy
= parseAnyRegister(TmpReg
);
7460 if (ResTy
== MatchOperand_NoMatch
) {
7461 const MCExpr
*OffsetExpr
;
7463 SMLoc ExprLoc
= getLexer().getLoc();
7465 if (Parser
.parseExpression(OffsetExpr
) ||
7466 !OffsetExpr
->evaluateAsAbsolute(OffsetVal
)) {
7467 reportParseError(ExprLoc
, "expected save register or stack offset");
7474 MipsOperand
&SaveOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
7475 if (!SaveOpnd
.isGPRAsmReg()) {
7476 reportParseError(SaveOpnd
.getStartLoc(), "invalid register");
7479 Save
= SaveOpnd
.getGPR32Reg();
7482 if (!eatComma("unexpected token, expected comma"))
7486 if (Parser
.parseExpression(Expr
)) {
7487 reportParseError("expected expression");
7491 if (Expr
->getKind() != MCExpr::SymbolRef
) {
7492 reportParseError("expected symbol");
7495 const MCSymbolRefExpr
*Ref
= static_cast<const MCSymbolRefExpr
*>(Expr
);
7497 CpSaveLocation
= Save
;
7498 CpSaveLocationIsRegister
= SaveIsReg
;
7500 getTargetStreamer().emitDirectiveCpsetup(FuncReg
, Save
, Ref
->getSymbol(),
7505 bool MipsAsmParser::parseDirectiveCPReturn() {
7506 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation
,
7507 CpSaveLocationIsRegister
);
7511 bool MipsAsmParser::parseDirectiveNaN() {
7512 MCAsmParser
&Parser
= getParser();
7513 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7514 const AsmToken
&Tok
= Parser
.getTok();
7516 if (Tok
.getString() == "2008") {
7518 getTargetStreamer().emitDirectiveNaN2008();
7520 } else if (Tok
.getString() == "legacy") {
7522 getTargetStreamer().emitDirectiveNaNLegacy();
7526 // If we don't recognize the option passed to the .nan
7527 // directive (e.g. no option or unknown option), emit an error.
7528 reportParseError("invalid option in .nan directive");
7532 bool MipsAsmParser::parseDirectiveSet() {
7533 const AsmToken
&Tok
= getParser().getTok();
7534 StringRef IdVal
= Tok
.getString();
7535 SMLoc Loc
= Tok
.getLoc();
7537 if (IdVal
== "noat")
7538 return parseSetNoAtDirective();
7540 return parseSetAtDirective();
7541 if (IdVal
== "arch")
7542 return parseSetArchDirective();
7543 if (IdVal
== "bopt") {
7544 Warning(Loc
, "'bopt' feature is unsupported");
7548 if (IdVal
== "nobopt") {
7549 // We're already running in nobopt mode, so nothing to do.
7554 return parseSetFpDirective();
7555 if (IdVal
== "oddspreg")
7556 return parseSetOddSPRegDirective();
7557 if (IdVal
== "nooddspreg")
7558 return parseSetNoOddSPRegDirective();
7560 return parseSetPopDirective();
7561 if (IdVal
== "push")
7562 return parseSetPushDirective();
7563 if (IdVal
== "reorder")
7564 return parseSetReorderDirective();
7565 if (IdVal
== "noreorder")
7566 return parseSetNoReorderDirective();
7567 if (IdVal
== "macro")
7568 return parseSetMacroDirective();
7569 if (IdVal
== "nomacro")
7570 return parseSetNoMacroDirective();
7571 if (IdVal
== "mips16")
7572 return parseSetMips16Directive();
7573 if (IdVal
== "nomips16")
7574 return parseSetNoMips16Directive();
7575 if (IdVal
== "nomicromips") {
7576 clearFeatureBits(Mips::FeatureMicroMips
, "micromips");
7577 getTargetStreamer().emitDirectiveSetNoMicroMips();
7578 getParser().eatToEndOfStatement();
7581 if (IdVal
== "micromips") {
7582 if (hasMips64r6()) {
7583 Error(Loc
, ".set micromips directive is not supported with MIPS64R6");
7586 return parseSetFeature(Mips::FeatureMicroMips
);
7588 if (IdVal
== "mips0")
7589 return parseSetMips0Directive();
7590 if (IdVal
== "mips1")
7591 return parseSetFeature(Mips::FeatureMips1
);
7592 if (IdVal
== "mips2")
7593 return parseSetFeature(Mips::FeatureMips2
);
7594 if (IdVal
== "mips3")
7595 return parseSetFeature(Mips::FeatureMips3
);
7596 if (IdVal
== "mips4")
7597 return parseSetFeature(Mips::FeatureMips4
);
7598 if (IdVal
== "mips5")
7599 return parseSetFeature(Mips::FeatureMips5
);
7600 if (IdVal
== "mips32")
7601 return parseSetFeature(Mips::FeatureMips32
);
7602 if (IdVal
== "mips32r2")
7603 return parseSetFeature(Mips::FeatureMips32r2
);
7604 if (IdVal
== "mips32r3")
7605 return parseSetFeature(Mips::FeatureMips32r3
);
7606 if (IdVal
== "mips32r5")
7607 return parseSetFeature(Mips::FeatureMips32r5
);
7608 if (IdVal
== "mips32r6")
7609 return parseSetFeature(Mips::FeatureMips32r6
);
7610 if (IdVal
== "mips64")
7611 return parseSetFeature(Mips::FeatureMips64
);
7612 if (IdVal
== "mips64r2")
7613 return parseSetFeature(Mips::FeatureMips64r2
);
7614 if (IdVal
== "mips64r3")
7615 return parseSetFeature(Mips::FeatureMips64r3
);
7616 if (IdVal
== "mips64r5")
7617 return parseSetFeature(Mips::FeatureMips64r5
);
7618 if (IdVal
== "mips64r6") {
7619 if (inMicroMipsMode()) {
7620 Error(Loc
, "MIPS64R6 is not supported with microMIPS");
7623 return parseSetFeature(Mips::FeatureMips64r6
);
7626 return parseSetFeature(Mips::FeatureDSP
);
7627 if (IdVal
== "dspr2")
7628 return parseSetFeature(Mips::FeatureDSPR2
);
7629 if (IdVal
== "nodsp")
7630 return parseSetNoDspDirective();
7632 return parseSetMsaDirective();
7633 if (IdVal
== "nomsa")
7634 return parseSetNoMsaDirective();
7636 return parseSetMtDirective();
7637 if (IdVal
== "nomt")
7638 return parseSetNoMtDirective();
7639 if (IdVal
== "softfloat")
7640 return parseSetSoftFloatDirective();
7641 if (IdVal
== "hardfloat")
7642 return parseSetHardFloatDirective();
7644 return parseSetFeature(Mips::FeatureCRC
);
7645 if (IdVal
== "nocrc")
7646 return parseSetNoCRCDirective();
7647 if (IdVal
== "virt")
7648 return parseSetFeature(Mips::FeatureVirt
);
7649 if (IdVal
== "novirt")
7650 return parseSetNoVirtDirective();
7651 if (IdVal
== "ginv")
7652 return parseSetFeature(Mips::FeatureGINV
);
7653 if (IdVal
== "noginv")
7654 return parseSetNoGINVDirective();
7656 // It is just an identifier, look for an assignment.
7657 return parseSetAssignment();
7660 /// parseDirectiveGpWord
7661 /// ::= .gpword local_sym
7662 bool MipsAsmParser::parseDirectiveGpWord() {
7663 MCAsmParser
&Parser
= getParser();
7664 const MCExpr
*Value
;
7665 // EmitGPRel32Value requires an expression, so we are using base class
7666 // method to evaluate the expression.
7667 if (getParser().parseExpression(Value
))
7669 getParser().getStreamer().EmitGPRel32Value(Value
);
7671 if (getLexer().isNot(AsmToken::EndOfStatement
))
7672 return Error(getLexer().getLoc(),
7673 "unexpected token, expected end of statement");
7674 Parser
.Lex(); // Eat EndOfStatement token.
7678 /// parseDirectiveGpDWord
7679 /// ::= .gpdword local_sym
7680 bool MipsAsmParser::parseDirectiveGpDWord() {
7681 MCAsmParser
&Parser
= getParser();
7682 const MCExpr
*Value
;
7683 // EmitGPRel64Value requires an expression, so we are using base class
7684 // method to evaluate the expression.
7685 if (getParser().parseExpression(Value
))
7687 getParser().getStreamer().EmitGPRel64Value(Value
);
7689 if (getLexer().isNot(AsmToken::EndOfStatement
))
7690 return Error(getLexer().getLoc(),
7691 "unexpected token, expected end of statement");
7692 Parser
.Lex(); // Eat EndOfStatement token.
7696 /// parseDirectiveDtpRelWord
7697 /// ::= .dtprelword tls_sym
7698 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7699 MCAsmParser
&Parser
= getParser();
7700 const MCExpr
*Value
;
7701 // EmitDTPRel32Value requires an expression, so we are using base class
7702 // method to evaluate the expression.
7703 if (getParser().parseExpression(Value
))
7705 getParser().getStreamer().EmitDTPRel32Value(Value
);
7707 if (getLexer().isNot(AsmToken::EndOfStatement
))
7708 return Error(getLexer().getLoc(),
7709 "unexpected token, expected end of statement");
7710 Parser
.Lex(); // Eat EndOfStatement token.
7714 /// parseDirectiveDtpRelDWord
7715 /// ::= .dtpreldword tls_sym
7716 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7717 MCAsmParser
&Parser
= getParser();
7718 const MCExpr
*Value
;
7719 // EmitDTPRel64Value requires an expression, so we are using base class
7720 // method to evaluate the expression.
7721 if (getParser().parseExpression(Value
))
7723 getParser().getStreamer().EmitDTPRel64Value(Value
);
7725 if (getLexer().isNot(AsmToken::EndOfStatement
))
7726 return Error(getLexer().getLoc(),
7727 "unexpected token, expected end of statement");
7728 Parser
.Lex(); // Eat EndOfStatement token.
7732 /// parseDirectiveTpRelWord
7733 /// ::= .tprelword tls_sym
7734 bool MipsAsmParser::parseDirectiveTpRelWord() {
7735 MCAsmParser
&Parser
= getParser();
7736 const MCExpr
*Value
;
7737 // EmitTPRel32Value requires an expression, so we are using base class
7738 // method to evaluate the expression.
7739 if (getParser().parseExpression(Value
))
7741 getParser().getStreamer().EmitTPRel32Value(Value
);
7743 if (getLexer().isNot(AsmToken::EndOfStatement
))
7744 return Error(getLexer().getLoc(),
7745 "unexpected token, expected end of statement");
7746 Parser
.Lex(); // Eat EndOfStatement token.
7750 /// parseDirectiveTpRelDWord
7751 /// ::= .tpreldword tls_sym
7752 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7753 MCAsmParser
&Parser
= getParser();
7754 const MCExpr
*Value
;
7755 // EmitTPRel64Value requires an expression, so we are using base class
7756 // method to evaluate the expression.
7757 if (getParser().parseExpression(Value
))
7759 getParser().getStreamer().EmitTPRel64Value(Value
);
7761 if (getLexer().isNot(AsmToken::EndOfStatement
))
7762 return Error(getLexer().getLoc(),
7763 "unexpected token, expected end of statement");
7764 Parser
.Lex(); // Eat EndOfStatement token.
7768 bool MipsAsmParser::parseDirectiveOption() {
7769 MCAsmParser
&Parser
= getParser();
7770 // Get the option token.
7771 AsmToken Tok
= Parser
.getTok();
7772 // At the moment only identifiers are supported.
7773 if (Tok
.isNot(AsmToken::Identifier
)) {
7774 return Error(Parser
.getTok().getLoc(),
7775 "unexpected token, expected identifier");
7778 StringRef Option
= Tok
.getIdentifier();
7780 if (Option
== "pic0") {
7781 // MipsAsmParser needs to know if the current PIC mode changes.
7782 IsPicEnabled
= false;
7784 getTargetStreamer().emitDirectiveOptionPic0();
7786 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
7787 return Error(Parser
.getTok().getLoc(),
7788 "unexpected token, expected end of statement");
7793 if (Option
== "pic2") {
7794 // MipsAsmParser needs to know if the current PIC mode changes.
7795 IsPicEnabled
= true;
7797 getTargetStreamer().emitDirectiveOptionPic2();
7799 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
7800 return Error(Parser
.getTok().getLoc(),
7801 "unexpected token, expected end of statement");
7807 Warning(Parser
.getTok().getLoc(),
7808 "unknown option, expected 'pic0' or 'pic2'");
7809 Parser
.eatToEndOfStatement();
7813 /// parseInsnDirective
7815 bool MipsAsmParser::parseInsnDirective() {
7816 // If this is not the end of the statement, report an error.
7817 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7818 reportParseError("unexpected token, expected end of statement");
7822 // The actual label marking happens in
7823 // MipsELFStreamer::createPendingLabelRelocs().
7824 getTargetStreamer().emitDirectiveInsn();
7826 getParser().Lex(); // Eat EndOfStatement token.
7830 /// parseRSectionDirective
7832 bool MipsAsmParser::parseRSectionDirective(StringRef Section
) {
7833 // If this is not the end of the statement, report an error.
7834 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7835 reportParseError("unexpected token, expected end of statement");
7839 MCSection
*ELFSection
= getContext().getELFSection(
7840 Section
, ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
);
7841 getParser().getStreamer().SwitchSection(ELFSection
);
7843 getParser().Lex(); // Eat EndOfStatement token.
7847 /// parseSSectionDirective
7850 bool MipsAsmParser::parseSSectionDirective(StringRef Section
, unsigned Type
) {
7851 // If this is not the end of the statement, report an error.
7852 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7853 reportParseError("unexpected token, expected end of statement");
7857 MCSection
*ELFSection
= getContext().getELFSection(
7858 Section
, Type
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
| ELF::SHF_MIPS_GPREL
);
7859 getParser().getStreamer().SwitchSection(ELFSection
);
7861 getParser().Lex(); // Eat EndOfStatement token.
7865 /// parseDirectiveModule
7866 /// ::= .module oddspreg
7867 /// ::= .module nooddspreg
7868 /// ::= .module fp=value
7869 /// ::= .module softfloat
7870 /// ::= .module hardfloat
7873 /// ::= .module nocrc
7874 /// ::= .module virt
7875 /// ::= .module novirt
7876 /// ::= .module ginv
7877 /// ::= .module noginv
7878 bool MipsAsmParser::parseDirectiveModule() {
7879 MCAsmParser
&Parser
= getParser();
7880 MCAsmLexer
&Lexer
= getLexer();
7881 SMLoc L
= Lexer
.getLoc();
7883 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7884 // TODO : get a better message.
7885 reportParseError(".module directive must appear before any code");
7890 if (Parser
.parseIdentifier(Option
)) {
7891 reportParseError("expected .module option identifier");
7895 if (Option
== "oddspreg") {
7896 clearModuleFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
7898 // Synchronize the abiflags information with the FeatureBits information we
7900 getTargetStreamer().updateABIInfo(*this);
7902 // If printing assembly, use the recently updated abiflags information.
7903 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7904 // emitted at the end).
7905 getTargetStreamer().emitDirectiveModuleOddSPReg();
7907 // If this is not the end of the statement, report an error.
7908 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7909 reportParseError("unexpected token, expected end of statement");
7913 return false; // parseDirectiveModule has finished successfully.
7914 } else if (Option
== "nooddspreg") {
7916 return Error(L
, "'.module nooddspreg' requires the O32 ABI");
7919 setModuleFeatureBits(Mips::FeatureNoOddSPReg
, "nooddspreg");
7921 // Synchronize the abiflags information with the FeatureBits information we
7923 getTargetStreamer().updateABIInfo(*this);
7925 // If printing assembly, use the recently updated abiflags information.
7926 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7927 // emitted at the end).
7928 getTargetStreamer().emitDirectiveModuleOddSPReg();
7930 // If this is not the end of the statement, report an error.
7931 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7932 reportParseError("unexpected token, expected end of statement");
7936 return false; // parseDirectiveModule has finished successfully.
7937 } else if (Option
== "fp") {
7938 return parseDirectiveModuleFP();
7939 } else if (Option
== "softfloat") {
7940 setModuleFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7942 // Synchronize the ABI Flags information with the FeatureBits information we
7944 getTargetStreamer().updateABIInfo(*this);
7946 // If printing assembly, use the recently updated ABI Flags information.
7947 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7949 getTargetStreamer().emitDirectiveModuleSoftFloat();
7951 // If this is not the end of the statement, report an error.
7952 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7953 reportParseError("unexpected token, expected end of statement");
7957 return false; // parseDirectiveModule has finished successfully.
7958 } else if (Option
== "hardfloat") {
7959 clearModuleFeatureBits(Mips::FeatureSoftFloat
, "soft-float");
7961 // Synchronize the ABI Flags information with the FeatureBits information we
7963 getTargetStreamer().updateABIInfo(*this);
7965 // If printing assembly, use the recently updated ABI Flags information.
7966 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7968 getTargetStreamer().emitDirectiveModuleHardFloat();
7970 // If this is not the end of the statement, report an error.
7971 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7972 reportParseError("unexpected token, expected end of statement");
7976 return false; // parseDirectiveModule has finished successfully.
7977 } else if (Option
== "mt") {
7978 setModuleFeatureBits(Mips::FeatureMT
, "mt");
7980 // Synchronize the ABI Flags information with the FeatureBits information we
7982 getTargetStreamer().updateABIInfo(*this);
7984 // If printing assembly, use the recently updated ABI Flags information.
7985 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7987 getTargetStreamer().emitDirectiveModuleMT();
7989 // If this is not the end of the statement, report an error.
7990 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
7991 reportParseError("unexpected token, expected end of statement");
7995 return false; // parseDirectiveModule has finished successfully.
7996 } else if (Option
== "crc") {
7997 setModuleFeatureBits(Mips::FeatureCRC
, "crc");
7999 // Synchronize the ABI Flags information with the FeatureBits information we
8001 getTargetStreamer().updateABIInfo(*this);
8003 // If printing assembly, use the recently updated ABI Flags information.
8004 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8006 getTargetStreamer().emitDirectiveModuleCRC();
8008 // If this is not the end of the statement, report an error.
8009 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8010 reportParseError("unexpected token, expected end of statement");
8014 return false; // parseDirectiveModule has finished successfully.
8015 } else if (Option
== "nocrc") {
8016 clearModuleFeatureBits(Mips::FeatureCRC
, "crc");
8018 // Synchronize the ABI Flags information with the FeatureBits information we
8020 getTargetStreamer().updateABIInfo(*this);
8022 // If printing assembly, use the recently updated ABI Flags information.
8023 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8025 getTargetStreamer().emitDirectiveModuleNoCRC();
8027 // If this is not the end of the statement, report an error.
8028 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8029 reportParseError("unexpected token, expected end of statement");
8033 return false; // parseDirectiveModule has finished successfully.
8034 } else if (Option
== "virt") {
8035 setModuleFeatureBits(Mips::FeatureVirt
, "virt");
8037 // Synchronize the ABI Flags information with the FeatureBits information we
8039 getTargetStreamer().updateABIInfo(*this);
8041 // If printing assembly, use the recently updated ABI Flags information.
8042 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8044 getTargetStreamer().emitDirectiveModuleVirt();
8046 // If this is not the end of the statement, report an error.
8047 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8048 reportParseError("unexpected token, expected end of statement");
8052 return false; // parseDirectiveModule has finished successfully.
8053 } else if (Option
== "novirt") {
8054 clearModuleFeatureBits(Mips::FeatureVirt
, "virt");
8056 // Synchronize the ABI Flags information with the FeatureBits information we
8058 getTargetStreamer().updateABIInfo(*this);
8060 // If printing assembly, use the recently updated ABI Flags information.
8061 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8063 getTargetStreamer().emitDirectiveModuleNoVirt();
8065 // If this is not the end of the statement, report an error.
8066 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8067 reportParseError("unexpected token, expected end of statement");
8071 return false; // parseDirectiveModule has finished successfully.
8072 } else if (Option
== "ginv") {
8073 setModuleFeatureBits(Mips::FeatureGINV
, "ginv");
8075 // Synchronize the ABI Flags information with the FeatureBits information we
8077 getTargetStreamer().updateABIInfo(*this);
8079 // If printing assembly, use the recently updated ABI Flags information.
8080 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8082 getTargetStreamer().emitDirectiveModuleGINV();
8084 // If this is not the end of the statement, report an error.
8085 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8086 reportParseError("unexpected token, expected end of statement");
8090 return false; // parseDirectiveModule has finished successfully.
8091 } else if (Option
== "noginv") {
8092 clearModuleFeatureBits(Mips::FeatureGINV
, "ginv");
8094 // Synchronize the ABI Flags information with the FeatureBits information we
8096 getTargetStreamer().updateABIInfo(*this);
8098 // If printing assembly, use the recently updated ABI Flags information.
8099 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8101 getTargetStreamer().emitDirectiveModuleNoGINV();
8103 // If this is not the end of the statement, report an error.
8104 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8105 reportParseError("unexpected token, expected end of statement");
8109 return false; // parseDirectiveModule has finished successfully.
8111 return Error(L
, "'" + Twine(Option
) + "' is not a valid .module option.");
8115 /// parseDirectiveModuleFP
8119 bool MipsAsmParser::parseDirectiveModuleFP() {
8120 MCAsmParser
&Parser
= getParser();
8121 MCAsmLexer
&Lexer
= getLexer();
8123 if (Lexer
.isNot(AsmToken::Equal
)) {
8124 reportParseError("unexpected token, expected equals sign '='");
8127 Parser
.Lex(); // Eat '=' token.
8129 MipsABIFlagsSection::FpABIKind FpABI
;
8130 if (!parseFpABIValue(FpABI
, ".module"))
8133 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8134 reportParseError("unexpected token, expected end of statement");
8138 // Synchronize the abiflags information with the FeatureBits information we
8140 getTargetStreamer().updateABIInfo(*this);
8142 // If printing assembly, use the recently updated abiflags information.
8143 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8144 // emitted at the end).
8145 getTargetStreamer().emitDirectiveModuleFP();
8147 Parser
.Lex(); // Consume the EndOfStatement.
8151 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind
&FpABI
,
8152 StringRef Directive
) {
8153 MCAsmParser
&Parser
= getParser();
8154 MCAsmLexer
&Lexer
= getLexer();
8155 bool ModuleLevelOptions
= Directive
== ".module";
8157 if (Lexer
.is(AsmToken::Identifier
)) {
8158 StringRef Value
= Parser
.getTok().getString();
8161 if (Value
!= "xx") {
8162 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8167 reportParseError("'" + Directive
+ " fp=xx' requires the O32 ABI");
8171 FpABI
= MipsABIFlagsSection::FpABIKind::XX
;
8172 if (ModuleLevelOptions
) {
8173 setModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8174 clearModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8176 setFeatureBits(Mips::FeatureFPXX
, "fpxx");
8177 clearFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8182 if (Lexer
.is(AsmToken::Integer
)) {
8183 unsigned Value
= Parser
.getTok().getIntVal();
8186 if (Value
!= 32 && Value
!= 64) {
8187 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8193 reportParseError("'" + Directive
+ " fp=32' requires the O32 ABI");
8197 FpABI
= MipsABIFlagsSection::FpABIKind::S32
;
8198 if (ModuleLevelOptions
) {
8199 clearModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8200 clearModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8202 clearFeatureBits(Mips::FeatureFPXX
, "fpxx");
8203 clearFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8206 FpABI
= MipsABIFlagsSection::FpABIKind::S64
;
8207 if (ModuleLevelOptions
) {
8208 clearModuleFeatureBits(Mips::FeatureFPXX
, "fpxx");
8209 setModuleFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8211 clearFeatureBits(Mips::FeatureFPXX
, "fpxx");
8212 setFeatureBits(Mips::FeatureFP64Bit
, "fp64");
8222 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID
) {
8223 // This returns false if this function recognizes the directive
8224 // regardless of whether it is successfully handles or reports an
8225 // error. Otherwise it returns true to give the generic parser a
8226 // chance at recognizing it.
8228 MCAsmParser
&Parser
= getParser();
8229 StringRef IDVal
= DirectiveID
.getString();
8231 if (IDVal
== ".cpload") {
8232 parseDirectiveCpLoad(DirectiveID
.getLoc());
8235 if (IDVal
== ".cprestore") {
8236 parseDirectiveCpRestore(DirectiveID
.getLoc());
8239 if (IDVal
== ".cplocal") {
8240 parseDirectiveCpLocal(DirectiveID
.getLoc());
8243 if (IDVal
== ".ent") {
8244 StringRef SymbolName
;
8246 if (Parser
.parseIdentifier(SymbolName
)) {
8247 reportParseError("expected identifier after .ent");
8251 // There's an undocumented extension that allows an integer to
8252 // follow the name of the procedure which AFAICS is ignored by GAS.
8253 // Example: .ent foo,2
8254 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8255 if (getLexer().isNot(AsmToken::Comma
)) {
8256 // Even though we accept this undocumented extension for compatibility
8257 // reasons, the additional integer argument does not actually change
8258 // the behaviour of the '.ent' directive, so we would like to discourage
8259 // its use. We do this by not referring to the extended version in
8260 // error messages which are not directly related to its use.
8261 reportParseError("unexpected token, expected end of statement");
8264 Parser
.Lex(); // Eat the comma.
8265 const MCExpr
*DummyNumber
;
8266 int64_t DummyNumberVal
;
8267 // If the user was explicitly trying to use the extended version,
8268 // we still give helpful extension-related error messages.
8269 if (Parser
.parseExpression(DummyNumber
)) {
8270 reportParseError("expected number after comma");
8273 if (!DummyNumber
->evaluateAsAbsolute(DummyNumberVal
)) {
8274 reportParseError("expected an absolute expression after comma");
8279 // If this is not the end of the statement, report an error.
8280 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8281 reportParseError("unexpected token, expected end of statement");
8285 MCSymbol
*Sym
= getContext().getOrCreateSymbol(SymbolName
);
8287 getTargetStreamer().emitDirectiveEnt(*Sym
);
8289 IsCpRestoreSet
= false;
8293 if (IDVal
== ".end") {
8294 StringRef SymbolName
;
8296 if (Parser
.parseIdentifier(SymbolName
)) {
8297 reportParseError("expected identifier after .end");
8301 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8302 reportParseError("unexpected token, expected end of statement");
8306 if (CurrentFn
== nullptr) {
8307 reportParseError(".end used without .ent");
8311 if ((SymbolName
!= CurrentFn
->getName())) {
8312 reportParseError(".end symbol does not match .ent symbol");
8316 getTargetStreamer().emitDirectiveEnd(SymbolName
);
8317 CurrentFn
= nullptr;
8318 IsCpRestoreSet
= false;
8322 if (IDVal
== ".frame") {
8323 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8324 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 1> TmpReg
;
8325 OperandMatchResultTy ResTy
= parseAnyRegister(TmpReg
);
8326 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
8327 reportParseError("expected stack register");
8331 MipsOperand
&StackRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
8332 if (!StackRegOpnd
.isGPRAsmReg()) {
8333 reportParseError(StackRegOpnd
.getStartLoc(),
8334 "expected general purpose register");
8337 unsigned StackReg
= StackRegOpnd
.getGPR32Reg();
8339 if (Parser
.getTok().is(AsmToken::Comma
))
8342 reportParseError("unexpected token, expected comma");
8346 // Parse the frame size.
8347 const MCExpr
*FrameSize
;
8348 int64_t FrameSizeVal
;
8350 if (Parser
.parseExpression(FrameSize
)) {
8351 reportParseError("expected frame size value");
8355 if (!FrameSize
->evaluateAsAbsolute(FrameSizeVal
)) {
8356 reportParseError("frame size not an absolute expression");
8360 if (Parser
.getTok().is(AsmToken::Comma
))
8363 reportParseError("unexpected token, expected comma");
8367 // Parse the return register.
8369 ResTy
= parseAnyRegister(TmpReg
);
8370 if (ResTy
== MatchOperand_NoMatch
|| ResTy
== MatchOperand_ParseFail
) {
8371 reportParseError("expected return register");
8375 MipsOperand
&ReturnRegOpnd
= static_cast<MipsOperand
&>(*TmpReg
[0]);
8376 if (!ReturnRegOpnd
.isGPRAsmReg()) {
8377 reportParseError(ReturnRegOpnd
.getStartLoc(),
8378 "expected general purpose register");
8382 // If this is not the end of the statement, report an error.
8383 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8384 reportParseError("unexpected token, expected end of statement");
8388 getTargetStreamer().emitFrame(StackReg
, FrameSizeVal
,
8389 ReturnRegOpnd
.getGPR32Reg());
8390 IsCpRestoreSet
= false;
8394 if (IDVal
== ".set") {
8395 parseDirectiveSet();
8399 if (IDVal
== ".mask" || IDVal
== ".fmask") {
8400 // .mask bitmask, frame_offset
8401 // bitmask: One bit for each register used.
8402 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8403 // first register is expected to be saved.
8405 // .mask 0x80000000, -4
8406 // .fmask 0x80000000, -4
8409 // Parse the bitmask
8410 const MCExpr
*BitMask
;
8413 if (Parser
.parseExpression(BitMask
)) {
8414 reportParseError("expected bitmask value");
8418 if (!BitMask
->evaluateAsAbsolute(BitMaskVal
)) {
8419 reportParseError("bitmask not an absolute expression");
8423 if (Parser
.getTok().is(AsmToken::Comma
))
8426 reportParseError("unexpected token, expected comma");
8430 // Parse the frame_offset
8431 const MCExpr
*FrameOffset
;
8432 int64_t FrameOffsetVal
;
8434 if (Parser
.parseExpression(FrameOffset
)) {
8435 reportParseError("expected frame offset value");
8439 if (!FrameOffset
->evaluateAsAbsolute(FrameOffsetVal
)) {
8440 reportParseError("frame offset not an absolute expression");
8444 // If this is not the end of the statement, report an error.
8445 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8446 reportParseError("unexpected token, expected end of statement");
8450 if (IDVal
== ".mask")
8451 getTargetStreamer().emitMask(BitMaskVal
, FrameOffsetVal
);
8453 getTargetStreamer().emitFMask(BitMaskVal
, FrameOffsetVal
);
8457 if (IDVal
== ".nan")
8458 return parseDirectiveNaN();
8460 if (IDVal
== ".gpword") {
8461 parseDirectiveGpWord();
8465 if (IDVal
== ".gpdword") {
8466 parseDirectiveGpDWord();
8470 if (IDVal
== ".dtprelword") {
8471 parseDirectiveDtpRelWord();
8475 if (IDVal
== ".dtpreldword") {
8476 parseDirectiveDtpRelDWord();
8480 if (IDVal
== ".tprelword") {
8481 parseDirectiveTpRelWord();
8485 if (IDVal
== ".tpreldword") {
8486 parseDirectiveTpRelDWord();
8490 if (IDVal
== ".option") {
8491 parseDirectiveOption();
8495 if (IDVal
== ".abicalls") {
8496 getTargetStreamer().emitDirectiveAbiCalls();
8497 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
)) {
8498 Error(Parser
.getTok().getLoc(),
8499 "unexpected token, expected end of statement");
8504 if (IDVal
== ".cpsetup") {
8505 parseDirectiveCPSetup();
8508 if (IDVal
== ".cpreturn") {
8509 parseDirectiveCPReturn();
8512 if (IDVal
== ".module") {
8513 parseDirectiveModule();
8516 if (IDVal
== ".llvm_internal_mips_reallow_module_directive") {
8517 parseInternalDirectiveReallowModule();
8520 if (IDVal
== ".insn") {
8521 parseInsnDirective();
8524 if (IDVal
== ".rdata") {
8525 parseRSectionDirective(".rodata");
8528 if (IDVal
== ".sbss") {
8529 parseSSectionDirective(IDVal
, ELF::SHT_NOBITS
);
8532 if (IDVal
== ".sdata") {
8533 parseSSectionDirective(IDVal
, ELF::SHT_PROGBITS
);
8540 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8541 // If this is not the end of the statement, report an error.
8542 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
8543 reportParseError("unexpected token, expected end of statement");
8547 getTargetStreamer().reallowModuleDirective();
8549 getParser().Lex(); // Eat EndOfStatement token.
8553 extern "C" void LLVMInitializeMipsAsmParser() {
8554 RegisterMCAsmParser
<MipsAsmParser
> X(getTheMipsTarget());
8555 RegisterMCAsmParser
<MipsAsmParser
> Y(getTheMipselTarget());
8556 RegisterMCAsmParser
<MipsAsmParser
> A(getTheMips64Target());
8557 RegisterMCAsmParser
<MipsAsmParser
> B(getTheMips64elTarget());
8560 #define GET_REGISTER_MATCHER
8561 #define GET_MATCHER_IMPLEMENTATION
8562 #define GET_MNEMONIC_SPELL_CHECKER
8563 #include "MipsGenAsmMatcher.inc"
8565 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic
, unsigned VariantID
) {
8566 // Find the appropriate table for this asm variant.
8567 const MatchEntry
*Start
, *End
;
8568 switch (VariantID
) {
8569 default: llvm_unreachable("invalid variant!");
8570 case 0: Start
= std::begin(MatchTable0
); End
= std::end(MatchTable0
); break;
8572 // Search the table.
8573 auto MnemonicRange
= std::equal_range(Start
, End
, Mnemonic
, LessOpcode());
8574 return MnemonicRange
.first
!= MnemonicRange
.second
;