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/Casting.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Compiler.h"
45 #include "llvm/Support/Debug.h"
46 #include "llvm/Support/ErrorHandling.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/SMLoc.h"
49 #include "llvm/Support/SourceMgr.h"
50 #include "llvm/Support/TargetRegistry.h"
51 #include "llvm/Support/raw_ostream.h"
61 #define DEBUG_TYPE "mips-asm-parser"
67 } // end namespace llvm
69 extern cl::opt<bool> EmitJalrReloc;
73 class MipsAssemblerOptions {
75 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
77 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
78 ATReg = Opts->getATRegIndex();
79 Reorder = Opts->isReorder();
80 Macro = Opts->isMacro();
81 Features = Opts->getFeatures();
84 unsigned getATRegIndex() const { return ATReg; }
85 bool setATRegIndex(unsigned Reg) {
93 bool isReorder() const { return Reorder; }
94 void setReorder() { Reorder = true; }
95 void setNoReorder() { Reorder = false; }
97 bool isMacro() const { return Macro; }
98 void setMacro() { Macro = true; }
99 void setNoMacro() { Macro = false; }
101 const FeatureBitset &getFeatures() const { return Features; }
102 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
104 // Set of features that are either architecture features or referenced
105 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
106 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
107 // The reason we need this mask is explained in the selectArch function.
108 // FIXME: Ideally we would like TableGen to generate this information.
109 static const FeatureBitset AllArchRelatedMask;
115 FeatureBitset Features;
118 } // end anonymous namespace
120 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
121 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
122 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
123 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
124 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
125 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
126 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
127 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
128 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
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 expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
334 const MCSubtargetInfo *STI);
336 bool reportParseError(Twine ErrorMsg);
337 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
339 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
341 bool isEvaluated(const MCExpr *Expr);
342 bool parseSetMips0Directive();
343 bool parseSetArchDirective();
344 bool parseSetFeature(uint64_t Feature);
345 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
346 bool parseDirectiveCpLoad(SMLoc Loc);
347 bool parseDirectiveCpLocal(SMLoc Loc);
348 bool parseDirectiveCpRestore(SMLoc Loc);
349 bool parseDirectiveCPSetup();
350 bool parseDirectiveCPReturn();
351 bool parseDirectiveNaN();
352 bool parseDirectiveSet();
353 bool parseDirectiveOption();
354 bool parseInsnDirective();
355 bool parseRSectionDirective(StringRef Section);
356 bool parseSSectionDirective(StringRef Section, unsigned Type);
358 bool parseSetAtDirective();
359 bool parseSetNoAtDirective();
360 bool parseSetMacroDirective();
361 bool parseSetNoMacroDirective();
362 bool parseSetMsaDirective();
363 bool parseSetNoMsaDirective();
364 bool parseSetNoDspDirective();
365 bool parseSetReorderDirective();
366 bool parseSetNoReorderDirective();
367 bool parseSetMips16Directive();
368 bool parseSetNoMips16Directive();
369 bool parseSetFpDirective();
370 bool parseSetOddSPRegDirective();
371 bool parseSetNoOddSPRegDirective();
372 bool parseSetPopDirective();
373 bool parseSetPushDirective();
374 bool parseSetSoftFloatDirective();
375 bool parseSetHardFloatDirective();
376 bool parseSetMtDirective();
377 bool parseSetNoMtDirective();
378 bool parseSetNoCRCDirective();
379 bool parseSetNoVirtDirective();
380 bool parseSetNoGINVDirective();
382 bool parseSetAssignment();
384 bool parseDirectiveGpWord();
385 bool parseDirectiveGpDWord();
386 bool parseDirectiveDtpRelWord();
387 bool parseDirectiveDtpRelDWord();
388 bool parseDirectiveTpRelWord();
389 bool parseDirectiveTpRelDWord();
390 bool parseDirectiveModule();
391 bool parseDirectiveModuleFP();
392 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
393 StringRef Directive);
395 bool parseInternalDirectiveReallowModule();
397 bool eatComma(StringRef ErrorStr);
399 int matchCPURegisterName(StringRef Symbol);
401 int matchHWRegsRegisterName(StringRef Symbol);
403 int matchFPURegisterName(StringRef Name);
405 int matchFCCRegisterName(StringRef Name);
407 int matchACRegisterName(StringRef Name);
409 int matchMSA128RegisterName(StringRef Name);
411 int matchMSA128CtrlRegisterName(StringRef Name);
413 unsigned getReg(int RC, int RegNo);
415 /// Returns the internal register number for the current AT. Also checks if
416 /// the current AT is unavailable (set to $0) and gives an error if it is.
417 /// This should be used in pseudo-instruction expansions which need AT.
418 unsigned getATReg(SMLoc Loc);
422 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
423 const MCSubtargetInfo *STI);
425 // Helper function that checks if the value of a vector index is within the
426 // boundaries of accepted values for each RegisterKind
427 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
428 bool validateMSAIndex(int Val, int RegKind);
430 // Selects a new architecture by updating the FeatureBits with the necessary
431 // info including implied dependencies.
432 // Internally, it clears all the feature bits related to *any* architecture
433 // and selects the new one using the ToggleFeature functionality of the
434 // MCSubtargetInfo object that handles implied dependencies. The reason we
435 // clear all the arch related bits manually is because ToggleFeature only
436 // clears the features that imply the feature being cleared and not the
437 // features implied by the feature being cleared. This is easier to see
439 // --------------------------------------------------
440 // | Feature | Implies |
441 // | -------------------------------------------------|
442 // | FeatureMips1 | None |
443 // | FeatureMips2 | FeatureMips1 |
444 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
445 // | FeatureMips4 | FeatureMips3 |
447 // --------------------------------------------------
449 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
450 // FeatureMipsGP64 | FeatureMips1)
451 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
452 void selectArch(StringRef ArchFeature) {
453 MCSubtargetInfo &STI = copySTI();
454 FeatureBitset FeatureBits = STI.getFeatureBits();
455 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
456 STI.setFeatureBits(FeatureBits);
457 setAvailableFeatures(
458 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
459 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
462 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
463 if (!(getSTI().getFeatureBits()[Feature])) {
464 MCSubtargetInfo &STI = copySTI();
465 setAvailableFeatures(
466 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
467 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
471 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
472 if (getSTI().getFeatureBits()[Feature]) {
473 MCSubtargetInfo &STI = copySTI();
474 setAvailableFeatures(
475 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
476 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
480 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
481 setFeatureBits(Feature, FeatureString);
482 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
485 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
486 clearFeatureBits(Feature, FeatureString);
487 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
491 enum MipsMatchResultTy {
492 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
493 Match_RequiresDifferentOperands,
494 Match_RequiresNoZeroRegister,
495 Match_RequiresSameSrcAndDst,
496 Match_NoFCCRegisterForCurrentISA,
497 Match_NonZeroOperandForSync,
498 Match_NonZeroOperandForMTCX,
499 Match_RequiresPosSizeRange0_32,
500 Match_RequiresPosSizeRange33_64,
501 Match_RequiresPosSizeUImm6,
502 #define GET_OPERAND_DIAGNOSTIC_TYPES
503 #include "MipsGenAsmMatcher.inc"
504 #undef GET_OPERAND_DIAGNOSTIC_TYPES
507 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
508 const MCInstrInfo &MII, const MCTargetOptions &Options)
509 : MCTargetAsmParser(Options, sti, MII),
510 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
511 sti.getCPU(), Options)) {
512 MCAsmParserExtension::Initialize(parser);
514 parser.addAliasForDirective(".asciiz", ".asciz");
515 parser.addAliasForDirective(".hword", ".2byte");
516 parser.addAliasForDirective(".word", ".4byte");
517 parser.addAliasForDirective(".dword", ".8byte");
519 // Initialize the set of available features.
520 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
522 // Remember the initial assembler options. The user can not modify these.
523 AssemblerOptions.push_back(
524 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
526 // Create an assembler options environment for the user to modify.
527 AssemblerOptions.push_back(
528 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
530 getTargetStreamer().updateABIInfo(*this);
532 if (!isABI_O32() && !useOddSPReg() != 0)
533 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
537 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
539 IsCpRestoreSet = false;
540 CpRestoreOffset = -1;
541 GPReg = ABI.GetGlobalPtr();
543 const Triple &TheTriple = sti.getTargetTriple();
544 IsLittleEndian = TheTriple.isLittleEndian();
546 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
547 report_fatal_error("microMIPS64R6 is not supported", false);
549 if (!isABI_O32() && inMicroMipsMode())
550 report_fatal_error("microMIPS64 is not supported", false);
553 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
554 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
556 bool isGP64bit() const {
557 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
560 bool isFP64bit() const {
561 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
564 const MipsABIInfo &getABI() const { return ABI; }
565 bool isABI_N32() const { return ABI.IsN32(); }
566 bool isABI_N64() const { return ABI.IsN64(); }
567 bool isABI_O32() const { return ABI.IsO32(); }
568 bool isABI_FPXX() const {
569 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
572 bool useOddSPReg() const {
573 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
576 bool inMicroMipsMode() const {
577 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
580 bool hasMips1() const {
581 return getSTI().getFeatureBits()[Mips::FeatureMips1];
584 bool hasMips2() const {
585 return getSTI().getFeatureBits()[Mips::FeatureMips2];
588 bool hasMips3() const {
589 return getSTI().getFeatureBits()[Mips::FeatureMips3];
592 bool hasMips4() const {
593 return getSTI().getFeatureBits()[Mips::FeatureMips4];
596 bool hasMips5() const {
597 return getSTI().getFeatureBits()[Mips::FeatureMips5];
600 bool hasMips32() const {
601 return getSTI().getFeatureBits()[Mips::FeatureMips32];
604 bool hasMips64() const {
605 return getSTI().getFeatureBits()[Mips::FeatureMips64];
608 bool hasMips32r2() const {
609 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
612 bool hasMips64r2() const {
613 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
616 bool hasMips32r3() const {
617 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
620 bool hasMips64r3() const {
621 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
624 bool hasMips32r5() const {
625 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
628 bool hasMips64r5() const {
629 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
632 bool hasMips32r6() const {
633 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
636 bool hasMips64r6() const {
637 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
640 bool hasDSP() const {
641 return getSTI().getFeatureBits()[Mips::FeatureDSP];
644 bool hasDSPR2() const {
645 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
648 bool hasDSPR3() const {
649 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
652 bool hasMSA() const {
653 return getSTI().getFeatureBits()[Mips::FeatureMSA];
656 bool hasCnMips() const {
657 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
660 bool hasCnMipsP() const {
661 return (getSTI().getFeatureBits()[Mips::FeatureCnMipsP]);
668 bool inMips16Mode() const {
669 return getSTI().getFeatureBits()[Mips::FeatureMips16];
672 bool useTraps() const {
673 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
676 bool useSoftFloat() const {
677 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
680 return getSTI().getFeatureBits()[Mips::FeatureMT];
683 bool hasCRC() const {
684 return getSTI().getFeatureBits()[Mips::FeatureCRC];
687 bool hasVirt() const {
688 return getSTI().getFeatureBits()[Mips::FeatureVirt];
691 bool hasGINV() const {
692 return getSTI().getFeatureBits()[Mips::FeatureGINV];
695 /// Warn if RegIndex is the same as the current AT.
696 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
698 void warnIfNoMacro(SMLoc Loc);
700 bool isLittle() const { return IsLittleEndian; }
702 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
703 AsmToken::TokenKind OperatorToken,
704 MCContext &Ctx) override {
705 switch(OperatorToken) {
707 llvm_unreachable("Unknown token");
709 case AsmToken::PercentCall16:
710 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
711 case AsmToken::PercentCall_Hi:
712 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
713 case AsmToken::PercentCall_Lo:
714 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
715 case AsmToken::PercentDtprel_Hi:
716 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
717 case AsmToken::PercentDtprel_Lo:
718 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
719 case AsmToken::PercentGot:
720 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
721 case AsmToken::PercentGot_Disp:
722 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
723 case AsmToken::PercentGot_Hi:
724 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
725 case AsmToken::PercentGot_Lo:
726 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
727 case AsmToken::PercentGot_Ofst:
728 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
729 case AsmToken::PercentGot_Page:
730 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
731 case AsmToken::PercentGottprel:
732 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
733 case AsmToken::PercentGp_Rel:
734 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
735 case AsmToken::PercentHi:
736 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
737 case AsmToken::PercentHigher:
738 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
739 case AsmToken::PercentHighest:
740 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
741 case AsmToken::PercentLo:
742 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
743 case AsmToken::PercentNeg:
744 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
745 case AsmToken::PercentPcrel_Hi:
746 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
747 case AsmToken::PercentPcrel_Lo:
748 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
749 case AsmToken::PercentTlsgd:
750 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
751 case AsmToken::PercentTlsldm:
752 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
753 case AsmToken::PercentTprel_Hi:
754 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
755 case AsmToken::PercentTprel_Lo:
756 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
761 /// MipsOperand - Instances of this class represent a parsed Mips machine
763 class MipsOperand : public MCParsedAsmOperand {
765 /// Broad categories of register classes
766 /// The exact class is finalized by the render method.
768 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
769 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
771 RegKind_FCC = 4, /// FCC
772 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
773 RegKind_MSACtrl = 16, /// MSA control registers
774 RegKind_COP2 = 32, /// COP2
775 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
777 RegKind_CCR = 128, /// CCR
778 RegKind_HWRegs = 256, /// HWRegs
779 RegKind_COP3 = 512, /// COP3
780 RegKind_COP0 = 1024, /// COP0
781 /// Potentially any (e.g. $1)
782 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
783 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
784 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
789 k_Immediate, /// An immediate (possibly involving symbol references)
790 k_Memory, /// Base + Offset Memory Address
791 k_RegisterIndex, /// A register index in one or more RegKind.
792 k_Token, /// A simple token
793 k_RegList, /// A physical register list
797 MipsOperand(KindTy K, MipsAsmParser &Parser)
798 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
800 ~MipsOperand() override {
809 case k_RegisterIndex:
816 /// For diagnostics, and checking the assembler temporary
817 MipsAsmParser &AsmParser;
825 unsigned Index; /// Index into the register class
826 RegKind Kind; /// Bitfield of the kinds it could possibly be
827 struct Token Tok; /// The input token this operand originated from.
828 const MCRegisterInfo *RegInfo;
841 SmallVector<unsigned, 10> *List;
846 struct RegIdxOp RegIdx;
849 struct RegListOp RegList;
852 SMLoc StartLoc, EndLoc;
854 /// Internal constructor for register kinds
855 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
857 const MCRegisterInfo *RegInfo,
859 MipsAsmParser &Parser) {
860 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
861 Op->RegIdx.Index = Index;
862 Op->RegIdx.RegInfo = RegInfo;
863 Op->RegIdx.Kind = RegKind;
864 Op->RegIdx.Tok.Data = Str.data();
865 Op->RegIdx.Tok.Length = Str.size();
872 /// Coerce the register to GPR32 and return the real register for the current
874 unsigned getGPR32Reg() const {
875 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
876 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
877 unsigned ClassID = Mips::GPR32RegClassID;
878 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
881 /// Coerce the register to GPR32 and return the real register for the current
883 unsigned getGPRMM16Reg() const {
884 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
885 unsigned ClassID = Mips::GPR32RegClassID;
886 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
889 /// Coerce the register to GPR64 and return the real register for the current
891 unsigned getGPR64Reg() const {
892 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
893 unsigned ClassID = Mips::GPR64RegClassID;
894 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
898 /// Coerce the register to AFGR64 and return the real register for the current
900 unsigned getAFGR64Reg() const {
901 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
902 if (RegIdx.Index % 2 != 0)
903 AsmParser.Warning(StartLoc, "Float register should be even.");
904 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
905 .getRegister(RegIdx.Index / 2);
908 /// Coerce the register to FGR64 and return the real register for the current
910 unsigned getFGR64Reg() const {
911 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
912 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
913 .getRegister(RegIdx.Index);
916 /// Coerce the register to FGR32 and return the real register for the current
918 unsigned getFGR32Reg() const {
919 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
920 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
921 .getRegister(RegIdx.Index);
924 /// Coerce the register to FCC and return the real register for the current
926 unsigned getFCCReg() const {
927 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
928 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
929 .getRegister(RegIdx.Index);
932 /// Coerce the register to MSA128 and return the real register for the current
934 unsigned getMSA128Reg() const {
935 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
936 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
938 unsigned ClassID = Mips::MSA128BRegClassID;
939 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
942 /// Coerce the register to MSACtrl and return the real register for the
944 unsigned getMSACtrlReg() const {
945 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
946 unsigned ClassID = Mips::MSACtrlRegClassID;
947 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
950 /// Coerce the register to COP0 and return the real register for the
952 unsigned getCOP0Reg() const {
953 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
954 unsigned ClassID = Mips::COP0RegClassID;
955 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
958 /// Coerce the register to COP2 and return the real register for the
960 unsigned getCOP2Reg() const {
961 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
962 unsigned ClassID = Mips::COP2RegClassID;
963 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
966 /// Coerce the register to COP3 and return the real register for the
968 unsigned getCOP3Reg() const {
969 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
970 unsigned ClassID = Mips::COP3RegClassID;
971 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
974 /// Coerce the register to ACC64DSP and return the real register for the
976 unsigned getACC64DSPReg() const {
977 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
978 unsigned ClassID = Mips::ACC64DSPRegClassID;
979 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
982 /// Coerce the register to HI32DSP and return the real register for the
984 unsigned getHI32DSPReg() const {
985 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
986 unsigned ClassID = Mips::HI32DSPRegClassID;
987 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
990 /// Coerce the register to LO32DSP and return the real register for the
992 unsigned getLO32DSPReg() const {
993 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
994 unsigned ClassID = Mips::LO32DSPRegClassID;
995 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
998 /// Coerce the register to CCR and return the real register for the
1000 unsigned getCCRReg() const {
1001 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
1002 unsigned ClassID = Mips::CCRRegClassID;
1003 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1006 /// Coerce the register to HWRegs and return the real register for the
1008 unsigned getHWRegsReg() const {
1009 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
1010 unsigned ClassID = Mips::HWRegsRegClassID;
1011 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1015 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1016 // Add as immediate when possible. Null MCExpr = 0.
1018 Inst.addOperand(MCOperand::createImm(0));
1019 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1020 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1022 Inst.addOperand(MCOperand::createExpr(Expr));
1025 void addRegOperands(MCInst &Inst, unsigned N) const {
1026 llvm_unreachable("Use a custom parser instead");
1029 /// Render the operand to an MCInst as a GPR32
1030 /// Asserts if the wrong number of operands are requested, or the operand
1031 /// is not a k_RegisterIndex compatible with RegKind_GPR
1032 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1033 assert(N == 1 && "Invalid number of operands!");
1034 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1037 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1038 assert(N == 1 && "Invalid number of operands!");
1039 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1042 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1043 assert(N == 1 && "Invalid number of operands!");
1044 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1047 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1048 assert(N == 1 && "Invalid number of operands!");
1049 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1052 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1053 assert(N == 1 && "Invalid number of operands!");
1054 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1057 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1058 assert(N == 1 && "Invalid number of operands!");
1059 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1062 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1063 assert(N == 1 && "Invalid number of operands!");
1064 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1067 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1069 assert(N == 1 && "Invalid number of operands!");
1070 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1073 /// Render the operand to an MCInst as a GPR64
1074 /// Asserts if the wrong number of operands are requested, or the operand
1075 /// is not a k_RegisterIndex compatible with RegKind_GPR
1076 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1077 assert(N == 1 && "Invalid number of operands!");
1078 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1081 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1082 assert(N == 1 && "Invalid number of operands!");
1083 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1086 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1087 assert(N == 1 && "Invalid number of operands!");
1088 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1091 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1096 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1097 assert(N == 1 && "Invalid number of operands!");
1098 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1101 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1102 assert(N == 1 && "Invalid number of operands!");
1103 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1104 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1105 // FIXME: This should propagate failure up to parseStatement.
1106 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1107 AsmParser.getParser().printError(
1108 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1112 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1113 assert(N == 1 && "Invalid number of operands!");
1114 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1115 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1116 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1117 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1121 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1122 assert(N == 1 && "Invalid number of operands!");
1123 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1126 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1127 assert(N == 1 && "Invalid number of operands!");
1128 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1131 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1132 assert(N == 1 && "Invalid number of operands!");
1133 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1136 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1137 assert(N == 1 && "Invalid number of operands!");
1138 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1141 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1142 assert(N == 1 && "Invalid number of operands!");
1143 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1146 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1147 assert(N == 1 && "Invalid number of operands!");
1148 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1151 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1152 assert(N == 1 && "Invalid number of operands!");
1153 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1156 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1157 assert(N == 1 && "Invalid number of operands!");
1158 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1161 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1162 assert(N == 1 && "Invalid number of operands!");
1163 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1166 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1167 assert(N == 1 && "Invalid number of operands!");
1168 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1171 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1172 assert(N == 1 && "Invalid number of operands!");
1173 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1176 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1177 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1178 assert(N == 1 && "Invalid number of operands!");
1179 uint64_t Imm = getConstantImm() - Offset;
1180 Imm &= (1ULL << Bits) - 1;
1182 Imm += AdjustOffset;
1183 Inst.addOperand(MCOperand::createImm(Imm));
1186 template <unsigned Bits>
1187 void addSImmOperands(MCInst &Inst, unsigned N) const {
1188 if (isImm() && !isConstantImm()) {
1189 addExpr(Inst, getImm());
1192 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1195 template <unsigned Bits>
1196 void addUImmOperands(MCInst &Inst, unsigned N) const {
1197 if (isImm() && !isConstantImm()) {
1198 addExpr(Inst, getImm());
1201 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1204 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1205 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1206 assert(N == 1 && "Invalid number of operands!");
1207 int64_t Imm = getConstantImm() - Offset;
1208 Imm = SignExtend64<Bits>(Imm);
1210 Imm += AdjustOffset;
1211 Inst.addOperand(MCOperand::createImm(Imm));
1214 void addImmOperands(MCInst &Inst, unsigned N) const {
1215 assert(N == 1 && "Invalid number of operands!");
1216 const MCExpr *Expr = getImm();
1217 addExpr(Inst, Expr);
1220 void addMemOperands(MCInst &Inst, unsigned N) const {
1221 assert(N == 2 && "Invalid number of operands!");
1223 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1224 ? getMemBase()->getGPR64Reg()
1225 : getMemBase()->getGPR32Reg()));
1227 const MCExpr *Expr = getMemOff();
1228 addExpr(Inst, Expr);
1231 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1232 assert(N == 2 && "Invalid number of operands!");
1234 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1236 const MCExpr *Expr = getMemOff();
1237 addExpr(Inst, Expr);
1240 void addRegListOperands(MCInst &Inst, unsigned N) const {
1241 assert(N == 1 && "Invalid number of operands!");
1243 for (auto RegNo : getRegList())
1244 Inst.addOperand(MCOperand::createReg(RegNo));
1247 bool isReg() const override {
1248 // As a special case until we sort out the definition of div/divu, accept
1249 // $0/$zero here so that MCK_ZERO works correctly.
1250 return isGPRAsmReg() && RegIdx.Index == 0;
1253 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1254 bool isImm() const override { return Kind == k_Immediate; }
1256 bool isConstantImm() const {
1258 return isImm() && getImm()->evaluateAsAbsolute(Res);
1261 bool isConstantImmz() const {
1262 return isConstantImm() && getConstantImm() == 0;
1265 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1266 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1269 template <unsigned Bits> bool isSImm() const {
1270 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1273 template <unsigned Bits> bool isUImm() const {
1274 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1277 template <unsigned Bits> bool isAnyImm() const {
1278 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1279 isUInt<Bits>(getConstantImm()))
1283 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1284 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1287 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1288 return isConstantImm() && getConstantImm() >= Bottom &&
1289 getConstantImm() <= Top;
1292 bool isToken() const override {
1293 // Note: It's not possible to pretend that other operand kinds are tokens.
1294 // The matcher emitter checks tokens first.
1295 return Kind == k_Token;
1298 bool isMem() const override { return Kind == k_Memory; }
1300 bool isConstantMemOff() const {
1301 return isMem() && isa<MCConstantExpr>(getMemOff());
1304 // Allow relocation operators.
1305 // FIXME: This predicate and others need to look through binary expressions
1306 // and determine whether a Value is a constant or not.
1307 template <unsigned Bits, unsigned ShiftAmount = 0>
1308 bool isMemWithSimmOffset() const {
1311 if (!getMemBase()->isGPRAsmReg())
1313 if (isa<MCTargetExpr>(getMemOff()) ||
1314 (isConstantMemOff() &&
1315 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1318 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1319 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1322 bool isMemWithPtrSizeOffset() const {
1325 if (!getMemBase()->isGPRAsmReg())
1327 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1328 if (isa<MCTargetExpr>(getMemOff()) ||
1329 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1332 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1333 return IsReloc && isIntN(PtrBits, Res.getConstant());
1336 bool isMemWithGRPMM16Base() const {
1337 return isMem() && getMemBase()->isMM16AsmReg();
1340 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1341 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1342 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1345 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1346 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1347 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1348 && (getMemBase()->getGPR32Reg() == Mips::SP);
1351 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1352 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1353 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1354 && (getMemBase()->getGPR32Reg() == Mips::GP);
1357 template <unsigned Bits, unsigned ShiftLeftAmount>
1358 bool isScaledUImm() const {
1359 return isConstantImm() &&
1360 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1363 template <unsigned Bits, unsigned ShiftLeftAmount>
1364 bool isScaledSImm() const {
1365 if (isConstantImm() &&
1366 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1368 // Operand can also be a symbol or symbol plus
1369 // offset in case of relocations.
1370 if (Kind != k_Immediate)
1373 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1374 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1377 bool isRegList16() const {
1381 int Size = RegList.List->size();
1382 if (Size < 2 || Size > 5)
1385 unsigned R0 = RegList.List->front();
1386 unsigned R1 = RegList.List->back();
1387 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1388 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1391 int PrevReg = *RegList.List->begin();
1392 for (int i = 1; i < Size - 1; i++) {
1393 int Reg = (*(RegList.List))[i];
1394 if ( Reg != PrevReg + 1)
1402 bool isInvNum() const { return Kind == k_Immediate; }
1404 bool isLSAImm() const {
1405 if (!isConstantImm())
1407 int64_t Val = getConstantImm();
1408 return 1 <= Val && Val <= 4;
1411 bool isRegList() const { return Kind == k_RegList; }
1413 StringRef getToken() const {
1414 assert(Kind == k_Token && "Invalid access!");
1415 return StringRef(Tok.Data, Tok.Length);
1418 unsigned getReg() const override {
1419 // As a special case until we sort out the definition of div/divu, accept
1420 // $0/$zero here so that MCK_ZERO works correctly.
1421 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1422 RegIdx.Kind & RegKind_GPR)
1423 return getGPR32Reg(); // FIXME: GPR64 too
1425 llvm_unreachable("Invalid access!");
1429 const MCExpr *getImm() const {
1430 assert((Kind == k_Immediate) && "Invalid access!");
1434 int64_t getConstantImm() const {
1435 const MCExpr *Val = getImm();
1437 (void)Val->evaluateAsAbsolute(Value);
1441 MipsOperand *getMemBase() const {
1442 assert((Kind == k_Memory) && "Invalid access!");
1446 const MCExpr *getMemOff() const {
1447 assert((Kind == k_Memory) && "Invalid access!");
1451 int64_t getConstantMemOff() const {
1452 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1455 const SmallVectorImpl<unsigned> &getRegList() const {
1456 assert((Kind == k_RegList) && "Invalid access!");
1457 return *(RegList.List);
1460 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1461 MipsAsmParser &Parser) {
1462 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1463 Op->Tok.Data = Str.data();
1464 Op->Tok.Length = Str.size();
1470 /// Create a numeric register (e.g. $1). The exact register remains
1471 /// unresolved until an instruction successfully matches
1472 static std::unique_ptr<MipsOperand>
1473 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1474 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1475 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1476 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1479 /// Create a register that is definitely a GPR.
1480 /// This is typically only used for named registers such as $gp.
1481 static std::unique_ptr<MipsOperand>
1482 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1483 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1484 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1487 /// Create a register that is definitely a FGR.
1488 /// This is typically only used for named registers such as $f0.
1489 static std::unique_ptr<MipsOperand>
1490 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1491 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1492 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1495 /// Create a register that is definitely a HWReg.
1496 /// This is typically only used for named registers such as $hwr_cpunum.
1497 static std::unique_ptr<MipsOperand>
1498 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1499 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1500 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1503 /// Create a register that is definitely an FCC.
1504 /// This is typically only used for named registers such as $fcc0.
1505 static std::unique_ptr<MipsOperand>
1506 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1507 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1508 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1511 /// Create a register that is definitely an ACC.
1512 /// This is typically only used for named registers such as $ac0.
1513 static std::unique_ptr<MipsOperand>
1514 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1515 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1516 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1519 /// Create a register that is definitely an MSA128.
1520 /// This is typically only used for named registers such as $w0.
1521 static std::unique_ptr<MipsOperand>
1522 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1523 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1524 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1527 /// Create a register that is definitely an MSACtrl.
1528 /// This is typically only used for named registers such as $msaaccess.
1529 static std::unique_ptr<MipsOperand>
1530 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1531 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1532 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1535 static std::unique_ptr<MipsOperand>
1536 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1537 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1544 static std::unique_ptr<MipsOperand>
1545 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1546 SMLoc E, MipsAsmParser &Parser) {
1547 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1548 Op->Mem.Base = Base.release();
1555 static std::unique_ptr<MipsOperand>
1556 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1557 MipsAsmParser &Parser) {
1558 assert(Regs.size() > 0 && "Empty list not allowed");
1560 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1561 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1562 Op->StartLoc = StartLoc;
1563 Op->EndLoc = EndLoc;
1567 bool isGPRZeroAsmReg() const {
1568 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1571 bool isGPRNonZeroAsmReg() const {
1572 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1576 bool isGPRAsmReg() const {
1577 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1580 bool isMM16AsmReg() const {
1581 if (!(isRegIdx() && RegIdx.Kind))
1583 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1584 || RegIdx.Index == 16 || RegIdx.Index == 17);
1587 bool isMM16AsmRegZero() const {
1588 if (!(isRegIdx() && RegIdx.Kind))
1590 return (RegIdx.Index == 0 ||
1591 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1592 RegIdx.Index == 17);
1595 bool isMM16AsmRegMoveP() const {
1596 if (!(isRegIdx() && RegIdx.Kind))
1598 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1599 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1602 bool isMM16AsmRegMovePPairFirst() const {
1603 if (!(isRegIdx() && RegIdx.Kind))
1605 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1608 bool isMM16AsmRegMovePPairSecond() const {
1609 if (!(isRegIdx() && RegIdx.Kind))
1611 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1612 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1615 bool isFGRAsmReg() const {
1616 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1617 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1620 bool isStrictlyFGRAsmReg() const {
1621 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1622 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1625 bool isHWRegsAsmReg() const {
1626 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1629 bool isCCRAsmReg() const {
1630 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1633 bool isFCCAsmReg() const {
1634 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1636 return RegIdx.Index <= 7;
1639 bool isACCAsmReg() const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1643 bool isCOP0AsmReg() const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1647 bool isCOP2AsmReg() const {
1648 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1651 bool isCOP3AsmReg() const {
1652 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1655 bool isMSA128AsmReg() const {
1656 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1659 bool isMSACtrlAsmReg() const {
1660 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1663 /// getStartLoc - Get the location of the first token of this operand.
1664 SMLoc getStartLoc() const override { return StartLoc; }
1665 /// getEndLoc - Get the location of the last token of this operand.
1666 SMLoc getEndLoc() const override { return EndLoc; }
1668 void print(raw_ostream &OS) const override {
1677 Mem.Base->print(OS);
1682 case k_RegisterIndex:
1683 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1684 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1691 for (auto Reg : (*RegList.List))
1698 bool isValidForTie(const MipsOperand &Other) const {
1699 if (Kind != Other.Kind)
1704 llvm_unreachable("Unexpected kind");
1706 case k_RegisterIndex: {
1707 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1708 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1709 return Token == OtherToken;
1713 }; // class MipsOperand
1715 } // end anonymous namespace
1719 extern const MCInstrDesc MipsInsts[];
1721 } // end namespace llvm
1723 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1724 return MipsInsts[Opcode];
1727 static bool hasShortDelaySlot(MCInst &Inst) {
1728 switch (Inst.getOpcode()) {
1735 case Mips::JRC16_MM:
1737 case Mips::JALRS_MM:
1738 case Mips::JALRS16_MM:
1739 case Mips::BGEZALS_MM:
1740 case Mips::BLTZALS_MM:
1743 return !Inst.getOperand(0).isReg();
1749 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1750 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1751 return &SRExpr->getSymbol();
1754 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1755 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1756 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1767 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1768 return getSingleMCSymbol(UExpr->getSubExpr());
1773 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1774 if (isa<MCSymbolRefExpr>(Expr))
1777 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1778 return countMCSymbolRefExpr(BExpr->getLHS()) +
1779 countMCSymbolRefExpr(BExpr->getRHS());
1781 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1782 return countMCSymbolRefExpr(UExpr->getSubExpr());
1787 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1789 const MCSubtargetInfo *STI) {
1790 MipsTargetStreamer &TOut = getTargetStreamer();
1791 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1792 bool ExpandedJalSym = false;
1796 if (MCID.isBranch() || MCID.isCall()) {
1797 const unsigned Opcode = Inst.getOpcode();
1807 assert(hasCnMips() && "instruction only valid for octeon cpus");
1814 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1815 Offset = Inst.getOperand(2);
1816 if (!Offset.isImm())
1817 break; // We'll deal with this situation later on when applying fixups.
1818 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1819 return Error(IDLoc, "branch target out of range");
1820 if (OffsetToAlignment(Offset.getImm(),
1821 1LL << (inMicroMipsMode() ? 1 : 2)))
1822 return Error(IDLoc, "branch to misaligned address");
1836 case Mips::BGEZAL_MM:
1837 case Mips::BLTZAL_MM:
1840 case Mips::BC1EQZC_MMR6:
1841 case Mips::BC1NEZC_MMR6:
1842 case Mips::BC2EQZC_MMR6:
1843 case Mips::BC2NEZC_MMR6:
1844 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1845 Offset = Inst.getOperand(1);
1846 if (!Offset.isImm())
1847 break; // We'll deal with this situation later on when applying fixups.
1848 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1849 return Error(IDLoc, "branch target out of range");
1850 if (OffsetToAlignment(Offset.getImm(),
1851 1LL << (inMicroMipsMode() ? 1 : 2)))
1852 return Error(IDLoc, "branch to misaligned address");
1854 case Mips::BGEC: case Mips::BGEC_MMR6:
1855 case Mips::BLTC: case Mips::BLTC_MMR6:
1856 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1857 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1858 case Mips::BEQC: case Mips::BEQC_MMR6:
1859 case Mips::BNEC: case Mips::BNEC_MMR6:
1860 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1861 Offset = Inst.getOperand(2);
1862 if (!Offset.isImm())
1863 break; // We'll deal with this situation later on when applying fixups.
1864 if (!isIntN(18, Offset.getImm()))
1865 return Error(IDLoc, "branch target out of range");
1866 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1867 return Error(IDLoc, "branch to misaligned address");
1869 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1870 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1871 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1872 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1873 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1874 Offset = Inst.getOperand(1);
1875 if (!Offset.isImm())
1876 break; // We'll deal with this situation later on when applying fixups.
1877 if (!isIntN(18, Offset.getImm()))
1878 return Error(IDLoc, "branch target out of range");
1879 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1880 return Error(IDLoc, "branch to misaligned address");
1882 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1883 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1884 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1885 Offset = Inst.getOperand(1);
1886 if (!Offset.isImm())
1887 break; // We'll deal with this situation later on when applying fixups.
1888 if (!isIntN(23, Offset.getImm()))
1889 return Error(IDLoc, "branch target out of range");
1890 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1891 return Error(IDLoc, "branch to misaligned address");
1893 case Mips::BEQZ16_MM:
1894 case Mips::BEQZC16_MMR6:
1895 case Mips::BNEZ16_MM:
1896 case Mips::BNEZC16_MMR6:
1897 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1898 Offset = Inst.getOperand(1);
1899 if (!Offset.isImm())
1900 break; // We'll deal with this situation later on when applying fixups.
1901 if (!isInt<8>(Offset.getImm()))
1902 return Error(IDLoc, "branch target out of range");
1903 if (OffsetToAlignment(Offset.getImm(), 2LL))
1904 return Error(IDLoc, "branch to misaligned address");
1909 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1910 // We still accept it but it is a normal nop.
1911 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1912 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1913 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1918 const unsigned Opcode = Inst.getOpcode();
1930 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1931 // The offset is handled above
1932 Opnd = Inst.getOperand(1);
1934 return Error(IDLoc, "expected immediate operand kind");
1935 Imm = Opnd.getImm();
1936 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1937 Opcode == Mips::BBIT1 ? 63 : 31))
1938 return Error(IDLoc, "immediate operand value out of range");
1940 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1942 Inst.getOperand(1).setImm(Imm - 32);
1948 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1949 Opnd = Inst.getOperand(2);
1951 return Error(IDLoc, "expected immediate operand kind");
1952 Imm = Opnd.getImm();
1953 if (!isInt<10>(Imm))
1954 return Error(IDLoc, "immediate operand value out of range");
1959 // Warn on division by zero. We're checking here as all instructions get
1960 // processed here, not just the macros that need expansion.
1962 // The MIPS backend models most of the divison instructions and macros as
1963 // three operand instructions. The pre-R6 divide instructions however have
1964 // two operands and explicitly define HI/LO as part of the instruction,
1965 // not in the operands.
1966 unsigned FirstOp = 1;
1967 unsigned SecondOp = 2;
1968 switch (Inst.getOpcode()) {
1971 case Mips::SDivIMacro:
1972 case Mips::UDivIMacro:
1973 case Mips::DSDivIMacro:
1974 case Mips::DUDivIMacro:
1975 if (Inst.getOperand(2).getImm() == 0) {
1976 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1977 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1978 Warning(IDLoc, "dividing zero by zero");
1980 Warning(IDLoc, "division by zero");
1992 case Mips::SDivMacro:
1993 case Mips::DSDivMacro:
1994 case Mips::UDivMacro:
1995 case Mips::DUDivMacro:
2000 case Mips::DIVU_MMR6:
2001 case Mips::DIV_MMR6:
2002 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2003 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2004 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2005 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2006 Warning(IDLoc, "dividing zero by zero");
2008 Warning(IDLoc, "division by zero");
2013 // For PIC code convert unconditional jump to unconditional branch.
2014 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2017 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2018 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2019 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2020 BInst.addOperand(Inst.getOperand(0));
2024 // This expansion is not in a function called by tryExpandInstruction()
2025 // because the pseudo-instruction doesn't have a distinct opcode.
2026 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2028 warnIfNoMacro(IDLoc);
2030 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2032 // We can do this expansion if there's only 1 symbol in the argument
2034 if (countMCSymbolRefExpr(JalExpr) > 1)
2035 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2037 // FIXME: This is checking the expression can be handled by the later stages
2038 // of the assembler. We ought to leave it to those later stages.
2039 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2041 // FIXME: Add support for label+offset operands (currently causes an error).
2042 // FIXME: Add support for forward-declared local symbols.
2043 // FIXME: Add expansion for when the LargeGOT option is enabled.
2044 if (JalSym->isInSection() || JalSym->isTemporary() ||
2046 cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2048 // If it's a local symbol and the O32 ABI is being used, we expand to:
2050 // R_(MICRO)MIPS_GOT16 label
2051 // addiu $25, $25, 0
2052 // R_(MICRO)MIPS_LO16 label
2054 const MCExpr *Got16RelocExpr =
2055 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2056 const MCExpr *Lo16RelocExpr =
2057 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2059 TOut.emitRRX(Mips::LW, Mips::T9, GPReg,
2060 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2061 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2062 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2063 } else if (isABI_N32() || isABI_N64()) {
2064 // If it's a local symbol and the N32/N64 ABIs are being used,
2066 // lw/ld $25, 0($gp)
2067 // R_(MICRO)MIPS_GOT_DISP label
2069 const MCExpr *GotDispRelocExpr =
2070 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2072 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2073 GPReg, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2077 // If it's an external/weak symbol, we expand to:
2078 // lw/ld $25, 0($gp)
2079 // R_(MICRO)MIPS_CALL16 label
2081 const MCExpr *Call16RelocExpr =
2082 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2084 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, GPReg,
2085 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2089 if (IsCpRestoreSet && inMicroMipsMode())
2090 JalrInst.setOpcode(Mips::JALRS_MM);
2092 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2093 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2094 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2096 if (EmitJalrReloc) {
2097 // As an optimization hint for the linker, before the JALR we add:
2098 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2100 MCSymbol *TmpLabel = getContext().createTempSymbol();
2101 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2102 const MCExpr *RelocJalrExpr =
2103 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2104 getContext(), IDLoc);
2106 TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2107 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2108 RelocJalrExpr, IDLoc, *STI);
2109 TOut.getStreamer().EmitLabel(TmpLabel);
2113 ExpandedJalSym = true;
2116 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2117 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2118 // Check the offset of memory operand, if it is a symbol
2119 // reference or immediate we may have to expand instructions.
2120 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2121 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2122 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2123 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2124 MCOperand &Op = Inst.getOperand(i);
2126 int64_t MemOffset = Op.getImm();
2127 if (MemOffset < -32768 || MemOffset > 32767) {
2128 // Offset can't exceed 16bit value.
2129 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2130 return getParser().hasPendingError();
2132 } else if (Op.isExpr()) {
2133 const MCExpr *Expr = Op.getExpr();
2134 if (Expr->getKind() == MCExpr::SymbolRef) {
2135 const MCSymbolRefExpr *SR =
2136 static_cast<const MCSymbolRefExpr *>(Expr);
2137 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2139 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2140 return getParser().hasPendingError();
2142 } else if (!isEvaluated(Expr)) {
2143 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2144 return getParser().hasPendingError();
2151 if (inMicroMipsMode()) {
2152 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2153 // Try to create 16-bit GP relative load instruction.
2154 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2155 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2156 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2157 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2158 MCOperand &Op = Inst.getOperand(i);
2160 int MemOffset = Op.getImm();
2161 MCOperand &DstReg = Inst.getOperand(0);
2162 MCOperand &BaseReg = Inst.getOperand(1);
2163 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2164 getContext().getRegisterInfo()->getRegClass(
2165 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2166 (BaseReg.getReg() == Mips::GP ||
2167 BaseReg.getReg() == Mips::GP_64)) {
2169 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2178 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2183 switch (Inst.getOpcode()) {
2186 case Mips::ADDIUSP_MM:
2187 Opnd = Inst.getOperand(0);
2189 return Error(IDLoc, "expected immediate operand kind");
2190 Imm = Opnd.getImm();
2191 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2193 return Error(IDLoc, "immediate operand value out of range");
2195 case Mips::SLL16_MM:
2196 case Mips::SRL16_MM:
2197 Opnd = Inst.getOperand(2);
2199 return Error(IDLoc, "expected immediate operand kind");
2200 Imm = Opnd.getImm();
2201 if (Imm < 1 || Imm > 8)
2202 return Error(IDLoc, "immediate operand value out of range");
2205 Opnd = Inst.getOperand(1);
2207 return Error(IDLoc, "expected immediate operand kind");
2208 Imm = Opnd.getImm();
2209 if (Imm < -1 || Imm > 126)
2210 return Error(IDLoc, "immediate operand value out of range");
2212 case Mips::ADDIUR2_MM:
2213 Opnd = Inst.getOperand(2);
2215 return Error(IDLoc, "expected immediate operand kind");
2216 Imm = Opnd.getImm();
2217 if (!(Imm == 1 || Imm == -1 ||
2218 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2219 return Error(IDLoc, "immediate operand value out of range");
2221 case Mips::ANDI16_MM:
2222 Opnd = Inst.getOperand(2);
2224 return Error(IDLoc, "expected immediate operand kind");
2225 Imm = Opnd.getImm();
2226 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2227 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2228 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2229 return Error(IDLoc, "immediate operand value out of range");
2231 case Mips::LBU16_MM:
2232 Opnd = Inst.getOperand(2);
2234 return Error(IDLoc, "expected immediate operand kind");
2235 Imm = Opnd.getImm();
2236 if (Imm < -1 || Imm > 14)
2237 return Error(IDLoc, "immediate operand value out of range");
2240 case Mips::SB16_MMR6:
2241 Opnd = Inst.getOperand(2);
2243 return Error(IDLoc, "expected immediate operand kind");
2244 Imm = Opnd.getImm();
2245 if (Imm < 0 || Imm > 15)
2246 return Error(IDLoc, "immediate operand value out of range");
2248 case Mips::LHU16_MM:
2250 case Mips::SH16_MMR6:
2251 Opnd = Inst.getOperand(2);
2253 return Error(IDLoc, "expected immediate operand kind");
2254 Imm = Opnd.getImm();
2255 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2256 return Error(IDLoc, "immediate operand value out of range");
2260 case Mips::SW16_MMR6:
2261 Opnd = Inst.getOperand(2);
2263 return Error(IDLoc, "expected immediate operand kind");
2264 Imm = Opnd.getImm();
2265 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2266 return Error(IDLoc, "immediate operand value out of range");
2268 case Mips::ADDIUPC_MM:
2269 Opnd = Inst.getOperand(1);
2271 return Error(IDLoc, "expected immediate operand kind");
2272 Imm = Opnd.getImm();
2273 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2274 return Error(IDLoc, "immediate operand value out of range");
2278 if (Inst.getOperand(0).getReg() == Mips::RA)
2279 return Error(IDLoc, "invalid operand for instruction");
2281 case Mips::MOVEP_MM:
2282 case Mips::MOVEP_MMR6: {
2283 unsigned R0 = Inst.getOperand(0).getReg();
2284 unsigned R1 = Inst.getOperand(1).getReg();
2285 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2286 (R0 == Mips::A1 && R1 == Mips::A3) ||
2287 (R0 == Mips::A2 && R1 == Mips::A3) ||
2288 (R0 == Mips::A0 && R1 == Mips::S5) ||
2289 (R0 == Mips::A0 && R1 == Mips::S6) ||
2290 (R0 == Mips::A0 && R1 == Mips::A1) ||
2291 (R0 == Mips::A0 && R1 == Mips::A2) ||
2292 (R0 == Mips::A0 && R1 == Mips::A3));
2294 return Error(IDLoc, "invalid operand for instruction");
2300 bool FillDelaySlot =
2301 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2303 TOut.emitDirectiveSetNoReorder();
2305 MacroExpanderResultTy ExpandResult =
2306 tryExpandInstruction(Inst, IDLoc, Out, STI);
2307 switch (ExpandResult) {
2309 Out.EmitInstruction(Inst, *STI);
2317 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2318 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2319 if (inMicroMipsMode()) {
2320 TOut.setUsesMicroMips();
2321 TOut.updateABIInfo(*this);
2324 // If this instruction has a delay slot and .set reorder is active,
2325 // emit a NOP after it.
2326 if (FillDelaySlot) {
2327 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2328 TOut.emitDirectiveSetReorder();
2331 if ((Inst.getOpcode() == Mips::JalOneReg ||
2332 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2333 isPicAndNotNxxAbi()) {
2334 if (IsCpRestoreSet) {
2335 // We need a NOP between the JALR and the LW:
2336 // If .set reorder has been used, we've already emitted a NOP.
2337 // If .set noreorder has been used, we need to emit a NOP at this point.
2338 if (!AssemblerOptions.back()->isReorder())
2339 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2342 // Load the $gp from the stack.
2343 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2345 Warning(IDLoc, "no .cprestore used in PIC mode");
2351 MipsAsmParser::MacroExpanderResultTy
2352 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2353 const MCSubtargetInfo *STI) {
2354 switch (Inst.getOpcode()) {
2356 return MER_NotAMacro;
2357 case Mips::LoadImm32:
2358 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2359 case Mips::LoadImm64:
2360 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2361 case Mips::LoadAddrImm32:
2362 case Mips::LoadAddrImm64:
2363 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2364 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2365 "expected immediate operand kind");
2367 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2369 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2373 case Mips::LoadAddrReg32:
2374 case Mips::LoadAddrReg64:
2375 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2376 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2377 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2378 "expected immediate operand kind");
2380 return expandLoadAddress(Inst.getOperand(0).getReg(),
2381 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2382 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2386 case Mips::B_MM_Pseudo:
2387 case Mips::B_MMR6_Pseudo:
2388 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2392 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2394 case Mips::JalOneReg:
2395 case Mips::JalTwoReg:
2396 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2399 case Mips::BEQLImmMacro:
2400 case Mips::BNELImmMacro:
2401 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2418 case Mips::BLTImmMacro:
2419 case Mips::BLEImmMacro:
2420 case Mips::BGEImmMacro:
2421 case Mips::BGTImmMacro:
2422 case Mips::BLTUImmMacro:
2423 case Mips::BLEUImmMacro:
2424 case Mips::BGEUImmMacro:
2425 case Mips::BGTUImmMacro:
2426 case Mips::BLTLImmMacro:
2427 case Mips::BLELImmMacro:
2428 case Mips::BGELImmMacro:
2429 case Mips::BGTLImmMacro:
2430 case Mips::BLTULImmMacro:
2431 case Mips::BLEULImmMacro:
2432 case Mips::BGEULImmMacro:
2433 case Mips::BGTULImmMacro:
2434 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2435 case Mips::SDivMacro:
2436 case Mips::SDivIMacro:
2437 case Mips::SRemMacro:
2438 case Mips::SRemIMacro:
2439 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2441 case Mips::DSDivMacro:
2442 case Mips::DSDivIMacro:
2443 case Mips::DSRemMacro:
2444 case Mips::DSRemIMacro:
2445 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2447 case Mips::UDivMacro:
2448 case Mips::UDivIMacro:
2449 case Mips::URemMacro:
2450 case Mips::URemIMacro:
2451 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2453 case Mips::DUDivMacro:
2454 case Mips::DUDivIMacro:
2455 case Mips::DURemMacro:
2456 case Mips::DURemIMacro:
2457 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2459 case Mips::PseudoTRUNC_W_S:
2460 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2462 case Mips::PseudoTRUNC_W_D32:
2463 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2465 case Mips::PseudoTRUNC_W_D:
2466 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2469 case Mips::LoadImmSingleGPR:
2470 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2472 case Mips::LoadImmSingleFGR:
2473 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2475 case Mips::LoadImmDoubleGPR:
2476 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2478 case Mips::LoadImmDoubleFGR:
2479 return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2481 case Mips::LoadImmDoubleFGR_32:
2482 return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2486 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2488 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2495 case Mips::NORImm64:
2496 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2499 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2502 case Mips::SGEImm64:
2503 case Mips::SGEUImm64:
2504 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2507 case Mips::SGTImm64:
2508 case Mips::SGTUImm64:
2509 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2510 case Mips::SLTImm64:
2511 if (isInt<16>(Inst.getOperand(2).getImm())) {
2512 Inst.setOpcode(Mips::SLTi64);
2513 return MER_NotAMacro;
2515 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2516 case Mips::SLTUImm64:
2517 if (isInt<16>(Inst.getOperand(2).getImm())) {
2518 Inst.setOpcode(Mips::SLTiu64);
2519 return MER_NotAMacro;
2521 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2522 case Mips::ADDi: case Mips::ADDi_MM:
2523 case Mips::ADDiu: case Mips::ADDiu_MM:
2524 case Mips::SLTi: case Mips::SLTi_MM:
2525 case Mips::SLTiu: case Mips::SLTiu_MM:
2526 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2527 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2528 int64_t ImmValue = Inst.getOperand(2).getImm();
2529 if (isInt<16>(ImmValue))
2530 return MER_NotAMacro;
2531 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2534 return MER_NotAMacro;
2535 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2536 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2537 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2538 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2539 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2540 int64_t ImmValue = Inst.getOperand(2).getImm();
2541 if (isUInt<16>(ImmValue))
2542 return MER_NotAMacro;
2543 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2546 return MER_NotAMacro;
2549 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2558 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2559 case Mips::ABSMacro:
2560 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2561 case Mips::MULImmMacro:
2562 case Mips::DMULImmMacro:
2563 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564 case Mips::MULOMacro:
2565 case Mips::DMULOMacro:
2566 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2567 case Mips::MULOUMacro:
2568 case Mips::DMULOUMacro:
2569 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2570 case Mips::DMULMacro:
2571 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2575 Inst.getOpcode() == Mips::LDMacro)
2579 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2582 case Mips::SEQMacro:
2583 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2584 case Mips::SEQIMacro:
2585 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2586 case Mips::MFTC0: case Mips::MTTC0:
2587 case Mips::MFTGPR: case Mips::MTTGPR:
2588 case Mips::MFTLO: case Mips::MTTLO:
2589 case Mips::MFTHI: case Mips::MTTHI:
2590 case Mips::MFTACX: case Mips::MTTACX:
2591 case Mips::MFTDSP: case Mips::MTTDSP:
2592 case Mips::MFTC1: case Mips::MTTC1:
2593 case Mips::MFTHC1: case Mips::MTTHC1:
2594 case Mips::CFTC1: case Mips::CTTC1:
2595 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2597 case Mips::SaadAddr:
2598 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2604 const MCSubtargetInfo *STI) {
2605 MipsTargetStreamer &TOut = getTargetStreamer();
2607 // Create a JALR instruction which is going to replace the pseudo-JAL.
2609 JalrInst.setLoc(IDLoc);
2610 const MCOperand FirstRegOp = Inst.getOperand(0);
2611 const unsigned Opcode = Inst.getOpcode();
2613 if (Opcode == Mips::JalOneReg) {
2614 // jal $rs => jalr $rs
2615 if (IsCpRestoreSet && inMicroMipsMode()) {
2616 JalrInst.setOpcode(Mips::JALRS16_MM);
2617 JalrInst.addOperand(FirstRegOp);
2618 } else if (inMicroMipsMode()) {
2619 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2620 JalrInst.addOperand(FirstRegOp);
2622 JalrInst.setOpcode(Mips::JALR);
2623 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2624 JalrInst.addOperand(FirstRegOp);
2626 } else if (Opcode == Mips::JalTwoReg) {
2627 // jal $rd, $rs => jalr $rd, $rs
2628 if (IsCpRestoreSet && inMicroMipsMode())
2629 JalrInst.setOpcode(Mips::JALRS_MM);
2631 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2632 JalrInst.addOperand(FirstRegOp);
2633 const MCOperand SecondRegOp = Inst.getOperand(1);
2634 JalrInst.addOperand(SecondRegOp);
2636 Out.EmitInstruction(JalrInst, *STI);
2638 // If .set reorder is active and branch instruction has a delay slot,
2639 // emit a NOP after it.
2640 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2641 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2642 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2648 /// Can the value be represented by a unsigned N-bit value and a shift left?
2649 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2650 unsigned BitNum = findFirstSet(x);
2652 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2655 /// Load (or add) an immediate into a register.
2657 /// @param ImmValue The immediate to load.
2658 /// @param DstReg The register that will hold the immediate.
2659 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2660 /// for a simple initialization.
2661 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2662 /// @param IsAddress True if the immediate represents an address. False if it
2664 /// @param IDLoc Location of the immediate in the source file.
2665 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2666 unsigned SrcReg, bool Is32BitImm,
2667 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2668 const MCSubtargetInfo *STI) {
2669 MipsTargetStreamer &TOut = getTargetStreamer();
2671 if (!Is32BitImm && !isGP64bit()) {
2672 Error(IDLoc, "instruction requires a 64-bit architecture");
2677 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2678 // Sign extend up to 64-bit so that the predicates match the hardware
2679 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2681 ImmValue = SignExtend64<32>(ImmValue);
2683 Error(IDLoc, "instruction requires a 32-bit immediate");
2688 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2689 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2691 bool UseSrcReg = false;
2692 if (SrcReg != Mips::NoRegister)
2695 unsigned TmpReg = DstReg;
2697 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2698 // At this point we need AT to perform the expansions and we exit if it is
2700 unsigned ATReg = getATReg(IDLoc);
2706 if (isInt<16>(ImmValue)) {
2710 // This doesn't quite follow the usual ABI expectations for N32 but matches
2711 // traditional assembler behaviour. N32 would normally use addiu for both
2712 // integers and addresses.
2713 if (IsAddress && !Is32BitImm) {
2714 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2718 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2722 if (isUInt<16>(ImmValue)) {
2723 unsigned TmpReg = DstReg;
2724 if (SrcReg == DstReg) {
2725 TmpReg = getATReg(IDLoc);
2730 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2732 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2736 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2737 warnIfNoMacro(IDLoc);
2739 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2740 uint16_t Bits15To0 = ImmValue & 0xffff;
2741 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2742 // Traditional behaviour seems to special case this particular value. It's
2743 // not clear why other masks are handled differently.
2744 if (ImmValue == 0xffffffff) {
2745 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2746 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2748 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2752 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2754 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2755 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2757 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2759 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2763 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2765 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2767 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2771 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2773 Error(IDLoc, "instruction requires a 32-bit immediate");
2777 // Traditionally, these immediates are shifted as little as possible and as
2778 // such we align the most significant bit to bit 15 of our temporary.
2779 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2780 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2781 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2782 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2783 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2784 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2787 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2792 warnIfNoMacro(IDLoc);
2794 // The remaining case is packed with a sequence of dsll and ori with zeros
2795 // being omitted and any neighbouring dsll's being coalesced.
2796 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2798 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2799 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2803 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2804 // skip it and defer the shift to the next chunk.
2805 unsigned ShiftCarriedForwards = 16;
2806 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2807 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2809 if (ImmChunk != 0) {
2810 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2811 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2812 ShiftCarriedForwards = 0;
2815 ShiftCarriedForwards += 16;
2817 ShiftCarriedForwards -= 16;
2819 // Finish any remaining shifts left by trailing zeros.
2820 if (ShiftCarriedForwards)
2821 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2824 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2829 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2830 MCStreamer &Out, const MCSubtargetInfo *STI) {
2831 const MCOperand &ImmOp = Inst.getOperand(1);
2832 assert(ImmOp.isImm() && "expected immediate operand kind");
2833 const MCOperand &DstRegOp = Inst.getOperand(0);
2834 assert(DstRegOp.isReg() && "expected register operand kind");
2836 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2837 Is32BitImm, false, IDLoc, Out, STI))
2843 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2844 const MCOperand &Offset,
2845 bool Is32BitAddress, SMLoc IDLoc,
2847 const MCSubtargetInfo *STI) {
2848 // la can't produce a usable address when addresses are 64-bit.
2849 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2850 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2851 // We currently can't do this because we depend on the equality
2852 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2853 Error(IDLoc, "la used to load 64-bit address");
2854 // Continue as if we had 'dla' instead.
2855 Is32BitAddress = false;
2859 // dla requires 64-bit addresses.
2860 if (!Is32BitAddress && !hasMips3()) {
2861 Error(IDLoc, "instruction requires a 64-bit architecture");
2865 if (!Offset.isImm())
2866 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2867 Is32BitAddress, IDLoc, Out, STI);
2869 if (!ABI.ArePtrs64bit()) {
2870 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2871 Is32BitAddress = true;
2874 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2878 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2879 unsigned DstReg, unsigned SrcReg,
2880 bool Is32BitSym, SMLoc IDLoc,
2882 const MCSubtargetInfo *STI) {
2883 // FIXME: These expansions do not respect -mxgot.
2884 MipsTargetStreamer &TOut = getTargetStreamer();
2885 bool UseSrcReg = SrcReg != Mips::NoRegister;
2886 warnIfNoMacro(IDLoc);
2888 if (inPicMode() && ABI.IsO32()) {
2890 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2891 Error(IDLoc, "expected relocatable expression");
2894 if (Res.getSymB() != nullptr) {
2895 Error(IDLoc, "expected relocatable expression with only one symbol");
2899 // The case where the result register is $25 is somewhat special. If the
2900 // symbol in the final relocation is external and not modified with a
2901 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2902 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2903 Res.getConstant() == 0 &&
2904 !(Res.getSymA()->getSymbol().isInSection() ||
2905 Res.getSymA()->getSymbol().isTemporary() ||
2906 (Res.getSymA()->getSymbol().isELF() &&
2907 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2909 const MCExpr *CallExpr =
2910 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2911 TOut.emitRRX(Mips::LW, DstReg, GPReg, MCOperand::createExpr(CallExpr),
2916 // The remaining cases are:
2917 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2918 // >addiu $tmp, $tmp, %lo(offset)
2919 // >addiu $rd, $tmp, $rs
2920 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2921 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2922 // >addiu $rd, $tmp, $rs
2923 // The addiu's marked with a '>' may be omitted if they are redundant. If
2924 // this happens then the last instruction must use $rd as the result
2926 const MipsMCExpr *GotExpr =
2927 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2928 const MCExpr *LoExpr = nullptr;
2929 if (Res.getSymA()->getSymbol().isInSection() ||
2930 Res.getSymA()->getSymbol().isTemporary())
2931 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2932 else if (Res.getConstant() != 0) {
2933 // External symbols fully resolve the symbol with just the %got(symbol)
2934 // but we must still account for any offset to the symbol for expressions
2936 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2939 unsigned TmpReg = DstReg;
2941 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2943 // If $rs is the same as $rd, we need to use AT.
2944 // If it is not available we exit.
2945 unsigned ATReg = getATReg(IDLoc);
2951 TOut.emitRRX(Mips::LW, TmpReg, GPReg, MCOperand::createExpr(GotExpr), IDLoc,
2955 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2959 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2964 if (inPicMode() && ABI.ArePtrs64bit()) {
2966 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2967 Error(IDLoc, "expected relocatable expression");
2970 if (Res.getSymB() != nullptr) {
2971 Error(IDLoc, "expected relocatable expression with only one symbol");
2975 // The case where the result register is $25 is somewhat special. If the
2976 // symbol in the final relocation is external and not modified with a
2977 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2978 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2979 Res.getConstant() == 0 &&
2980 !(Res.getSymA()->getSymbol().isInSection() ||
2981 Res.getSymA()->getSymbol().isTemporary() ||
2982 (Res.getSymA()->getSymbol().isELF() &&
2983 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2985 const MCExpr *CallExpr =
2986 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2987 TOut.emitRRX(Mips::LD, DstReg, GPReg, MCOperand::createExpr(CallExpr),
2992 // The remaining cases are:
2993 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2994 // >daddiu $tmp, $tmp, offset
2995 // >daddu $rd, $tmp, $rs
2996 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2997 // this happens then the last instruction must use $rd as the result
2999 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
3002 const MCExpr *LoExpr = nullptr;
3003 if (Res.getConstant() != 0) {
3004 // Symbols fully resolve with just the %got_disp(symbol) but we
3005 // must still account for any offset to the symbol for
3006 // expressions like symbol+8.
3007 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3009 // FIXME: Offsets greater than 16 bits are not yet implemented.
3010 // FIXME: The correct range is a 32-bit sign-extended number.
3011 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3012 Error(IDLoc, "macro instruction uses large offset, which is not "
3013 "currently supported");
3018 unsigned TmpReg = DstReg;
3020 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3022 // If $rs is the same as $rd, we need to use AT.
3023 // If it is not available we exit.
3024 unsigned ATReg = getATReg(IDLoc);
3030 TOut.emitRRX(Mips::LD, TmpReg, GPReg, MCOperand::createExpr(GotExpr), IDLoc,
3034 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3038 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3043 const MipsMCExpr *HiExpr =
3044 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3045 const MipsMCExpr *LoExpr =
3046 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3048 // This is the 64-bit symbol address expansion.
3049 if (ABI.ArePtrs64bit() && isGP64bit()) {
3050 // We need AT for the 64-bit expansion in the cases where the optional
3051 // source register is the destination register and for the superscalar
3054 // If it is not available we exit if the destination is the same as the
3057 const MipsMCExpr *HighestExpr =
3058 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3059 const MipsMCExpr *HigherExpr =
3060 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3063 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3065 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3066 unsigned ATReg = getATReg(IDLoc);
3068 // If $rs is the same as $rd:
3069 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3070 // daddiu $at, $at, %higher(sym)
3071 // dsll $at, $at, 16
3072 // daddiu $at, $at, %hi(sym)
3073 // dsll $at, $at, 16
3074 // daddiu $at, $at, %lo(sym)
3075 // daddu $rd, $at, $rd
3076 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3078 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3079 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3080 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3081 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3083 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3084 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3086 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3089 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3090 unsigned ATReg = getATReg(IDLoc);
3092 // If the $rs is different from $rd or if $rs isn't specified and we
3093 // have $at available:
3094 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3095 // lui $at, %hi(sym)
3096 // daddiu $rd, $rd, %higher(sym)
3097 // daddiu $at, $at, %lo(sym)
3098 // dsll32 $rd, $rd, 0
3099 // daddu $rd, $rd, $at
3100 // (daddu $rd, $rd, $rs)
3102 // Which is preferred for superscalar issue.
3103 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3105 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3106 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3107 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3108 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3110 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3111 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3113 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3116 } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3117 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3118 // Otherwise, synthesize the address in the destination register
3120 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3121 // daddiu $rd, $rd, %higher(sym)
3122 // dsll $rd, $rd, 16
3123 // daddiu $rd, $rd, %hi(sym)
3124 // dsll $rd, $rd, 16
3125 // daddiu $rd, $rd, %lo(sym)
3126 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3128 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3129 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3130 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3131 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3132 MCOperand::createExpr(HiExpr), IDLoc, STI);
3133 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3134 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3135 MCOperand::createExpr(LoExpr), IDLoc, STI);
3137 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3141 // We have a case where SrcReg == DstReg and we don't have $at
3142 // available. We can't expand this case, so error out appropriately.
3143 assert(SrcReg == DstReg && !canUseATReg() &&
3144 "Could have expanded dla but didn't?");
3145 reportParseError(IDLoc,
3146 "pseudo-instruction requires $at, which is not available");
3151 // And now, the 32-bit symbol address expansion:
3152 // If $rs is the same as $rd:
3153 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3154 // ori $at, $at, %lo(sym)
3155 // addu $rd, $at, $rd
3156 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3157 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3158 // ori $rd, $rd, %lo(sym)
3159 // (addu $rd, $rd, $rs)
3160 unsigned TmpReg = DstReg;
3162 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3163 // If $rs is the same as $rd, we need to use AT.
3164 // If it is not available we exit.
3165 unsigned ATReg = getATReg(IDLoc);
3171 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3172 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3176 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3179 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3184 // Each double-precision register DO-D15 overlaps with two of the single
3185 // precision registers F0-F31. As an example, all of the following hold true:
3186 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3187 static unsigned nextReg(unsigned Reg) {
3188 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3189 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3191 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3192 case Mips::ZERO: return Mips::AT;
3193 case Mips::AT: return Mips::V0;
3194 case Mips::V0: return Mips::V1;
3195 case Mips::V1: return Mips::A0;
3196 case Mips::A0: return Mips::A1;
3197 case Mips::A1: return Mips::A2;
3198 case Mips::A2: return Mips::A3;
3199 case Mips::A3: return Mips::T0;
3200 case Mips::T0: return Mips::T1;
3201 case Mips::T1: return Mips::T2;
3202 case Mips::T2: return Mips::T3;
3203 case Mips::T3: return Mips::T4;
3204 case Mips::T4: return Mips::T5;
3205 case Mips::T5: return Mips::T6;
3206 case Mips::T6: return Mips::T7;
3207 case Mips::T7: return Mips::S0;
3208 case Mips::S0: return Mips::S1;
3209 case Mips::S1: return Mips::S2;
3210 case Mips::S2: return Mips::S3;
3211 case Mips::S3: return Mips::S4;
3212 case Mips::S4: return Mips::S5;
3213 case Mips::S5: return Mips::S6;
3214 case Mips::S6: return Mips::S7;
3215 case Mips::S7: return Mips::T8;
3216 case Mips::T8: return Mips::T9;
3217 case Mips::T9: return Mips::K0;
3218 case Mips::K0: return Mips::K1;
3219 case Mips::K1: return Mips::GP;
3220 case Mips::GP: return Mips::SP;
3221 case Mips::SP: return Mips::FP;
3222 case Mips::FP: return Mips::RA;
3223 case Mips::RA: return Mips::ZERO;
3224 case Mips::D0: return Mips::F1;
3225 case Mips::D1: return Mips::F3;
3226 case Mips::D2: return Mips::F5;
3227 case Mips::D3: return Mips::F7;
3228 case Mips::D4: return Mips::F9;
3229 case Mips::D5: return Mips::F11;
3230 case Mips::D6: return Mips::F13;
3231 case Mips::D7: return Mips::F15;
3232 case Mips::D8: return Mips::F17;
3233 case Mips::D9: return Mips::F19;
3234 case Mips::D10: return Mips::F21;
3235 case Mips::D11: return Mips::F23;
3236 case Mips::D12: return Mips::F25;
3237 case Mips::D13: return Mips::F27;
3238 case Mips::D14: return Mips::F29;
3239 case Mips::D15: return Mips::F31;
3243 // FIXME: This method is too general. In principle we should compute the number
3244 // of instructions required to synthesize the immediate inline compared to
3245 // synthesizing the address inline and relying on non .text sections.
3246 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3247 // likely to yield a much larger benefit as we have to synthesize a 64bit
3248 // address to load a 64 bit value.
3249 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3251 unsigned ATReg = getATReg(IDLoc);
3256 const MCExpr *GotSym =
3257 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3258 const MipsMCExpr *GotExpr =
3259 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3261 if(isABI_O32() || isABI_N32()) {
3262 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3264 } else { //isABI_N64()
3265 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3268 } else { //!IsPicEnabled
3269 const MCExpr *HiSym =
3270 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3271 const MipsMCExpr *HiExpr =
3272 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3274 // FIXME: This is technically correct but gives a different result to gas,
3275 // but gas is incomplete there (it has a fixme noting it doesn't work with
3276 // 64-bit addresses).
3277 // FIXME: With -msym32 option, the address expansion for N64 should probably
3278 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3279 // symbol's value is considered sign extended.
3280 if(isABI_O32() || isABI_N32()) {
3281 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3282 } else { //isABI_N64()
3283 const MCExpr *HighestSym =
3284 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3285 const MipsMCExpr *HighestExpr =
3286 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3287 const MCExpr *HigherSym =
3288 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3289 const MipsMCExpr *HigherExpr =
3290 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3292 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3294 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3295 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3296 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3297 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3299 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3305 static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) {
3306 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3307 // exponent field), convert it to double (e.g. 1 to 1.0)
3308 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3309 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3310 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3315 static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) {
3316 // Conversion of a double in an uint64_t to a float in a uint32_t,
3317 // retaining the bit pattern of a float.
3318 double DoubleImm = BitsToDouble(ImmOp64);
3319 float TmpFloat = static_cast<float>(DoubleImm);
3320 return FloatToBits(TmpFloat);
3323 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3325 const MCSubtargetInfo *STI) {
3326 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3327 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3328 "Invalid instruction operand.");
3330 unsigned FirstReg = Inst.getOperand(0).getReg();
3331 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3333 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3335 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3337 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3341 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3343 const MCSubtargetInfo *STI) {
3344 MipsTargetStreamer &TOut = getTargetStreamer();
3345 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3346 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3347 "Invalid instruction operand.");
3349 unsigned FirstReg = Inst.getOperand(0).getReg();
3350 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3352 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3354 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3356 unsigned TmpReg = getATReg(IDLoc);
3360 if (Lo_32(ImmOp64) == 0) {
3361 if (loadImmediate(ImmOp32, TmpReg, Mips::NoRegister, true, true, IDLoc, Out,
3364 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3368 MCSection *CS = getStreamer().getCurrentSectionOnly();
3369 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3370 // where appropriate.
3371 MCSection *ReadOnlySection =
3372 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3374 MCSymbol *Sym = getContext().createTempSymbol();
3375 const MCExpr *LoSym =
3376 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3377 const MipsMCExpr *LoExpr =
3378 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3380 getStreamer().SwitchSection(ReadOnlySection);
3381 getStreamer().EmitLabel(Sym, IDLoc);
3382 getStreamer().EmitIntValue(ImmOp32, 4);
3383 getStreamer().SwitchSection(CS);
3385 if (emitPartialAddress(TOut, IDLoc, Sym))
3387 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3392 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3394 const MCSubtargetInfo *STI) {
3395 MipsTargetStreamer &TOut = getTargetStreamer();
3396 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3397 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3398 "Invalid instruction operand.");
3400 unsigned FirstReg = Inst.getOperand(0).getReg();
3401 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3403 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3405 uint32_t LoImmOp64 = Lo_32(ImmOp64);
3406 uint32_t HiImmOp64 = Hi_32(ImmOp64);
3408 unsigned TmpReg = getATReg(IDLoc);
3412 if (LoImmOp64 == 0) {
3413 if (isABI_N32() || isABI_N64()) {
3414 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, true, IDLoc,
3418 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3422 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3429 MCSection *CS = getStreamer().getCurrentSectionOnly();
3430 MCSection *ReadOnlySection =
3431 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3433 MCSymbol *Sym = getContext().createTempSymbol();
3434 const MCExpr *LoSym =
3435 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3436 const MipsMCExpr *LoExpr =
3437 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3439 getStreamer().SwitchSection(ReadOnlySection);
3440 getStreamer().EmitLabel(Sym, IDLoc);
3441 getStreamer().EmitValueToAlignment(8);
3442 getStreamer().EmitIntValue(ImmOp64, 8);
3443 getStreamer().SwitchSection(CS);
3445 if (emitPartialAddress(TOut, IDLoc, Sym))
3449 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3452 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3455 if (isABI_N32() || isABI_N64())
3456 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3458 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3459 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3464 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3465 SMLoc IDLoc, MCStreamer &Out,
3466 const MCSubtargetInfo *STI) {
3467 MipsTargetStreamer &TOut = getTargetStreamer();
3468 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3469 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3470 "Invalid instruction operand.");
3472 unsigned FirstReg = Inst.getOperand(0).getReg();
3473 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3475 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3477 uint32_t LoImmOp64 = Lo_32(ImmOp64);
3478 uint32_t HiImmOp64 = Hi_32(ImmOp64);
3480 unsigned TmpReg = getATReg(IDLoc);
3484 if ((LoImmOp64 == 0) &&
3485 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3486 // FIXME: In the case where the constant is zero, we can load the
3487 // register directly from the zero register.
3489 if (isABI_N32() || isABI_N64()) {
3490 if (loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3493 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3497 if (loadImmediate(HiImmOp64, TmpReg, Mips::NoRegister, true, false, IDLoc,
3501 if (hasMips32r2()) {
3502 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3503 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3505 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3506 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3511 MCSection *CS = getStreamer().getCurrentSectionOnly();
3512 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3513 // where appropriate.
3514 MCSection *ReadOnlySection =
3515 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3517 MCSymbol *Sym = getContext().createTempSymbol();
3518 const MCExpr *LoSym =
3519 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3520 const MipsMCExpr *LoExpr =
3521 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3523 getStreamer().SwitchSection(ReadOnlySection);
3524 getStreamer().EmitLabel(Sym, IDLoc);
3525 getStreamer().EmitValueToAlignment(8);
3526 getStreamer().EmitIntValue(ImmOp64, 8);
3527 getStreamer().SwitchSection(CS);
3529 if (emitPartialAddress(TOut, IDLoc, Sym))
3532 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3533 MCOperand::createExpr(LoExpr), IDLoc, STI);
3538 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3540 const MCSubtargetInfo *STI) {
3541 MipsTargetStreamer &TOut = getTargetStreamer();
3543 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3544 "unexpected number of operands");
3546 MCOperand Offset = Inst.getOperand(0);
3547 if (Offset.isExpr()) {
3549 Inst.setOpcode(Mips::BEQ_MM);
3550 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3551 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3552 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3554 assert(Offset.isImm() && "expected immediate operand kind");
3555 if (isInt<11>(Offset.getImm())) {
3556 // If offset fits into 11 bits then this instruction becomes microMIPS
3557 // 16-bit unconditional branch instruction.
3558 if (inMicroMipsMode())
3559 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3561 if (!isInt<17>(Offset.getImm()))
3562 return Error(IDLoc, "branch target out of range");
3563 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3564 return Error(IDLoc, "branch to misaligned address");
3566 Inst.setOpcode(Mips::BEQ_MM);
3567 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3568 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3569 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3572 Out.EmitInstruction(Inst, *STI);
3574 // If .set reorder is active and branch instruction has a delay slot,
3575 // emit a NOP after it.
3576 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3577 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3578 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3583 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3584 const MCSubtargetInfo *STI) {
3585 MipsTargetStreamer &TOut = getTargetStreamer();
3586 const MCOperand &DstRegOp = Inst.getOperand(0);
3587 assert(DstRegOp.isReg() && "expected register operand kind");
3589 const MCOperand &ImmOp = Inst.getOperand(1);
3590 assert(ImmOp.isImm() && "expected immediate operand kind");
3592 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3593 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3594 "expected immediate or expression operand");
3596 bool IsLikely = false;
3598 unsigned OpCode = 0;
3599 switch(Inst.getOpcode()) {
3606 case Mips::BEQLImmMacro:
3607 OpCode = Mips::BEQL;
3610 case Mips::BNELImmMacro:
3611 OpCode = Mips::BNEL;
3615 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3619 int64_t ImmValue = ImmOp.getImm();
3620 if (ImmValue == 0) {
3622 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3623 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3624 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3626 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3629 warnIfNoMacro(IDLoc);
3631 unsigned ATReg = getATReg(IDLoc);
3635 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3640 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3641 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3642 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3644 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3649 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3650 const MCSubtargetInfo *STI, bool IsLoad) {
3651 const MCOperand &DstRegOp = Inst.getOperand(0);
3652 assert(DstRegOp.isReg() && "expected register operand kind");
3653 const MCOperand &BaseRegOp = Inst.getOperand(1);
3654 assert(BaseRegOp.isReg() && "expected register operand kind");
3655 const MCOperand &OffsetOp = Inst.getOperand(2);
3657 MipsTargetStreamer &TOut = getTargetStreamer();
3658 unsigned DstReg = DstRegOp.getReg();
3659 unsigned BaseReg = BaseRegOp.getReg();
3660 unsigned TmpReg = DstReg;
3662 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3663 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3664 unsigned DstRegClassID =
3665 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3666 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3667 (DstRegClassID == Mips::GPR64RegClassID);
3669 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3670 // At this point we need AT to perform the expansions
3671 // and we exit if it is not available.
3672 TmpReg = getATReg(IDLoc);
3677 if (OffsetOp.isImm()) {
3678 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3679 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3681 // If msb of LoOffset is 1(negative number) we must increment
3682 // HiOffset to account for the sign-extension of the low part.
3683 if (LoOffset & 0x8000)
3684 HiOffset += 0x10000;
3686 bool IsLargeOffset = HiOffset != 0;
3688 if (IsLargeOffset) {
3689 bool Is32BitImm = (HiOffset >> 32) == 0;
3690 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3695 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3696 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3697 BaseReg, IDLoc, STI);
3698 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3702 assert(OffsetOp.isExpr() && "expected expression operand kind");
3705 // a) Fix lw/sw $reg, symbol($reg) instruction expanding.
3706 // b) If expression includes offset (sym + number), do not
3707 // encode the offset into a relocation. Take it in account
3708 // in the last load/store instruction.
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
3714 expandLoadAddress(TmpReg, Mips::NoRegister, OffsetOp, !ABI.ArePtrs64bit(),
3716 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, 0, IDLoc, STI);
3718 const MCExpr *ExprOffset = OffsetOp.getExpr();
3719 MCOperand LoOperand = MCOperand::createExpr(
3720 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3721 MCOperand HiOperand = MCOperand::createExpr(
3722 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3725 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3726 LoOperand, TmpReg, IDLoc, STI);
3728 TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3729 LoOperand, TmpReg, IDLoc, STI);
3733 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3735 const MCSubtargetInfo *STI) {
3736 unsigned OpNum = Inst.getNumOperands();
3737 unsigned Opcode = Inst.getOpcode();
3738 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3740 assert(Inst.getOperand(OpNum - 1).isImm() &&
3741 Inst.getOperand(OpNum - 2).isReg() &&
3742 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3744 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3745 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3746 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3747 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3748 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3749 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3750 // It can be implemented as SWM16 or LWM16 instruction.
3751 if (inMicroMipsMode() && hasMips32r6())
3752 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3754 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3757 Inst.setOpcode(NewOpcode);
3758 Out.EmitInstruction(Inst, *STI);
3762 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3764 const MCSubtargetInfo *STI) {
3765 MipsTargetStreamer &TOut = getTargetStreamer();
3766 bool EmittedNoMacroWarning = false;
3767 unsigned PseudoOpcode = Inst.getOpcode();
3768 unsigned SrcReg = Inst.getOperand(0).getReg();
3769 const MCOperand &TrgOp = Inst.getOperand(1);
3770 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3772 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3773 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3777 TrgReg = TrgOp.getReg();
3778 else if (TrgOp.isImm()) {
3779 warnIfNoMacro(IDLoc);
3780 EmittedNoMacroWarning = true;
3782 TrgReg = getATReg(IDLoc);
3786 switch(PseudoOpcode) {
3788 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3789 case Mips::BLTImmMacro:
3790 PseudoOpcode = Mips::BLT;
3792 case Mips::BLEImmMacro:
3793 PseudoOpcode = Mips::BLE;
3795 case Mips::BGEImmMacro:
3796 PseudoOpcode = Mips::BGE;
3798 case Mips::BGTImmMacro:
3799 PseudoOpcode = Mips::BGT;
3801 case Mips::BLTUImmMacro:
3802 PseudoOpcode = Mips::BLTU;
3804 case Mips::BLEUImmMacro:
3805 PseudoOpcode = Mips::BLEU;
3807 case Mips::BGEUImmMacro:
3808 PseudoOpcode = Mips::BGEU;
3810 case Mips::BGTUImmMacro:
3811 PseudoOpcode = Mips::BGTU;
3813 case Mips::BLTLImmMacro:
3814 PseudoOpcode = Mips::BLTL;
3816 case Mips::BLELImmMacro:
3817 PseudoOpcode = Mips::BLEL;
3819 case Mips::BGELImmMacro:
3820 PseudoOpcode = Mips::BGEL;
3822 case Mips::BGTLImmMacro:
3823 PseudoOpcode = Mips::BGTL;
3825 case Mips::BLTULImmMacro:
3826 PseudoOpcode = Mips::BLTUL;
3828 case Mips::BLEULImmMacro:
3829 PseudoOpcode = Mips::BLEUL;
3831 case Mips::BGEULImmMacro:
3832 PseudoOpcode = Mips::BGEUL;
3834 case Mips::BGTULImmMacro:
3835 PseudoOpcode = Mips::BGTUL;
3839 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3840 false, IDLoc, Out, STI))
3844 switch (PseudoOpcode) {
3849 AcceptsEquality = false;
3850 ReverseOrderSLT = false;
3852 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3853 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3854 ZeroSrcOpcode = Mips::BGTZ;
3855 ZeroTrgOpcode = Mips::BLTZ;
3861 AcceptsEquality = true;
3862 ReverseOrderSLT = true;
3864 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3865 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3866 ZeroSrcOpcode = Mips::BGEZ;
3867 ZeroTrgOpcode = Mips::BLEZ;
3873 AcceptsEquality = true;
3874 ReverseOrderSLT = false;
3876 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3877 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3878 ZeroSrcOpcode = Mips::BLEZ;
3879 ZeroTrgOpcode = Mips::BGEZ;
3885 AcceptsEquality = false;
3886 ReverseOrderSLT = true;
3888 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3889 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3890 ZeroSrcOpcode = Mips::BLTZ;
3891 ZeroTrgOpcode = Mips::BGTZ;
3894 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3897 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3898 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3899 if (IsSrcRegZero && IsTrgRegZero) {
3900 // FIXME: All of these Opcode-specific if's are needed for compatibility
3901 // with GAS' behaviour. However, they may not generate the most efficient
3902 // code in some circumstances.
3903 if (PseudoOpcode == Mips::BLT) {
3904 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3908 if (PseudoOpcode == Mips::BLE) {
3909 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3911 Warning(IDLoc, "branch is always taken");
3914 if (PseudoOpcode == Mips::BGE) {
3915 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3917 Warning(IDLoc, "branch is always taken");
3920 if (PseudoOpcode == Mips::BGT) {
3921 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3925 if (PseudoOpcode == Mips::BGTU) {
3926 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3927 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3930 if (AcceptsEquality) {
3931 // If both registers are $0 and the pseudo-branch accepts equality, it
3932 // will always be taken, so we emit an unconditional branch.
3933 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3934 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3935 Warning(IDLoc, "branch is always taken");
3938 // If both registers are $0 and the pseudo-branch does not accept
3939 // equality, it will never be taken, so we don't have to emit anything.
3942 if (IsSrcRegZero || IsTrgRegZero) {
3943 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3944 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3945 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3946 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3947 // the pseudo-branch will never be taken, so we don't emit anything.
3948 // This only applies to unsigned pseudo-branches.
3951 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3952 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3953 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3954 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3955 // the pseudo-branch will always be taken, so we emit an unconditional
3957 // This only applies to unsigned pseudo-branches.
3958 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3959 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3960 Warning(IDLoc, "branch is always taken");
3964 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3965 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3966 // the pseudo-branch will be taken only when the non-zero register is
3967 // different from 0, so we emit a BNEZ.
3969 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3970 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3971 // the pseudo-branch will be taken only when the non-zero register is
3972 // equal to 0, so we emit a BEQZ.
3974 // Because only BLEU and BGEU branch on equality, we can use the
3975 // AcceptsEquality variable to decide when to emit the BEQZ.
3976 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3977 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3978 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3981 // If we have a signed pseudo-branch and one of the registers is $0,
3982 // we can use an appropriate compare-to-zero branch. We select which one
3983 // to use in the switch statement above.
3984 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3985 IsSrcRegZero ? TrgReg : SrcReg,
3986 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3990 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3991 // expansions. If it is not available, we return.
3992 unsigned ATRegNum = getATReg(IDLoc);
3996 if (!EmittedNoMacroWarning)
3997 warnIfNoMacro(IDLoc);
3999 // SLT fits well with 2 of our 4 pseudo-branches:
4000 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4001 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4002 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4003 // This is accomplished by using a BNEZ with the result of the SLT.
4005 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4006 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4007 // Because only BGE and BLE branch on equality, we can use the
4008 // AcceptsEquality variable to decide when to emit the BEQZ.
4009 // Note that the order of the SLT arguments doesn't change between
4012 // The same applies to the unsigned variants, except that SLTu is used
4014 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4015 ReverseOrderSLT ? TrgReg : SrcReg,
4016 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4018 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4019 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4020 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4025 // Expand a integer division macro.
4027 // Notably we don't have to emit a warning when encountering $rt as the $zero
4028 // register, or 0 as an immediate. processInstruction() has already done that.
4030 // The destination register can only be $zero when expanding (S)DivIMacro or
4033 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4034 const MCSubtargetInfo *STI, const bool IsMips64,
4035 const bool Signed) {
4036 MipsTargetStreamer &TOut = getTargetStreamer();
4038 warnIfNoMacro(IDLoc);
4040 const MCOperand &RdRegOp = Inst.getOperand(0);
4041 assert(RdRegOp.isReg() && "expected register operand kind");
4042 unsigned RdReg = RdRegOp.getReg();
4044 const MCOperand &RsRegOp = Inst.getOperand(1);
4045 assert(RsRegOp.isReg() && "expected register operand kind");
4046 unsigned RsReg = RsRegOp.getReg();
4051 const MCOperand &RtOp = Inst.getOperand(2);
4052 assert((RtOp.isReg() || RtOp.isImm()) &&
4053 "expected register or immediate operand kind");
4055 RtReg = RtOp.getReg();
4057 ImmValue = RtOp.getImm();
4064 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4065 ZeroReg = Mips::ZERO_64;
4068 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4069 ZeroReg = Mips::ZERO;
4073 bool UseTraps = useTraps();
4075 unsigned Opcode = Inst.getOpcode();
4076 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4077 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4078 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4079 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4081 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4082 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4083 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4084 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4087 unsigned ATReg = getATReg(IDLoc);
4091 if (ImmValue == 0) {
4093 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4095 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4099 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4100 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4102 } else if (isDiv && ImmValue == 1) {
4103 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4105 } else if (isDiv && Signed && ImmValue == -1) {
4106 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4109 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4110 false, Inst.getLoc(), Out, STI))
4112 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4113 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4119 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4120 // break, insert the trap/break and exit. This gives a different result to
4121 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4122 // are handled equivalently. As the observed behaviour is the same, we're ok.
4123 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4125 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4128 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4132 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4133 // not expand to macro sequence.
4134 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4135 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4139 // Temporary label for first branch traget
4140 MCContext &Context = TOut.getStreamer().getContext();
4145 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4147 // Branch to the li instruction.
4148 BrTarget = Context.createTempSymbol();
4149 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4150 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4153 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4156 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4160 TOut.getStreamer().EmitLabel(BrTarget);
4162 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4166 unsigned ATReg = getATReg(IDLoc);
4171 TOut.getStreamer().EmitLabel(BrTarget);
4173 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4175 // Temporary label for the second branch target.
4176 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4177 MCOperand LabelOpEnd =
4178 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4180 // Branch to the mflo instruction.
4181 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4184 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4185 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4187 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4191 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4193 // Branch to the mflo instruction.
4194 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4195 TOut.emitNop(IDLoc, STI);
4196 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4199 TOut.getStreamer().EmitLabel(BrTargetEnd);
4200 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4204 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4205 SMLoc IDLoc, MCStreamer &Out,
4206 const MCSubtargetInfo *STI) {
4207 MipsTargetStreamer &TOut = getTargetStreamer();
4209 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4210 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4211 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4213 unsigned FirstReg = Inst.getOperand(0).getReg();
4214 unsigned SecondReg = Inst.getOperand(1).getReg();
4215 unsigned ThirdReg = Inst.getOperand(2).getReg();
4217 if (hasMips1() && !hasMips2()) {
4218 unsigned ATReg = getATReg(IDLoc);
4221 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4222 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4223 TOut.emitNop(IDLoc, STI);
4224 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4225 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4226 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4227 TOut.emitNop(IDLoc, STI);
4228 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4230 FirstReg, SecondReg, IDLoc, STI);
4231 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4232 TOut.emitNop(IDLoc, STI);
4236 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4238 FirstReg, SecondReg, IDLoc, STI);
4243 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4244 MCStreamer &Out, const MCSubtargetInfo *STI) {
4245 if (hasMips32r6() || hasMips64r6()) {
4246 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4249 const MCOperand &DstRegOp = Inst.getOperand(0);
4250 assert(DstRegOp.isReg() && "expected register operand kind");
4251 const MCOperand &SrcRegOp = Inst.getOperand(1);
4252 assert(SrcRegOp.isReg() && "expected register operand kind");
4253 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4254 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4256 MipsTargetStreamer &TOut = getTargetStreamer();
4257 unsigned DstReg = DstRegOp.getReg();
4258 unsigned SrcReg = SrcRegOp.getReg();
4259 int64_t OffsetValue = OffsetImmOp.getImm();
4261 // NOTE: We always need AT for ULHU, as it is always used as the source
4262 // register for one of the LBu's.
4263 warnIfNoMacro(IDLoc);
4264 unsigned ATReg = getATReg(IDLoc);
4268 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4269 if (IsLargeOffset) {
4270 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4275 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4276 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4278 std::swap(FirstOffset, SecondOffset);
4280 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4281 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4283 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4284 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4286 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4287 FirstOffset, IDLoc, STI);
4288 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4289 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4290 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4295 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4296 const MCSubtargetInfo *STI) {
4297 if (hasMips32r6() || hasMips64r6()) {
4298 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4301 const MCOperand &DstRegOp = Inst.getOperand(0);
4302 assert(DstRegOp.isReg() && "expected register operand kind");
4303 const MCOperand &SrcRegOp = Inst.getOperand(1);
4304 assert(SrcRegOp.isReg() && "expected register operand kind");
4305 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4306 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4308 MipsTargetStreamer &TOut = getTargetStreamer();
4309 unsigned DstReg = DstRegOp.getReg();
4310 unsigned SrcReg = SrcRegOp.getReg();
4311 int64_t OffsetValue = OffsetImmOp.getImm();
4313 warnIfNoMacro(IDLoc);
4314 unsigned ATReg = getATReg(IDLoc);
4318 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4319 if (IsLargeOffset) {
4320 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4325 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4326 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4328 std::swap(FirstOffset, SecondOffset);
4330 if (IsLargeOffset) {
4331 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4332 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4333 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4334 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4335 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4336 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4338 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4339 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4340 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4346 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4347 const MCSubtargetInfo *STI) {
4348 if (hasMips32r6() || hasMips64r6()) {
4349 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4352 const MCOperand &DstRegOp = Inst.getOperand(0);
4353 assert(DstRegOp.isReg() && "expected register operand kind");
4354 const MCOperand &SrcRegOp = Inst.getOperand(1);
4355 assert(SrcRegOp.isReg() && "expected register operand kind");
4356 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4357 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4359 MipsTargetStreamer &TOut = getTargetStreamer();
4360 unsigned DstReg = DstRegOp.getReg();
4361 unsigned SrcReg = SrcRegOp.getReg();
4362 int64_t OffsetValue = OffsetImmOp.getImm();
4364 // Compute left/right load/store offsets.
4365 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4366 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4367 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4369 std::swap(LxlOffset, LxrOffset);
4371 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4372 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4373 unsigned TmpReg = SrcReg;
4374 if (IsLargeOffset || DoMove) {
4375 warnIfNoMacro(IDLoc);
4376 TmpReg = getATReg(IDLoc);
4381 if (IsLargeOffset) {
4382 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4388 std::swap(DstReg, TmpReg);
4390 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4391 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4392 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4393 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4396 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4401 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4402 const MCSubtargetInfo *STI) {
4403 MipsTargetStreamer &TOut = getTargetStreamer();
4405 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4406 assert(Inst.getOperand(0).isReg() &&
4407 Inst.getOperand(1).isReg() &&
4408 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4410 unsigned DstReg = Inst.getOperand(0).getReg();
4411 unsigned SrcReg = Inst.getOperand(1).getReg();
4412 unsigned OpReg = Inst.getOperand(2).getReg();
4415 warnIfNoMacro(IDLoc);
4417 switch (Inst.getOpcode()) {
4422 OpCode = Mips::SLTu;
4425 llvm_unreachable("unexpected 'sge' opcode");
4428 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4429 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4430 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4435 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4436 const MCSubtargetInfo *STI) {
4437 MipsTargetStreamer &TOut = getTargetStreamer();
4439 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4440 assert(Inst.getOperand(0).isReg() &&
4441 Inst.getOperand(1).isReg() &&
4442 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4444 unsigned DstReg = Inst.getOperand(0).getReg();
4445 unsigned SrcReg = Inst.getOperand(1).getReg();
4446 int64_t ImmValue = Inst.getOperand(2).getImm();
4447 unsigned OpRegCode, OpImmCode;
4449 warnIfNoMacro(IDLoc);
4451 switch (Inst.getOpcode()) {
4453 case Mips::SGEImm64:
4454 OpRegCode = Mips::SLT;
4455 OpImmCode = Mips::SLTi;
4458 case Mips::SGEUImm64:
4459 OpRegCode = Mips::SLTu;
4460 OpImmCode = Mips::SLTiu;
4463 llvm_unreachable("unexpected 'sge' opcode with immediate");
4466 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4467 if (isInt<16>(ImmValue)) {
4468 // Use immediate version of STL.
4469 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4470 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4472 unsigned ImmReg = DstReg;
4473 if (DstReg == SrcReg) {
4474 unsigned ATReg = getATReg(Inst.getLoc());
4480 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4481 false, IDLoc, Out, STI))
4484 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4485 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4491 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4492 const MCSubtargetInfo *STI) {
4493 MipsTargetStreamer &TOut = getTargetStreamer();
4495 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4496 assert(Inst.getOperand(0).isReg() &&
4497 Inst.getOperand(1).isReg() &&
4498 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4500 unsigned DstReg = Inst.getOperand(0).getReg();
4501 unsigned SrcReg = Inst.getOperand(1).getReg();
4502 unsigned ImmReg = DstReg;
4503 int64_t ImmValue = Inst.getOperand(2).getImm();
4506 warnIfNoMacro(IDLoc);
4508 switch (Inst.getOpcode()) {
4510 case Mips::SGTImm64:
4514 case Mips::SGTUImm64:
4515 OpCode = Mips::SLTu;
4518 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4521 if (DstReg == SrcReg) {
4522 unsigned ATReg = getATReg(Inst.getLoc());
4528 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4529 false, IDLoc, Out, STI))
4532 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4533 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4538 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4540 const MCSubtargetInfo *STI) {
4541 MipsTargetStreamer &TOut = getTargetStreamer();
4543 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4544 assert(Inst.getOperand(0).isReg() &&
4545 Inst.getOperand(1).isReg() &&
4546 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4548 unsigned ATReg = Mips::NoRegister;
4549 unsigned FinalDstReg = Mips::NoRegister;
4550 unsigned DstReg = Inst.getOperand(0).getReg();
4551 unsigned SrcReg = Inst.getOperand(1).getReg();
4552 int64_t ImmValue = Inst.getOperand(2).getImm();
4554 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4556 unsigned FinalOpcode = Inst.getOpcode();
4558 if (DstReg == SrcReg) {
4559 ATReg = getATReg(Inst.getLoc());
4562 FinalDstReg = DstReg;
4566 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4567 Inst.getLoc(), Out, STI)) {
4568 switch (FinalOpcode) {
4570 llvm_unreachable("unimplemented expansion");
4572 FinalOpcode = Mips::ADD;
4575 FinalOpcode = Mips::ADDu;
4578 FinalOpcode = Mips::AND;
4581 FinalOpcode = Mips::NOR;
4584 FinalOpcode = Mips::OR;
4587 FinalOpcode = Mips::SLT;
4590 FinalOpcode = Mips::SLTu;
4593 FinalOpcode = Mips::XOR;
4596 FinalOpcode = Mips::ADD_MM;
4598 case Mips::ADDiu_MM:
4599 FinalOpcode = Mips::ADDu_MM;
4602 FinalOpcode = Mips::AND_MM;
4605 FinalOpcode = Mips::OR_MM;
4608 FinalOpcode = Mips::SLT_MM;
4610 case Mips::SLTiu_MM:
4611 FinalOpcode = Mips::SLTu_MM;
4614 FinalOpcode = Mips::XOR_MM;
4617 FinalOpcode = Mips::AND64;
4619 case Mips::NORImm64:
4620 FinalOpcode = Mips::NOR64;
4623 FinalOpcode = Mips::OR64;
4625 case Mips::SLTImm64:
4626 FinalOpcode = Mips::SLT64;
4628 case Mips::SLTUImm64:
4629 FinalOpcode = Mips::SLTu64;
4632 FinalOpcode = Mips::XOR64;
4636 if (FinalDstReg == Mips::NoRegister)
4637 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4639 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4645 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4646 const MCSubtargetInfo *STI) {
4647 MipsTargetStreamer &TOut = getTargetStreamer();
4648 unsigned ATReg = Mips::NoRegister;
4649 unsigned DReg = Inst.getOperand(0).getReg();
4650 unsigned SReg = Inst.getOperand(1).getReg();
4651 unsigned TReg = Inst.getOperand(2).getReg();
4652 unsigned TmpReg = DReg;
4654 unsigned FirstShift = Mips::NOP;
4655 unsigned SecondShift = Mips::NOP;
4657 if (hasMips32r2()) {
4659 TmpReg = getATReg(Inst.getLoc());
4664 if (Inst.getOpcode() == Mips::ROL) {
4665 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4666 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4670 if (Inst.getOpcode() == Mips::ROR) {
4671 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4679 switch (Inst.getOpcode()) {
4681 llvm_unreachable("unexpected instruction opcode");
4683 FirstShift = Mips::SRLV;
4684 SecondShift = Mips::SLLV;
4687 FirstShift = Mips::SLLV;
4688 SecondShift = Mips::SRLV;
4692 ATReg = getATReg(Inst.getLoc());
4696 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4697 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4698 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4699 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4707 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4709 const MCSubtargetInfo *STI) {
4710 MipsTargetStreamer &TOut = getTargetStreamer();
4711 unsigned ATReg = Mips::NoRegister;
4712 unsigned DReg = Inst.getOperand(0).getReg();
4713 unsigned SReg = Inst.getOperand(1).getReg();
4714 int64_t ImmValue = Inst.getOperand(2).getImm();
4716 unsigned FirstShift = Mips::NOP;
4717 unsigned SecondShift = Mips::NOP;
4719 if (hasMips32r2()) {
4720 if (Inst.getOpcode() == Mips::ROLImm) {
4721 uint64_t MaxShift = 32;
4722 uint64_t ShiftValue = ImmValue;
4724 ShiftValue = MaxShift - ImmValue;
4725 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4729 if (Inst.getOpcode() == Mips::RORImm) {
4730 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4738 if (ImmValue == 0) {
4739 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4743 switch (Inst.getOpcode()) {
4745 llvm_unreachable("unexpected instruction opcode");
4747 FirstShift = Mips::SLL;
4748 SecondShift = Mips::SRL;
4751 FirstShift = Mips::SRL;
4752 SecondShift = Mips::SLL;
4756 ATReg = getATReg(Inst.getLoc());
4760 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4761 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4762 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4770 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4771 const MCSubtargetInfo *STI) {
4772 MipsTargetStreamer &TOut = getTargetStreamer();
4773 unsigned ATReg = Mips::NoRegister;
4774 unsigned DReg = Inst.getOperand(0).getReg();
4775 unsigned SReg = Inst.getOperand(1).getReg();
4776 unsigned TReg = Inst.getOperand(2).getReg();
4777 unsigned TmpReg = DReg;
4779 unsigned FirstShift = Mips::NOP;
4780 unsigned SecondShift = Mips::NOP;
4782 if (hasMips64r2()) {
4783 if (TmpReg == SReg) {
4784 TmpReg = getATReg(Inst.getLoc());
4789 if (Inst.getOpcode() == Mips::DROL) {
4790 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4791 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4795 if (Inst.getOpcode() == Mips::DROR) {
4796 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4804 switch (Inst.getOpcode()) {
4806 llvm_unreachable("unexpected instruction opcode");
4808 FirstShift = Mips::DSRLV;
4809 SecondShift = Mips::DSLLV;
4812 FirstShift = Mips::DSLLV;
4813 SecondShift = Mips::DSRLV;
4817 ATReg = getATReg(Inst.getLoc());
4821 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4822 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4823 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4824 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4832 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4834 const MCSubtargetInfo *STI) {
4835 MipsTargetStreamer &TOut = getTargetStreamer();
4836 unsigned ATReg = Mips::NoRegister;
4837 unsigned DReg = Inst.getOperand(0).getReg();
4838 unsigned SReg = Inst.getOperand(1).getReg();
4839 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4841 unsigned FirstShift = Mips::NOP;
4842 unsigned SecondShift = Mips::NOP;
4846 if (hasMips64r2()) {
4847 unsigned FinalOpcode = Mips::NOP;
4849 FinalOpcode = Mips::DROTR;
4850 else if (ImmValue % 32 == 0)
4851 FinalOpcode = Mips::DROTR32;
4852 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4853 if (Inst.getOpcode() == Mips::DROLImm)
4854 FinalOpcode = Mips::DROTR32;
4856 FinalOpcode = Mips::DROTR;
4857 } else if (ImmValue >= 33) {
4858 if (Inst.getOpcode() == Mips::DROLImm)
4859 FinalOpcode = Mips::DROTR;
4861 FinalOpcode = Mips::DROTR32;
4864 uint64_t ShiftValue = ImmValue % 32;
4865 if (Inst.getOpcode() == Mips::DROLImm)
4866 ShiftValue = (32 - ImmValue % 32) % 32;
4868 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4874 if (ImmValue == 0) {
4875 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4879 switch (Inst.getOpcode()) {
4881 llvm_unreachable("unexpected instruction opcode");
4883 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4884 FirstShift = Mips::DSLL;
4885 SecondShift = Mips::DSRL32;
4887 if (ImmValue == 32) {
4888 FirstShift = Mips::DSLL32;
4889 SecondShift = Mips::DSRL32;
4891 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4892 FirstShift = Mips::DSLL32;
4893 SecondShift = Mips::DSRL;
4897 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4898 FirstShift = Mips::DSRL;
4899 SecondShift = Mips::DSLL32;
4901 if (ImmValue == 32) {
4902 FirstShift = Mips::DSRL32;
4903 SecondShift = Mips::DSLL32;
4905 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4906 FirstShift = Mips::DSRL32;
4907 SecondShift = Mips::DSLL;
4912 ATReg = getATReg(Inst.getLoc());
4916 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4917 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4918 Inst.getLoc(), STI);
4919 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4927 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4928 const MCSubtargetInfo *STI) {
4929 MipsTargetStreamer &TOut = getTargetStreamer();
4930 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4931 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4933 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4934 if (FirstRegOp != SecondRegOp)
4935 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4937 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4938 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4943 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4944 const MCSubtargetInfo *STI) {
4945 MipsTargetStreamer &TOut = getTargetStreamer();
4946 unsigned ATReg = Mips::NoRegister;
4947 unsigned DstReg = Inst.getOperand(0).getReg();
4948 unsigned SrcReg = Inst.getOperand(1).getReg();
4949 int32_t ImmValue = Inst.getOperand(2).getImm();
4951 ATReg = getATReg(IDLoc);
4955 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4958 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4959 SrcReg, ATReg, IDLoc, STI);
4961 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4966 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4967 const MCSubtargetInfo *STI) {
4968 MipsTargetStreamer &TOut = getTargetStreamer();
4969 unsigned ATReg = Mips::NoRegister;
4970 unsigned DstReg = Inst.getOperand(0).getReg();
4971 unsigned SrcReg = Inst.getOperand(1).getReg();
4972 unsigned TmpReg = Inst.getOperand(2).getReg();
4974 ATReg = getATReg(Inst.getLoc());
4978 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4979 SrcReg, TmpReg, IDLoc, STI);
4981 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4983 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4984 DstReg, DstReg, 0x1F, IDLoc, STI);
4986 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4989 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4991 MCContext & Context = TOut.getStreamer().getContext();
4992 MCSymbol * BrTarget = Context.createTempSymbol();
4994 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4996 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4997 if (AssemblerOptions.back()->isReorder())
4998 TOut.emitNop(IDLoc, STI);
4999 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5001 TOut.getStreamer().EmitLabel(BrTarget);
5003 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5008 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5009 const MCSubtargetInfo *STI) {
5010 MipsTargetStreamer &TOut = getTargetStreamer();
5011 unsigned ATReg = Mips::NoRegister;
5012 unsigned DstReg = Inst.getOperand(0).getReg();
5013 unsigned SrcReg = Inst.getOperand(1).getReg();
5014 unsigned TmpReg = Inst.getOperand(2).getReg();
5016 ATReg = getATReg(IDLoc);
5020 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5021 SrcReg, TmpReg, IDLoc, STI);
5023 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5024 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5026 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5028 MCContext & Context = TOut.getStreamer().getContext();
5029 MCSymbol * BrTarget = Context.createTempSymbol();
5031 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5033 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5034 if (AssemblerOptions.back()->isReorder())
5035 TOut.emitNop(IDLoc, STI);
5036 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5038 TOut.getStreamer().EmitLabel(BrTarget);
5044 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5045 const MCSubtargetInfo *STI) {
5046 MipsTargetStreamer &TOut = getTargetStreamer();
5047 unsigned DstReg = Inst.getOperand(0).getReg();
5048 unsigned SrcReg = Inst.getOperand(1).getReg();
5049 unsigned TmpReg = Inst.getOperand(2).getReg();
5051 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5052 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5057 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5058 // lw $<reg+1>>, offset+4($reg2)'
5059 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5060 // sw $<reg+1>>, offset+4($reg2)'
5062 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5064 const MCSubtargetInfo *STI,
5069 warnIfNoMacro(IDLoc);
5071 MipsTargetStreamer &TOut = getTargetStreamer();
5072 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5073 unsigned FirstReg = Inst.getOperand(0).getReg();
5074 unsigned SecondReg = nextReg(FirstReg);
5075 unsigned BaseReg = Inst.getOperand(1).getReg();
5079 warnIfRegIndexIsAT(FirstReg, IDLoc);
5081 assert(Inst.getOperand(2).isImm() &&
5082 "Offset for load macro is not immediate!");
5084 MCOperand &FirstOffset = Inst.getOperand(2);
5085 signed NextOffset = FirstOffset.getImm() + 4;
5086 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5088 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5091 // For loads, clobber the base register with the second load instead of the
5092 // first if the BaseReg == FirstReg.
5093 if (FirstReg != BaseReg || !IsLoad) {
5094 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5095 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5097 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5098 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5105 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5106 // swc1 $<reg>, offset+4($reg2)'
5107 // or if little endian to 'swc1 $<reg>, offset($reg2);
5108 // swc1 $<reg+1>, offset+4($reg2)'
5110 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5112 const MCSubtargetInfo *STI) {
5116 warnIfNoMacro(IDLoc);
5118 MipsTargetStreamer &TOut = getTargetStreamer();
5119 unsigned Opcode = Mips::SWC1;
5120 unsigned FirstReg = Inst.getOperand(0).getReg();
5121 unsigned SecondReg = nextReg(FirstReg);
5122 unsigned BaseReg = Inst.getOperand(1).getReg();
5126 warnIfRegIndexIsAT(FirstReg, IDLoc);
5128 assert(Inst.getOperand(2).isImm() &&
5129 "Offset for macro is not immediate!");
5131 MCOperand &FirstOffset = Inst.getOperand(2);
5132 signed NextOffset = FirstOffset.getImm() + 4;
5133 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5135 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5138 if (!IsLittleEndian)
5139 std::swap(FirstReg, SecondReg);
5141 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5142 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5147 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5148 const MCSubtargetInfo *STI) {
5149 MipsTargetStreamer &TOut = getTargetStreamer();
5151 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5152 assert(Inst.getOperand(0).isReg() &&
5153 Inst.getOperand(1).isReg() &&
5154 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5156 unsigned DstReg = Inst.getOperand(0).getReg();
5157 unsigned SrcReg = Inst.getOperand(1).getReg();
5158 unsigned OpReg = Inst.getOperand(2).getReg();
5160 warnIfNoMacro(IDLoc);
5162 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5163 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5164 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5168 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5169 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5173 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5174 const MCSubtargetInfo *STI) {
5175 MipsTargetStreamer &TOut = getTargetStreamer();
5177 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5178 assert(Inst.getOperand(0).isReg() &&
5179 Inst.getOperand(1).isReg() &&
5180 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5182 unsigned DstReg = Inst.getOperand(0).getReg();
5183 unsigned SrcReg = Inst.getOperand(1).getReg();
5184 int64_t Imm = Inst.getOperand(2).getImm();
5186 warnIfNoMacro(IDLoc);
5189 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5193 if (SrcReg == Mips::ZERO) {
5194 Warning(IDLoc, "comparison is always false");
5195 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5196 DstReg, SrcReg, SrcReg, IDLoc, STI);
5201 if (Imm > -0x8000 && Imm < 0) {
5203 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5208 if (!isUInt<16>(Imm)) {
5209 unsigned ATReg = getATReg(IDLoc);
5213 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5217 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5218 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5222 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5223 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5227 // Map the DSP accumulator and control register to the corresponding gpr
5228 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5229 // do not map the DSP registers contigously to gpr registers.
5230 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5231 switch (Inst.getOpcode()) {
5234 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5244 llvm_unreachable("Unknown register for 'mttr' alias!");
5248 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5258 llvm_unreachable("Unknown register for 'mttr' alias!");
5262 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5272 llvm_unreachable("Unknown register for 'mttr' alias!");
5278 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5282 // Map the floating point register operand to the corresponding register
5284 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5285 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5286 case Mips::F0: return Mips::ZERO;
5287 case Mips::F1: return Mips::AT;
5288 case Mips::F2: return Mips::V0;
5289 case Mips::F3: return Mips::V1;
5290 case Mips::F4: return Mips::A0;
5291 case Mips::F5: return Mips::A1;
5292 case Mips::F6: return Mips::A2;
5293 case Mips::F7: return Mips::A3;
5294 case Mips::F8: return Mips::T0;
5295 case Mips::F9: return Mips::T1;
5296 case Mips::F10: return Mips::T2;
5297 case Mips::F11: return Mips::T3;
5298 case Mips::F12: return Mips::T4;
5299 case Mips::F13: return Mips::T5;
5300 case Mips::F14: return Mips::T6;
5301 case Mips::F15: return Mips::T7;
5302 case Mips::F16: return Mips::S0;
5303 case Mips::F17: return Mips::S1;
5304 case Mips::F18: return Mips::S2;
5305 case Mips::F19: return Mips::S3;
5306 case Mips::F20: return Mips::S4;
5307 case Mips::F21: return Mips::S5;
5308 case Mips::F22: return Mips::S6;
5309 case Mips::F23: return Mips::S7;
5310 case Mips::F24: return Mips::T8;
5311 case Mips::F25: return Mips::T9;
5312 case Mips::F26: return Mips::K0;
5313 case Mips::F27: return Mips::K1;
5314 case Mips::F28: return Mips::GP;
5315 case Mips::F29: return Mips::SP;
5316 case Mips::F30: return Mips::FP;
5317 case Mips::F31: return Mips::RA;
5318 default: llvm_unreachable("Unknown register for mttc1 alias!");
5322 // Map the coprocessor operand the corresponding gpr register operand.
5323 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5324 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5325 case Mips::COP00: return Mips::ZERO;
5326 case Mips::COP01: return Mips::AT;
5327 case Mips::COP02: return Mips::V0;
5328 case Mips::COP03: return Mips::V1;
5329 case Mips::COP04: return Mips::A0;
5330 case Mips::COP05: return Mips::A1;
5331 case Mips::COP06: return Mips::A2;
5332 case Mips::COP07: return Mips::A3;
5333 case Mips::COP08: return Mips::T0;
5334 case Mips::COP09: return Mips::T1;
5335 case Mips::COP010: return Mips::T2;
5336 case Mips::COP011: return Mips::T3;
5337 case Mips::COP012: return Mips::T4;
5338 case Mips::COP013: return Mips::T5;
5339 case Mips::COP014: return Mips::T6;
5340 case Mips::COP015: return Mips::T7;
5341 case Mips::COP016: return Mips::S0;
5342 case Mips::COP017: return Mips::S1;
5343 case Mips::COP018: return Mips::S2;
5344 case Mips::COP019: return Mips::S3;
5345 case Mips::COP020: return Mips::S4;
5346 case Mips::COP021: return Mips::S5;
5347 case Mips::COP022: return Mips::S6;
5348 case Mips::COP023: return Mips::S7;
5349 case Mips::COP024: return Mips::T8;
5350 case Mips::COP025: return Mips::T9;
5351 case Mips::COP026: return Mips::K0;
5352 case Mips::COP027: return Mips::K1;
5353 case Mips::COP028: return Mips::GP;
5354 case Mips::COP029: return Mips::SP;
5355 case Mips::COP030: return Mips::FP;
5356 case Mips::COP031: return Mips::RA;
5357 default: llvm_unreachable("Unknown register for mttc0 alias!");
5361 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5362 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5363 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5364 const MCSubtargetInfo *STI) {
5365 MipsTargetStreamer &TOut = getTargetStreamer();
5370 bool IsMFTR = false;
5371 switch (Inst.getOpcode()) {
5377 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5378 sel = Inst.getOperand(2).getImm();
5384 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5396 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5404 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5411 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5418 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5422 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5425 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5426 : Inst.getOperand(0).getReg());
5428 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5433 bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5434 const MCSubtargetInfo *STI) {
5435 assert(Inst.getNumOperands() == 3 && "expected three operands");
5436 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5437 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5439 warnIfNoMacro(IDLoc);
5441 MipsTargetStreamer &TOut = getTargetStreamer();
5442 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5443 unsigned RtReg = Inst.getOperand(0).getReg();
5444 unsigned BaseReg = Inst.getOperand(1).getReg();
5445 const MCOperand &BaseOp = Inst.getOperand(2);
5447 if (BaseOp.isImm()) {
5448 int64_t ImmValue = BaseOp.getImm();
5449 if (ImmValue == 0) {
5450 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5455 unsigned ATReg = getATReg(IDLoc);
5459 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5462 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5467 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5468 const OperandVector &Operands) {
5469 switch (Inst.getOpcode()) {
5471 return Match_Success;
5474 if (static_cast<MipsOperand &>(*Operands[1])
5475 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5476 return Match_Success;
5477 return Match_RequiresSameSrcAndDst;
5481 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5482 switch (Inst.getOpcode()) {
5483 // As described by the MIPSR6 spec, daui must not use the zero operand for
5484 // its source operand.
5486 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5487 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5488 return Match_RequiresNoZeroRegister;
5489 return Match_Success;
5490 // As described by the Mips32r2 spec, the registers Rd and Rs for
5491 // jalr.hb must be different.
5492 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5493 // and registers Rd and Base for microMIPS lwp instruction
5495 case Mips::JALR_HB64:
5496 case Mips::JALRC_HB_MMR6:
5497 case Mips::JALRC_MMR6:
5498 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5499 return Match_RequiresDifferentSrcAndDst;
5500 return Match_Success;
5502 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5503 return Match_RequiresDifferentSrcAndDst;
5504 return Match_Success;
5506 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5507 return Match_NonZeroOperandForSync;
5508 return Match_Success;
5513 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5514 return Match_NonZeroOperandForMTCX;
5515 return Match_Success;
5516 // As described the MIPSR6 spec, the compact branches that compare registers
5518 // a) Not use the zero register.
5519 // b) Not use the same register twice.
5520 // c) rs < rt for bnec, beqc.
5521 // NB: For this case, the encoding will swap the operands as their
5522 // ordering doesn't matter. GAS performs this transformation too.
5523 // Hence, that constraint does not have to be enforced.
5525 // The compact branches that branch iff the signed addition of two registers
5526 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5527 // operand swapping. They do not have restriction of using the zero register.
5528 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5529 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5530 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5531 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5532 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5533 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5540 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5541 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5542 return Match_RequiresNoZeroRegister;
5543 return Match_Success;
5544 case Mips::BGEC: case Mips::BGEC_MMR6:
5545 case Mips::BLTC: case Mips::BLTC_MMR6:
5546 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5547 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5548 case Mips::BEQC: case Mips::BEQC_MMR6:
5549 case Mips::BNEC: case Mips::BNEC_MMR6:
5556 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5557 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5558 return Match_RequiresNoZeroRegister;
5559 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5560 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5561 return Match_RequiresNoZeroRegister;
5562 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5563 return Match_RequiresDifferentOperands;
5564 return Match_Success;
5566 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5567 "Operands must be immediates for dins!");
5568 const signed Pos = Inst.getOperand(2).getImm();
5569 const signed Size = Inst.getOperand(3).getImm();
5570 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5571 return Match_RequiresPosSizeRange0_32;
5572 return Match_Success;
5576 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5577 "Operands must be immediates for dinsm/dinsu!");
5578 const signed Pos = Inst.getOperand(2).getImm();
5579 const signed Size = Inst.getOperand(3).getImm();
5580 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5581 return Match_RequiresPosSizeRange33_64;
5582 return Match_Success;
5585 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5586 "Operands must be immediates for DEXTM!");
5587 const signed Pos = Inst.getOperand(2).getImm();
5588 const signed Size = Inst.getOperand(3).getImm();
5589 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5590 return Match_RequiresPosSizeUImm6;
5591 return Match_Success;
5595 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5596 "Operands must be immediates for dextm/dextu!");
5597 const signed Pos = Inst.getOperand(2).getImm();
5598 const signed Size = Inst.getOperand(3).getImm();
5599 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5600 return Match_RequiresPosSizeRange33_64;
5601 return Match_Success;
5603 case Mips::CRC32B: case Mips::CRC32CB:
5604 case Mips::CRC32H: case Mips::CRC32CH:
5605 case Mips::CRC32W: case Mips::CRC32CW:
5606 case Mips::CRC32D: case Mips::CRC32CD:
5607 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5608 return Match_RequiresSameSrcAndDst;
5609 return Match_Success;
5612 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5613 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5614 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5615 return Match_NoFCCRegisterForCurrentISA;
5617 return Match_Success;
5621 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5622 uint64_t ErrorInfo) {
5623 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5624 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5625 if (ErrorLoc == SMLoc())
5632 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5633 OperandVector &Operands,
5635 uint64_t &ErrorInfo,
5636 bool MatchingInlineAsm) {
5638 unsigned MatchResult =
5639 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5641 switch (MatchResult) {
5643 if (processInstruction(Inst, IDLoc, Out, STI))
5646 case Match_MissingFeature:
5647 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5649 case Match_InvalidOperand: {
5650 SMLoc ErrorLoc = IDLoc;
5651 if (ErrorInfo != ~0ULL) {
5652 if (ErrorInfo >= Operands.size())
5653 return Error(IDLoc, "too few operands for instruction");
5655 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5656 if (ErrorLoc == SMLoc())
5660 return Error(ErrorLoc, "invalid operand for instruction");
5662 case Match_NonZeroOperandForSync:
5664 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5665 case Match_NonZeroOperandForMTCX:
5666 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5667 case Match_MnemonicFail:
5668 return Error(IDLoc, "invalid instruction");
5669 case Match_RequiresDifferentSrcAndDst:
5670 return Error(IDLoc, "source and destination must be different");
5671 case Match_RequiresDifferentOperands:
5672 return Error(IDLoc, "registers must be different");
5673 case Match_RequiresNoZeroRegister:
5674 return Error(IDLoc, "invalid operand ($zero) for instruction");
5675 case Match_RequiresSameSrcAndDst:
5676 return Error(IDLoc, "source and destination must match");
5677 case Match_NoFCCRegisterForCurrentISA:
5678 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5679 "non-zero fcc register doesn't exist in current ISA level");
5681 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5683 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5684 "expected 1-bit unsigned immediate");
5686 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5687 "expected 2-bit unsigned immediate");
5689 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5690 "expected immediate in range 1 .. 4");
5692 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5693 "expected 3-bit unsigned immediate");
5695 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5696 "expected 4-bit unsigned immediate");
5698 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5699 "expected 4-bit signed immediate");
5701 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5702 "expected 5-bit unsigned immediate");
5704 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5705 "expected 5-bit signed immediate");
5707 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5708 "expected immediate in range 1 .. 32");
5709 case Match_UImm5_32:
5710 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5711 "expected immediate in range 32 .. 63");
5712 case Match_UImm5_33:
5713 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5714 "expected immediate in range 33 .. 64");
5715 case Match_UImm5_0_Report_UImm6:
5716 // This is used on UImm5 operands that have a corresponding UImm5_32
5717 // operand to avoid confusing the user.
5718 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5719 "expected 6-bit unsigned immediate");
5720 case Match_UImm5_Lsl2:
5721 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5722 "expected both 7-bit unsigned immediate and multiple of 4");
5723 case Match_UImmRange2_64:
5724 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5725 "expected immediate in range 2 .. 64");
5727 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5728 "expected 6-bit unsigned immediate");
5729 case Match_UImm6_Lsl2:
5730 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5731 "expected both 8-bit unsigned immediate and multiple of 4");
5733 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5734 "expected 6-bit signed immediate");
5736 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5737 "expected 7-bit unsigned immediate");
5738 case Match_UImm7_N1:
5739 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5740 "expected immediate in range -1 .. 126");
5741 case Match_SImm7_Lsl2:
5742 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5743 "expected both 9-bit signed immediate and multiple of 4");
5745 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5746 "expected 8-bit unsigned immediate");
5747 case Match_UImm10_0:
5748 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5749 "expected 10-bit unsigned immediate");
5750 case Match_SImm10_0:
5751 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5752 "expected 10-bit signed immediate");
5753 case Match_SImm11_0:
5754 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5755 "expected 11-bit signed immediate");
5757 case Match_UImm16_Relaxed:
5758 case Match_UImm16_AltRelaxed:
5759 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5760 "expected 16-bit unsigned immediate");
5762 case Match_SImm16_Relaxed:
5763 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5764 "expected 16-bit signed immediate");
5765 case Match_SImm19_Lsl2:
5766 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5767 "expected both 19-bit signed immediate and multiple of 4");
5768 case Match_UImm20_0:
5769 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5770 "expected 20-bit unsigned immediate");
5771 case Match_UImm26_0:
5772 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5773 "expected 26-bit unsigned immediate");
5775 case Match_SImm32_Relaxed:
5776 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5777 "expected 32-bit signed immediate");
5778 case Match_UImm32_Coerced:
5779 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5780 "expected 32-bit immediate");
5781 case Match_MemSImm9:
5782 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5783 "expected memory with 9-bit signed offset");
5784 case Match_MemSImm10:
5785 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5786 "expected memory with 10-bit signed offset");
5787 case Match_MemSImm10Lsl1:
5788 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5789 "expected memory with 11-bit signed offset and multiple of 2");
5790 case Match_MemSImm10Lsl2:
5791 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5792 "expected memory with 12-bit signed offset and multiple of 4");
5793 case Match_MemSImm10Lsl3:
5794 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5795 "expected memory with 13-bit signed offset and multiple of 8");
5796 case Match_MemSImm11:
5797 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5798 "expected memory with 11-bit signed offset");
5799 case Match_MemSImm12:
5800 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5801 "expected memory with 12-bit signed offset");
5802 case Match_MemSImm16:
5803 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5804 "expected memory with 16-bit signed offset");
5805 case Match_MemSImmPtr:
5806 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5807 "expected memory with 32-bit signed offset");
5808 case Match_RequiresPosSizeRange0_32: {
5809 SMLoc ErrorStart = Operands[3]->getStartLoc();
5810 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5811 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5812 SMRange(ErrorStart, ErrorEnd));
5814 case Match_RequiresPosSizeUImm6: {
5815 SMLoc ErrorStart = Operands[3]->getStartLoc();
5816 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5817 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5818 SMRange(ErrorStart, ErrorEnd));
5820 case Match_RequiresPosSizeRange33_64: {
5821 SMLoc ErrorStart = Operands[3]->getStartLoc();
5822 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5823 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5824 SMRange(ErrorStart, ErrorEnd));
5828 llvm_unreachable("Implement any new match types added!");
5831 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5832 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5833 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5834 ") without \".set noat\"");
5837 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5838 if (!AssemblerOptions.back()->isMacro())
5839 Warning(Loc, "macro instruction expanded into multiple instructions");
5842 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5843 const OperandVector &Operands) {
5845 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
5846 "Unexpected instruction!");
5847 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5848 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5849 Inst.addOperand(MCOperand::createReg(NextReg));
5850 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5854 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5855 SMRange Range, bool ShowColors) {
5856 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5857 Range, SMFixIt(Range, FixMsg),
5861 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5864 CC = StringSwitch<unsigned>(Name)
5866 .Cases("at", "AT", 1)
5900 if (!(isABI_N32() || isABI_N64()))
5903 if (12 <= CC && CC <= 15) {
5904 // Name is one of t4-t7
5905 AsmToken RegTok = getLexer().peekTok();
5906 SMRange RegRange = RegTok.getLocRange();
5908 StringRef FixedName = StringSwitch<StringRef>(Name)
5914 assert(FixedName != "" && "Register name is not one of t4-t7.");
5916 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5917 "Did you mean $" + FixedName + "?", RegRange);
5920 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5921 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5922 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5923 if (8 <= CC && CC <= 11)
5927 CC = StringSwitch<unsigned>(Name)
5939 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5942 CC = StringSwitch<unsigned>(Name)
5943 .Case("hwr_cpunum", 0)
5944 .Case("hwr_synci_step", 1)
5946 .Case("hwr_ccres", 3)
5947 .Case("hwr_ulr", 29)
5953 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5954 if (Name[0] == 'f') {
5955 StringRef NumString = Name.substr(1);
5957 if (NumString.getAsInteger(10, IntVal))
5958 return -1; // This is not an integer.
5959 if (IntVal > 31) // Maximum index for fpu register.
5966 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5967 if (Name.startswith("fcc")) {
5968 StringRef NumString = Name.substr(3);
5970 if (NumString.getAsInteger(10, IntVal))
5971 return -1; // This is not an integer.
5972 if (IntVal > 7) // There are only 8 fcc registers.
5979 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5980 if (Name.startswith("ac")) {
5981 StringRef NumString = Name.substr(2);
5983 if (NumString.getAsInteger(10, IntVal))
5984 return -1; // This is not an integer.
5985 if (IntVal > 3) // There are only 3 acc registers.
5992 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5995 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6004 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6007 CC = StringSwitch<unsigned>(Name)
6010 .Case("msaaccess", 2)
6012 .Case("msamodify", 4)
6013 .Case("msarequest", 5)
6015 .Case("msaunmap", 7)
6021 bool MipsAsmParser::canUseATReg() {
6022 return AssemblerOptions.back()->getATRegIndex() != 0;
6025 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
6026 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6028 reportParseError(Loc,
6029 "pseudo-instruction requires $at, which is not available");
6032 unsigned AT = getReg(
6033 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6037 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
6038 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6041 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6042 MCAsmParser &Parser = getParser();
6043 LLVM_DEBUG(dbgs() << "parseOperand\n");
6045 // Check if the current operand has a custom associated parser, if so, try to
6046 // custom parse the operand, or fallback to the general approach.
6047 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6048 if (ResTy == MatchOperand_Success)
6050 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6051 // there was a match, but an error occurred, in which case, just return that
6052 // the operand parsing failed.
6053 if (ResTy == MatchOperand_ParseFail)
6056 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6058 switch (getLexer().getKind()) {
6059 case AsmToken::Dollar: {
6060 // Parse the register.
6061 SMLoc S = Parser.getTok().getLoc();
6063 // Almost all registers have been parsed by custom parsers. There is only
6064 // one exception to this. $zero (and it's alias $0) will reach this point
6065 // for div, divu, and similar instructions because it is not an operand
6066 // to the instruction definition but an explicit register. Special case
6067 // this situation for now.
6068 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
6071 // Maybe it is a symbol reference.
6072 StringRef Identifier;
6073 if (Parser.parseIdentifier(Identifier))
6076 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6077 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
6078 // Otherwise create a symbol reference.
6080 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
6082 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
6086 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6089 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6090 if (getParser().parseExpression(Expr))
6093 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6095 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6098 } // switch(getLexer().getKind())
6102 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
6103 switch (Expr->getKind()) {
6104 case MCExpr::Constant:
6106 case MCExpr::SymbolRef:
6107 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
6108 case MCExpr::Binary: {
6109 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
6110 if (!isEvaluated(BE->getLHS()))
6112 return isEvaluated(BE->getRHS());
6115 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
6116 case MCExpr::Target:
6122 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
6124 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6125 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6126 if (ResTy == MatchOperand_Success) {
6127 assert(Operands.size() == 1);
6128 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6129 StartLoc = Operand.getStartLoc();
6130 EndLoc = Operand.getEndLoc();
6132 // AFAIK, we only support numeric registers and named GPR's in CFI
6134 // Don't worry about eating tokens before failing. Using an unrecognised
6135 // register is a parse error.
6136 if (Operand.isGPRAsmReg()) {
6137 // Resolve to GPR32 or GPR64 appropriately.
6138 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6141 return (RegNo == (unsigned)-1);
6144 assert(Operands.size() == 0);
6145 return (RegNo == (unsigned)-1);
6148 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
6152 return getParser().parseParenExprOfDepth(0, Res, S);
6153 return getParser().parseExpression(Res);
6156 OperandMatchResultTy
6157 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6158 MCAsmParser &Parser = getParser();
6159 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6160 const MCExpr *IdVal = nullptr;
6162 bool isParenExpr = false;
6163 OperandMatchResultTy Res = MatchOperand_NoMatch;
6164 // First operand is the offset.
6165 S = Parser.getTok().getLoc();
6167 if (getLexer().getKind() == AsmToken::LParen) {
6172 if (getLexer().getKind() != AsmToken::Dollar) {
6173 if (parseMemOffset(IdVal, isParenExpr))
6174 return MatchOperand_ParseFail;
6176 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6177 if (Tok.isNot(AsmToken::LParen)) {
6178 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6179 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6181 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6182 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6183 return MatchOperand_Success;
6185 if (Tok.is(AsmToken::EndOfStatement)) {
6187 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6189 // Zero register assumed, add a memory operand with ZERO as its base.
6190 // "Base" will be managed by k_Memory.
6191 auto Base = MipsOperand::createGPRReg(
6192 0, "0", getContext().getRegisterInfo(), S, E, *this);
6194 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6195 return MatchOperand_Success;
6197 MCBinaryExpr::Opcode Opcode;
6198 // GAS and LLVM treat comparison operators different. GAS will generate -1
6199 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6200 // highly unlikely to be found in a memory offset expression, we don't
6202 switch (Tok.getKind()) {
6203 case AsmToken::Plus:
6204 Opcode = MCBinaryExpr::Add;
6207 case AsmToken::Minus:
6208 Opcode = MCBinaryExpr::Sub;
6211 case AsmToken::Star:
6212 Opcode = MCBinaryExpr::Mul;
6215 case AsmToken::Pipe:
6216 Opcode = MCBinaryExpr::Or;
6220 Opcode = MCBinaryExpr::And;
6223 case AsmToken::LessLess:
6224 Opcode = MCBinaryExpr::Shl;
6227 case AsmToken::GreaterGreater:
6228 Opcode = MCBinaryExpr::LShr;
6231 case AsmToken::Caret:
6232 Opcode = MCBinaryExpr::Xor;
6235 case AsmToken::Slash:
6236 Opcode = MCBinaryExpr::Div;
6239 case AsmToken::Percent:
6240 Opcode = MCBinaryExpr::Mod;
6244 Error(Parser.getTok().getLoc(), "'(' or expression expected");
6245 return MatchOperand_ParseFail;
6247 const MCExpr * NextExpr;
6248 if (getParser().parseExpression(NextExpr))
6249 return MatchOperand_ParseFail;
6250 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6253 Parser.Lex(); // Eat the '(' token.
6256 Res = parseAnyRegister(Operands);
6257 if (Res != MatchOperand_Success)
6260 if (Parser.getTok().isNot(AsmToken::RParen)) {
6261 Error(Parser.getTok().getLoc(), "')' expected");
6262 return MatchOperand_ParseFail;
6265 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6267 Parser.Lex(); // Eat the ')' token.
6270 IdVal = MCConstantExpr::create(0, getContext());
6272 // Replace the register operand with the memory operand.
6273 std::unique_ptr<MipsOperand> op(
6274 static_cast<MipsOperand *>(Operands.back().release()));
6275 // Remove the register from the operands.
6276 // "op" will be managed by k_Memory.
6277 Operands.pop_back();
6278 // Add the memory operand.
6279 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6281 if (IdVal->evaluateAsAbsolute(Imm))
6282 IdVal = MCConstantExpr::create(Imm, getContext());
6283 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6284 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6288 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6289 return MatchOperand_Success;
6292 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6293 MCAsmParser &Parser = getParser();
6294 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6298 SMLoc S = Parser.getTok().getLoc();
6299 if (Sym->isVariable()) {
6300 const MCExpr *Expr = Sym->getVariableValue();
6301 if (Expr->getKind() == MCExpr::SymbolRef) {
6302 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6303 StringRef DefSymbol = Ref->getSymbol().getName();
6304 if (DefSymbol.startswith("$")) {
6305 OperandMatchResultTy ResTy =
6306 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6307 if (ResTy == MatchOperand_Success) {
6311 if (ResTy == MatchOperand_ParseFail)
6312 llvm_unreachable("Should never ParseFail");
6315 } else if (Sym->isUnset()) {
6316 // If symbol is unset, it might be created in the `parseSetAssignment`
6317 // routine as an alias for a numeric register name.
6318 // Lookup in the aliases list.
6319 auto Entry = RegisterSets.find(Sym->getName());
6320 if (Entry != RegisterSets.end()) {
6321 OperandMatchResultTy ResTy =
6322 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6323 if (ResTy == MatchOperand_Success) {
6333 OperandMatchResultTy
6334 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6335 StringRef Identifier,
6337 int Index = matchCPURegisterName(Identifier);
6339 Operands.push_back(MipsOperand::createGPRReg(
6340 Index, Identifier, getContext().getRegisterInfo(), S,
6341 getLexer().getLoc(), *this));
6342 return MatchOperand_Success;
6345 Index = matchHWRegsRegisterName(Identifier);
6347 Operands.push_back(MipsOperand::createHWRegsReg(
6348 Index, Identifier, getContext().getRegisterInfo(), S,
6349 getLexer().getLoc(), *this));
6350 return MatchOperand_Success;
6353 Index = matchFPURegisterName(Identifier);
6355 Operands.push_back(MipsOperand::createFGRReg(
6356 Index, Identifier, getContext().getRegisterInfo(), S,
6357 getLexer().getLoc(), *this));
6358 return MatchOperand_Success;
6361 Index = matchFCCRegisterName(Identifier);
6363 Operands.push_back(MipsOperand::createFCCReg(
6364 Index, Identifier, getContext().getRegisterInfo(), S,
6365 getLexer().getLoc(), *this));
6366 return MatchOperand_Success;
6369 Index = matchACRegisterName(Identifier);
6371 Operands.push_back(MipsOperand::createACCReg(
6372 Index, Identifier, getContext().getRegisterInfo(), S,
6373 getLexer().getLoc(), *this));
6374 return MatchOperand_Success;
6377 Index = matchMSA128RegisterName(Identifier);
6379 Operands.push_back(MipsOperand::createMSA128Reg(
6380 Index, Identifier, getContext().getRegisterInfo(), S,
6381 getLexer().getLoc(), *this));
6382 return MatchOperand_Success;
6385 Index = matchMSA128CtrlRegisterName(Identifier);
6387 Operands.push_back(MipsOperand::createMSACtrlReg(
6388 Index, Identifier, getContext().getRegisterInfo(), S,
6389 getLexer().getLoc(), *this));
6390 return MatchOperand_Success;
6393 return MatchOperand_NoMatch;
6396 OperandMatchResultTy
6397 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6398 const AsmToken &Token, SMLoc S) {
6399 if (Token.is(AsmToken::Identifier)) {
6400 LLVM_DEBUG(dbgs() << ".. identifier\n");
6401 StringRef Identifier = Token.getIdentifier();
6402 OperandMatchResultTy ResTy =
6403 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6405 } else if (Token.is(AsmToken::Integer)) {
6406 LLVM_DEBUG(dbgs() << ".. integer\n");
6407 int64_t RegNum = Token.getIntVal();
6408 if (RegNum < 0 || RegNum > 31) {
6409 // Show the error, but treat invalid register
6410 // number as a normal one to continue parsing
6411 // and catch other possible errors.
6412 Error(getLexer().getLoc(), "invalid register number");
6414 Operands.push_back(MipsOperand::createNumericReg(
6415 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6416 Token.getLoc(), *this));
6417 return MatchOperand_Success;
6420 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6422 return MatchOperand_NoMatch;
6425 OperandMatchResultTy
6426 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6427 auto Token = getLexer().peekTok(false);
6428 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6431 OperandMatchResultTy
6432 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6433 MCAsmParser &Parser = getParser();
6434 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6436 auto Token = Parser.getTok();
6438 SMLoc S = Token.getLoc();
6440 if (Token.isNot(AsmToken::Dollar)) {
6441 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6442 if (Token.is(AsmToken::Identifier)) {
6443 if (searchSymbolAlias(Operands))
6444 return MatchOperand_Success;
6446 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6447 return MatchOperand_NoMatch;
6449 LLVM_DEBUG(dbgs() << ".. $\n");
6451 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6452 if (ResTy == MatchOperand_Success) {
6454 Parser.Lex(); // identifier
6459 OperandMatchResultTy
6460 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6461 MCAsmParser &Parser = getParser();
6462 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6464 SMLoc S = getLexer().getLoc();
6466 // Registers are a valid target and have priority over symbols.
6467 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6468 if (ResTy != MatchOperand_NoMatch)
6471 // Integers and expressions are acceptable
6472 const MCExpr *Expr = nullptr;
6473 if (Parser.parseExpression(Expr)) {
6474 // We have no way of knowing if a symbol was consumed so we must ParseFail
6475 return MatchOperand_ParseFail;
6478 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6479 return MatchOperand_Success;
6482 OperandMatchResultTy
6483 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6484 MCAsmParser &Parser = getParser();
6485 const MCExpr *IdVal;
6486 // If the first token is '$' we may have register operand. We have to reject
6487 // cases where it is not a register. Complicating the matter is that
6488 // register names are not reserved across all ABIs.
6489 // Peek past the dollar to see if it's a register name for this ABI.
6490 SMLoc S = Parser.getTok().getLoc();
6491 if (Parser.getTok().is(AsmToken::Dollar)) {
6492 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6493 ? MatchOperand_ParseFail
6494 : MatchOperand_NoMatch;
6496 if (getParser().parseExpression(IdVal))
6497 return MatchOperand_ParseFail;
6498 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6500 return MatchOperand_NoMatch;
6501 int64_t Val = MCE->getValue();
6502 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6503 Operands.push_back(MipsOperand::CreateImm(
6504 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6505 return MatchOperand_Success;
6508 OperandMatchResultTy
6509 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6510 MCAsmParser &Parser = getParser();
6511 SmallVector<unsigned, 10> Regs;
6513 unsigned PrevReg = Mips::NoRegister;
6514 bool RegRange = false;
6515 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6517 if (Parser.getTok().isNot(AsmToken::Dollar))
6518 return MatchOperand_ParseFail;
6520 SMLoc S = Parser.getTok().getLoc();
6521 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6522 SMLoc E = getLexer().getLoc();
6523 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6524 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6526 // Remove last register operand because registers from register range
6527 // should be inserted first.
6528 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6529 (!isGP64bit() && RegNo == Mips::RA)) {
6530 Regs.push_back(RegNo);
6532 unsigned TmpReg = PrevReg + 1;
6533 while (TmpReg <= RegNo) {
6534 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6535 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6537 Error(E, "invalid register operand");
6538 return MatchOperand_ParseFail;
6542 Regs.push_back(TmpReg++);
6548 if ((PrevReg == Mips::NoRegister) &&
6549 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6550 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6551 Error(E, "$16 or $31 expected");
6552 return MatchOperand_ParseFail;
6553 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6554 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6556 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6557 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6559 Error(E, "invalid register operand");
6560 return MatchOperand_ParseFail;
6561 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6562 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6563 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6565 Error(E, "consecutive register numbers expected");
6566 return MatchOperand_ParseFail;
6569 Regs.push_back(RegNo);
6572 if (Parser.getTok().is(AsmToken::Minus))
6575 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6576 !Parser.getTok().isNot(AsmToken::Comma)) {
6577 Error(E, "',' or '-' expected");
6578 return MatchOperand_ParseFail;
6581 Lex(); // Consume comma or minus
6582 if (Parser.getTok().isNot(AsmToken::Dollar))
6588 SMLoc E = Parser.getTok().getLoc();
6589 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6590 parseMemOperand(Operands);
6591 return MatchOperand_Success;
6594 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6596 /// ::= '(', register, ')'
6597 /// handle it before we iterate so we don't get tripped up by the lack of
6599 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6600 MCAsmParser &Parser = getParser();
6601 if (getLexer().is(AsmToken::LParen)) {
6603 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6605 if (parseOperand(Operands, Name)) {
6606 SMLoc Loc = getLexer().getLoc();
6607 return Error(Loc, "unexpected token in argument list");
6609 if (Parser.getTok().isNot(AsmToken::RParen)) {
6610 SMLoc Loc = getLexer().getLoc();
6611 return Error(Loc, "unexpected token, expected ')'");
6614 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6620 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6621 /// either one of these.
6622 /// ::= '[', register, ']'
6623 /// ::= '[', integer, ']'
6624 /// handle it before we iterate so we don't get tripped up by the lack of
6626 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6627 OperandVector &Operands) {
6628 MCAsmParser &Parser = getParser();
6629 if (getLexer().is(AsmToken::LBrac)) {
6631 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6633 if (parseOperand(Operands, Name)) {
6634 SMLoc Loc = getLexer().getLoc();
6635 return Error(Loc, "unexpected token in argument list");
6637 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6638 SMLoc Loc = getLexer().getLoc();
6639 return Error(Loc, "unexpected token, expected ']'");
6642 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6648 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6649 unsigned VariantID = 0);
6651 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6652 SMLoc NameLoc, OperandVector &Operands) {
6653 MCAsmParser &Parser = getParser();
6654 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6656 // We have reached first instruction, module directive are now forbidden.
6657 getTargetStreamer().forbidModuleDirective();
6659 // Check if we have valid mnemonic
6660 if (!mnemonicIsValid(Name, 0)) {
6661 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6662 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6663 return Error(NameLoc, "unknown instruction" + Suggestion);
6665 // First operand in MCInst is instruction mnemonic.
6666 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6668 // Read the remaining operands.
6669 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6670 // Read the first operand.
6671 if (parseOperand(Operands, Name)) {
6672 SMLoc Loc = getLexer().getLoc();
6673 return Error(Loc, "unexpected token in argument list");
6675 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6677 // AFAIK, parenthesis suffixes are never on the first operand
6679 while (getLexer().is(AsmToken::Comma)) {
6680 Parser.Lex(); // Eat the comma.
6681 // Parse and remember the operand.
6682 if (parseOperand(Operands, Name)) {
6683 SMLoc Loc = getLexer().getLoc();
6684 return Error(Loc, "unexpected token in argument list");
6686 // Parse bracket and parenthesis suffixes before we iterate
6687 if (getLexer().is(AsmToken::LBrac)) {
6688 if (parseBracketSuffix(Name, Operands))
6690 } else if (getLexer().is(AsmToken::LParen) &&
6691 parseParenSuffix(Name, Operands))
6695 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6696 SMLoc Loc = getLexer().getLoc();
6697 return Error(Loc, "unexpected token in argument list");
6699 Parser.Lex(); // Consume the EndOfStatement.
6703 // FIXME: Given that these have the same name, these should both be
6704 // consistent on affecting the Parser.
6705 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6706 SMLoc Loc = getLexer().getLoc();
6707 return Error(Loc, ErrorMsg);
6710 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6711 return Error(Loc, ErrorMsg);
6714 bool MipsAsmParser::parseSetNoAtDirective() {
6715 MCAsmParser &Parser = getParser();
6716 // Line should look like: ".set noat".
6718 // Set the $at register to $0.
6719 AssemblerOptions.back()->setATRegIndex(0);
6721 Parser.Lex(); // Eat "noat".
6723 // If this is not the end of the statement, report an error.
6724 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6725 reportParseError("unexpected token, expected end of statement");
6729 getTargetStreamer().emitDirectiveSetNoAt();
6730 Parser.Lex(); // Consume the EndOfStatement.
6734 bool MipsAsmParser::parseSetAtDirective() {
6735 // Line can be: ".set at", which sets $at to $1
6736 // or ".set at=$reg", which sets $at to $reg.
6737 MCAsmParser &Parser = getParser();
6738 Parser.Lex(); // Eat "at".
6740 if (getLexer().is(AsmToken::EndOfStatement)) {
6741 // No register was specified, so we set $at to $1.
6742 AssemblerOptions.back()->setATRegIndex(1);
6744 getTargetStreamer().emitDirectiveSetAt();
6745 Parser.Lex(); // Consume the EndOfStatement.
6749 if (getLexer().isNot(AsmToken::Equal)) {
6750 reportParseError("unexpected token, expected equals sign");
6753 Parser.Lex(); // Eat "=".
6755 if (getLexer().isNot(AsmToken::Dollar)) {
6756 if (getLexer().is(AsmToken::EndOfStatement)) {
6757 reportParseError("no register specified");
6760 reportParseError("unexpected token, expected dollar sign '$'");
6764 Parser.Lex(); // Eat "$".
6766 // Find out what "reg" is.
6768 const AsmToken &Reg = Parser.getTok();
6769 if (Reg.is(AsmToken::Identifier)) {
6770 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6771 } else if (Reg.is(AsmToken::Integer)) {
6772 AtRegNo = Reg.getIntVal();
6774 reportParseError("unexpected token, expected identifier or integer");
6778 // Check if $reg is a valid register. If it is, set $at to $reg.
6779 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6780 reportParseError("invalid register");
6783 Parser.Lex(); // Eat "reg".
6785 // If this is not the end of the statement, report an error.
6786 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6787 reportParseError("unexpected token, expected end of statement");
6791 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6793 Parser.Lex(); // Consume the EndOfStatement.
6797 bool MipsAsmParser::parseSetReorderDirective() {
6798 MCAsmParser &Parser = getParser();
6800 // If this is not the end of the statement, report an error.
6801 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6802 reportParseError("unexpected token, expected end of statement");
6805 AssemblerOptions.back()->setReorder();
6806 getTargetStreamer().emitDirectiveSetReorder();
6807 Parser.Lex(); // Consume the EndOfStatement.
6811 bool MipsAsmParser::parseSetNoReorderDirective() {
6812 MCAsmParser &Parser = getParser();
6814 // If this is not the end of the statement, report an error.
6815 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6816 reportParseError("unexpected token, expected end of statement");
6819 AssemblerOptions.back()->setNoReorder();
6820 getTargetStreamer().emitDirectiveSetNoReorder();
6821 Parser.Lex(); // Consume the EndOfStatement.
6825 bool MipsAsmParser::parseSetMacroDirective() {
6826 MCAsmParser &Parser = getParser();
6828 // If this is not the end of the statement, report an error.
6829 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6830 reportParseError("unexpected token, expected end of statement");
6833 AssemblerOptions.back()->setMacro();
6834 getTargetStreamer().emitDirectiveSetMacro();
6835 Parser.Lex(); // Consume the EndOfStatement.
6839 bool MipsAsmParser::parseSetNoMacroDirective() {
6840 MCAsmParser &Parser = getParser();
6842 // If this is not the end of the statement, report an error.
6843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6844 reportParseError("unexpected token, expected end of statement");
6847 if (AssemblerOptions.back()->isReorder()) {
6848 reportParseError("`noreorder' must be set before `nomacro'");
6851 AssemblerOptions.back()->setNoMacro();
6852 getTargetStreamer().emitDirectiveSetNoMacro();
6853 Parser.Lex(); // Consume the EndOfStatement.
6857 bool MipsAsmParser::parseSetMsaDirective() {
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 setFeatureBits(Mips::FeatureMSA, "msa");
6866 getTargetStreamer().emitDirectiveSetMsa();
6870 bool MipsAsmParser::parseSetNoMsaDirective() {
6871 MCAsmParser &Parser = getParser();
6874 // If this is not the end of the statement, report an error.
6875 if (getLexer().isNot(AsmToken::EndOfStatement))
6876 return reportParseError("unexpected token, expected end of statement");
6878 clearFeatureBits(Mips::FeatureMSA, "msa");
6879 getTargetStreamer().emitDirectiveSetNoMsa();
6883 bool MipsAsmParser::parseSetNoDspDirective() {
6884 MCAsmParser &Parser = getParser();
6885 Parser.Lex(); // Eat "nodsp".
6887 // If this is not the end of the statement, report an error.
6888 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6889 reportParseError("unexpected token, expected end of statement");
6893 clearFeatureBits(Mips::FeatureDSP, "dsp");
6894 getTargetStreamer().emitDirectiveSetNoDsp();
6898 bool MipsAsmParser::parseSetMips16Directive() {
6899 MCAsmParser &Parser = getParser();
6900 Parser.Lex(); // Eat "mips16".
6902 // If this is not the end of the statement, report an error.
6903 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6904 reportParseError("unexpected token, expected end of statement");
6908 setFeatureBits(Mips::FeatureMips16, "mips16");
6909 getTargetStreamer().emitDirectiveSetMips16();
6910 Parser.Lex(); // Consume the EndOfStatement.
6914 bool MipsAsmParser::parseSetNoMips16Directive() {
6915 MCAsmParser &Parser = getParser();
6916 Parser.Lex(); // Eat "nomips16".
6918 // If this is not the end of the statement, report an error.
6919 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6920 reportParseError("unexpected token, expected end of statement");
6924 clearFeatureBits(Mips::FeatureMips16, "mips16");
6925 getTargetStreamer().emitDirectiveSetNoMips16();
6926 Parser.Lex(); // Consume the EndOfStatement.
6930 bool MipsAsmParser::parseSetFpDirective() {
6931 MCAsmParser &Parser = getParser();
6932 MipsABIFlagsSection::FpABIKind FpAbiVal;
6933 // Line can be: .set fp=32
6936 Parser.Lex(); // Eat fp token
6937 AsmToken Tok = Parser.getTok();
6938 if (Tok.isNot(AsmToken::Equal)) {
6939 reportParseError("unexpected token, expected equals sign '='");
6942 Parser.Lex(); // Eat '=' token.
6943 Tok = Parser.getTok();
6945 if (!parseFpABIValue(FpAbiVal, ".set"))
6948 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6949 reportParseError("unexpected token, expected end of statement");
6952 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6953 Parser.Lex(); // Consume the EndOfStatement.
6957 bool MipsAsmParser::parseSetOddSPRegDirective() {
6958 MCAsmParser &Parser = getParser();
6960 Parser.Lex(); // Eat "oddspreg".
6961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6962 reportParseError("unexpected token, expected end of statement");
6966 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6967 getTargetStreamer().emitDirectiveSetOddSPReg();
6971 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6972 MCAsmParser &Parser = getParser();
6974 Parser.Lex(); // Eat "nooddspreg".
6975 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6976 reportParseError("unexpected token, expected end of statement");
6980 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6981 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6985 bool MipsAsmParser::parseSetMtDirective() {
6986 MCAsmParser &Parser = getParser();
6987 Parser.Lex(); // Eat "mt".
6989 // If this is not the end of the statement, report an error.
6990 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6991 reportParseError("unexpected token, expected end of statement");
6995 setFeatureBits(Mips::FeatureMT, "mt");
6996 getTargetStreamer().emitDirectiveSetMt();
6997 Parser.Lex(); // Consume the EndOfStatement.
7001 bool MipsAsmParser::parseSetNoMtDirective() {
7002 MCAsmParser &Parser = getParser();
7003 Parser.Lex(); // Eat "nomt".
7005 // If this is not the end of the statement, report an error.
7006 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7007 reportParseError("unexpected token, expected end of statement");
7011 clearFeatureBits(Mips::FeatureMT, "mt");
7013 getTargetStreamer().emitDirectiveSetNoMt();
7014 Parser.Lex(); // Consume the EndOfStatement.
7018 bool MipsAsmParser::parseSetNoCRCDirective() {
7019 MCAsmParser &Parser = getParser();
7020 Parser.Lex(); // Eat "nocrc".
7022 // If this is not the end of the statement, report an error.
7023 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7024 reportParseError("unexpected token, expected end of statement");
7028 clearFeatureBits(Mips::FeatureCRC, "crc");
7030 getTargetStreamer().emitDirectiveSetNoCRC();
7031 Parser.Lex(); // Consume the EndOfStatement.
7035 bool MipsAsmParser::parseSetNoVirtDirective() {
7036 MCAsmParser &Parser = getParser();
7037 Parser.Lex(); // Eat "novirt".
7039 // If this is not the end of the statement, report an error.
7040 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7041 reportParseError("unexpected token, expected end of statement");
7045 clearFeatureBits(Mips::FeatureVirt, "virt");
7047 getTargetStreamer().emitDirectiveSetNoVirt();
7048 Parser.Lex(); // Consume the EndOfStatement.
7052 bool MipsAsmParser::parseSetNoGINVDirective() {
7053 MCAsmParser &Parser = getParser();
7054 Parser.Lex(); // Eat "noginv".
7056 // If this is not the end of the statement, report an error.
7057 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7058 reportParseError("unexpected token, expected end of statement");
7062 clearFeatureBits(Mips::FeatureGINV, "ginv");
7064 getTargetStreamer().emitDirectiveSetNoGINV();
7065 Parser.Lex(); // Consume the EndOfStatement.
7069 bool MipsAsmParser::parseSetPopDirective() {
7070 MCAsmParser &Parser = getParser();
7071 SMLoc Loc = getLexer().getLoc();
7074 if (getLexer().isNot(AsmToken::EndOfStatement))
7075 return reportParseError("unexpected token, expected end of statement");
7077 // Always keep an element on the options "stack" to prevent the user
7078 // from changing the initial options. This is how we remember them.
7079 if (AssemblerOptions.size() == 2)
7080 return reportParseError(Loc, ".set pop with no .set push");
7082 MCSubtargetInfo &STI = copySTI();
7083 AssemblerOptions.pop_back();
7084 setAvailableFeatures(
7085 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7086 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7088 getTargetStreamer().emitDirectiveSetPop();
7092 bool MipsAsmParser::parseSetPushDirective() {
7093 MCAsmParser &Parser = getParser();
7095 if (getLexer().isNot(AsmToken::EndOfStatement))
7096 return reportParseError("unexpected token, expected end of statement");
7098 // Create a copy of the current assembler options environment and push it.
7099 AssemblerOptions.push_back(
7100 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7102 getTargetStreamer().emitDirectiveSetPush();
7106 bool MipsAsmParser::parseSetSoftFloatDirective() {
7107 MCAsmParser &Parser = getParser();
7109 if (getLexer().isNot(AsmToken::EndOfStatement))
7110 return reportParseError("unexpected token, expected end of statement");
7112 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7113 getTargetStreamer().emitDirectiveSetSoftFloat();
7117 bool MipsAsmParser::parseSetHardFloatDirective() {
7118 MCAsmParser &Parser = getParser();
7120 if (getLexer().isNot(AsmToken::EndOfStatement))
7121 return reportParseError("unexpected token, expected end of statement");
7123 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7124 getTargetStreamer().emitDirectiveSetHardFloat();
7128 bool MipsAsmParser::parseSetAssignment() {
7130 MCAsmParser &Parser = getParser();
7132 if (Parser.parseIdentifier(Name))
7133 return reportParseError("expected identifier after .set");
7135 if (getLexer().isNot(AsmToken::Comma))
7136 return reportParseError("unexpected token, expected comma");
7139 if (getLexer().is(AsmToken::Dollar) &&
7140 getLexer().peekTok().is(AsmToken::Integer)) {
7141 // Parse assignment of a numeric register:
7143 Parser.Lex(); // Eat $.
7144 RegisterSets[Name] = Parser.getTok();
7145 Parser.Lex(); // Eat identifier.
7146 getContext().getOrCreateSymbol(Name);
7151 const MCExpr *Value;
7152 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7153 Parser, Sym, Value))
7155 Sym->setVariableValue(Value);
7160 bool MipsAsmParser::parseSetMips0Directive() {
7161 MCAsmParser &Parser = getParser();
7163 if (getLexer().isNot(AsmToken::EndOfStatement))
7164 return reportParseError("unexpected token, expected end of statement");
7166 // Reset assembler options to their initial values.
7167 MCSubtargetInfo &STI = copySTI();
7168 setAvailableFeatures(
7169 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7170 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7171 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7173 getTargetStreamer().emitDirectiveSetMips0();
7177 bool MipsAsmParser::parseSetArchDirective() {
7178 MCAsmParser &Parser = getParser();
7180 if (getLexer().isNot(AsmToken::Equal))
7181 return reportParseError("unexpected token, expected equals sign");
7184 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7186 return reportParseError("expected arch identifier");
7188 StringRef ArchFeatureName =
7189 StringSwitch<StringRef>(Arch)
7190 .Case("mips1", "mips1")
7191 .Case("mips2", "mips2")
7192 .Case("mips3", "mips3")
7193 .Case("mips4", "mips4")
7194 .Case("mips5", "mips5")
7195 .Case("mips32", "mips32")
7196 .Case("mips32r2", "mips32r2")
7197 .Case("mips32r3", "mips32r3")
7198 .Case("mips32r5", "mips32r5")
7199 .Case("mips32r6", "mips32r6")
7200 .Case("mips64", "mips64")
7201 .Case("mips64r2", "mips64r2")
7202 .Case("mips64r3", "mips64r3")
7203 .Case("mips64r5", "mips64r5")
7204 .Case("mips64r6", "mips64r6")
7205 .Case("octeon", "cnmips")
7206 .Case("octeon+", "cnmipsp")
7207 .Case("r4000", "mips3") // This is an implementation of Mips3.
7210 if (ArchFeatureName.empty())
7211 return reportParseError("unsupported architecture");
7213 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7214 return reportParseError("mips64r6 does not support microMIPS");
7216 selectArch(ArchFeatureName);
7217 getTargetStreamer().emitDirectiveSetArch(Arch);
7221 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7222 MCAsmParser &Parser = getParser();
7224 if (getLexer().isNot(AsmToken::EndOfStatement))
7225 return reportParseError("unexpected token, expected end of statement");
7229 llvm_unreachable("Unimplemented feature");
7230 case Mips::FeatureDSP:
7231 setFeatureBits(Mips::FeatureDSP, "dsp");
7232 getTargetStreamer().emitDirectiveSetDsp();
7234 case Mips::FeatureDSPR2:
7235 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7236 getTargetStreamer().emitDirectiveSetDspr2();
7238 case Mips::FeatureMicroMips:
7239 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7240 getTargetStreamer().emitDirectiveSetMicroMips();
7242 case Mips::FeatureMips1:
7243 selectArch("mips1");
7244 getTargetStreamer().emitDirectiveSetMips1();
7246 case Mips::FeatureMips2:
7247 selectArch("mips2");
7248 getTargetStreamer().emitDirectiveSetMips2();
7250 case Mips::FeatureMips3:
7251 selectArch("mips3");
7252 getTargetStreamer().emitDirectiveSetMips3();
7254 case Mips::FeatureMips4:
7255 selectArch("mips4");
7256 getTargetStreamer().emitDirectiveSetMips4();
7258 case Mips::FeatureMips5:
7259 selectArch("mips5");
7260 getTargetStreamer().emitDirectiveSetMips5();
7262 case Mips::FeatureMips32:
7263 selectArch("mips32");
7264 getTargetStreamer().emitDirectiveSetMips32();
7266 case Mips::FeatureMips32r2:
7267 selectArch("mips32r2");
7268 getTargetStreamer().emitDirectiveSetMips32R2();
7270 case Mips::FeatureMips32r3:
7271 selectArch("mips32r3");
7272 getTargetStreamer().emitDirectiveSetMips32R3();
7274 case Mips::FeatureMips32r5:
7275 selectArch("mips32r5");
7276 getTargetStreamer().emitDirectiveSetMips32R5();
7278 case Mips::FeatureMips32r6:
7279 selectArch("mips32r6");
7280 getTargetStreamer().emitDirectiveSetMips32R6();
7282 case Mips::FeatureMips64:
7283 selectArch("mips64");
7284 getTargetStreamer().emitDirectiveSetMips64();
7286 case Mips::FeatureMips64r2:
7287 selectArch("mips64r2");
7288 getTargetStreamer().emitDirectiveSetMips64R2();
7290 case Mips::FeatureMips64r3:
7291 selectArch("mips64r3");
7292 getTargetStreamer().emitDirectiveSetMips64R3();
7294 case Mips::FeatureMips64r5:
7295 selectArch("mips64r5");
7296 getTargetStreamer().emitDirectiveSetMips64R5();
7298 case Mips::FeatureMips64r6:
7299 selectArch("mips64r6");
7300 getTargetStreamer().emitDirectiveSetMips64R6();
7302 case Mips::FeatureCRC:
7303 setFeatureBits(Mips::FeatureCRC, "crc");
7304 getTargetStreamer().emitDirectiveSetCRC();
7306 case Mips::FeatureVirt:
7307 setFeatureBits(Mips::FeatureVirt, "virt");
7308 getTargetStreamer().emitDirectiveSetVirt();
7310 case Mips::FeatureGINV:
7311 setFeatureBits(Mips::FeatureGINV, "ginv");
7312 getTargetStreamer().emitDirectiveSetGINV();
7318 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7319 MCAsmParser &Parser = getParser();
7320 if (getLexer().isNot(AsmToken::Comma)) {
7321 SMLoc Loc = getLexer().getLoc();
7322 return Error(Loc, ErrorStr);
7325 Parser.Lex(); // Eat the comma.
7329 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7330 // In this class, it is only used for .cprestore.
7331 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7332 // MipsTargetELFStreamer and MipsAsmParser.
7333 bool MipsAsmParser::isPicAndNotNxxAbi() {
7334 return inPicMode() && !(isABI_N32() || isABI_N64());
7337 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7338 if (AssemblerOptions.back()->isReorder())
7339 Warning(Loc, ".cpload should be inside a noreorder section");
7341 if (inMips16Mode()) {
7342 reportParseError(".cpload is not supported in Mips16 mode");
7346 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7347 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7348 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7349 reportParseError("expected register containing function address");
7353 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7354 if (!RegOpnd.isGPRAsmReg()) {
7355 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7359 // If this is not the end of the statement, report an error.
7360 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7361 reportParseError("unexpected token, expected end of statement");
7365 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7369 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7370 if (!isABI_N32() && !isABI_N64()) {
7371 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7375 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7376 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7377 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7378 reportParseError("expected register containing global pointer");
7382 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7383 if (!RegOpnd.isGPRAsmReg()) {
7384 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7388 // If this is not the end of the statement, report an error.
7389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7390 reportParseError("unexpected token, expected end of statement");
7393 getParser().Lex(); // Consume the EndOfStatement.
7395 unsigned NewReg = RegOpnd.getGPR32Reg();
7399 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7403 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7404 MCAsmParser &Parser = getParser();
7406 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7407 // is used in non-PIC mode.
7409 if (inMips16Mode()) {
7410 reportParseError(".cprestore is not supported in Mips16 mode");
7414 // Get the stack offset value.
7415 const MCExpr *StackOffset;
7416 int64_t StackOffsetVal;
7417 if (Parser.parseExpression(StackOffset)) {
7418 reportParseError("expected stack offset value");
7422 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7423 reportParseError("stack offset is not an absolute expression");
7427 if (StackOffsetVal < 0) {
7428 Warning(Loc, ".cprestore with negative stack offset has no effect");
7429 IsCpRestoreSet = false;
7431 IsCpRestoreSet = true;
7432 CpRestoreOffset = StackOffsetVal;
7435 // If this is not the end of the statement, report an error.
7436 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7437 reportParseError("unexpected token, expected end of statement");
7441 if (!getTargetStreamer().emitDirectiveCpRestore(
7442 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7444 Parser.Lex(); // Consume the EndOfStatement.
7448 bool MipsAsmParser::parseDirectiveCPSetup() {
7449 MCAsmParser &Parser = getParser();
7452 bool SaveIsReg = true;
7454 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7455 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7456 if (ResTy == MatchOperand_NoMatch) {
7457 reportParseError("expected register containing function address");
7461 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7462 if (!FuncRegOpnd.isGPRAsmReg()) {
7463 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7467 FuncReg = FuncRegOpnd.getGPR32Reg();
7470 if (!eatComma("unexpected token, expected comma"))
7473 ResTy = parseAnyRegister(TmpReg);
7474 if (ResTy == MatchOperand_NoMatch) {
7475 const MCExpr *OffsetExpr;
7477 SMLoc ExprLoc = getLexer().getLoc();
7479 if (Parser.parseExpression(OffsetExpr) ||
7480 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7481 reportParseError(ExprLoc, "expected save register or stack offset");
7488 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7489 if (!SaveOpnd.isGPRAsmReg()) {
7490 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7493 Save = SaveOpnd.getGPR32Reg();
7496 if (!eatComma("unexpected token, expected comma"))
7500 if (Parser.parseExpression(Expr)) {
7501 reportParseError("expected expression");
7505 if (Expr->getKind() != MCExpr::SymbolRef) {
7506 reportParseError("expected symbol");
7509 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7511 CpSaveLocation = Save;
7512 CpSaveLocationIsRegister = SaveIsReg;
7514 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7519 bool MipsAsmParser::parseDirectiveCPReturn() {
7520 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7521 CpSaveLocationIsRegister);
7525 bool MipsAsmParser::parseDirectiveNaN() {
7526 MCAsmParser &Parser = getParser();
7527 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7528 const AsmToken &Tok = Parser.getTok();
7530 if (Tok.getString() == "2008") {
7532 getTargetStreamer().emitDirectiveNaN2008();
7534 } else if (Tok.getString() == "legacy") {
7536 getTargetStreamer().emitDirectiveNaNLegacy();
7540 // If we don't recognize the option passed to the .nan
7541 // directive (e.g. no option or unknown option), emit an error.
7542 reportParseError("invalid option in .nan directive");
7546 bool MipsAsmParser::parseDirectiveSet() {
7547 const AsmToken &Tok = getParser().getTok();
7548 StringRef IdVal = Tok.getString();
7549 SMLoc Loc = Tok.getLoc();
7551 if (IdVal == "noat")
7552 return parseSetNoAtDirective();
7554 return parseSetAtDirective();
7555 if (IdVal == "arch")
7556 return parseSetArchDirective();
7557 if (IdVal == "bopt") {
7558 Warning(Loc, "'bopt' feature is unsupported");
7562 if (IdVal == "nobopt") {
7563 // We're already running in nobopt mode, so nothing to do.
7568 return parseSetFpDirective();
7569 if (IdVal == "oddspreg")
7570 return parseSetOddSPRegDirective();
7571 if (IdVal == "nooddspreg")
7572 return parseSetNoOddSPRegDirective();
7574 return parseSetPopDirective();
7575 if (IdVal == "push")
7576 return parseSetPushDirective();
7577 if (IdVal == "reorder")
7578 return parseSetReorderDirective();
7579 if (IdVal == "noreorder")
7580 return parseSetNoReorderDirective();
7581 if (IdVal == "macro")
7582 return parseSetMacroDirective();
7583 if (IdVal == "nomacro")
7584 return parseSetNoMacroDirective();
7585 if (IdVal == "mips16")
7586 return parseSetMips16Directive();
7587 if (IdVal == "nomips16")
7588 return parseSetNoMips16Directive();
7589 if (IdVal == "nomicromips") {
7590 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7591 getTargetStreamer().emitDirectiveSetNoMicroMips();
7592 getParser().eatToEndOfStatement();
7595 if (IdVal == "micromips") {
7596 if (hasMips64r6()) {
7597 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7600 return parseSetFeature(Mips::FeatureMicroMips);
7602 if (IdVal == "mips0")
7603 return parseSetMips0Directive();
7604 if (IdVal == "mips1")
7605 return parseSetFeature(Mips::FeatureMips1);
7606 if (IdVal == "mips2")
7607 return parseSetFeature(Mips::FeatureMips2);
7608 if (IdVal == "mips3")
7609 return parseSetFeature(Mips::FeatureMips3);
7610 if (IdVal == "mips4")
7611 return parseSetFeature(Mips::FeatureMips4);
7612 if (IdVal == "mips5")
7613 return parseSetFeature(Mips::FeatureMips5);
7614 if (IdVal == "mips32")
7615 return parseSetFeature(Mips::FeatureMips32);
7616 if (IdVal == "mips32r2")
7617 return parseSetFeature(Mips::FeatureMips32r2);
7618 if (IdVal == "mips32r3")
7619 return parseSetFeature(Mips::FeatureMips32r3);
7620 if (IdVal == "mips32r5")
7621 return parseSetFeature(Mips::FeatureMips32r5);
7622 if (IdVal == "mips32r6")
7623 return parseSetFeature(Mips::FeatureMips32r6);
7624 if (IdVal == "mips64")
7625 return parseSetFeature(Mips::FeatureMips64);
7626 if (IdVal == "mips64r2")
7627 return parseSetFeature(Mips::FeatureMips64r2);
7628 if (IdVal == "mips64r3")
7629 return parseSetFeature(Mips::FeatureMips64r3);
7630 if (IdVal == "mips64r5")
7631 return parseSetFeature(Mips::FeatureMips64r5);
7632 if (IdVal == "mips64r6") {
7633 if (inMicroMipsMode()) {
7634 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7637 return parseSetFeature(Mips::FeatureMips64r6);
7640 return parseSetFeature(Mips::FeatureDSP);
7641 if (IdVal == "dspr2")
7642 return parseSetFeature(Mips::FeatureDSPR2);
7643 if (IdVal == "nodsp")
7644 return parseSetNoDspDirective();
7646 return parseSetMsaDirective();
7647 if (IdVal == "nomsa")
7648 return parseSetNoMsaDirective();
7650 return parseSetMtDirective();
7651 if (IdVal == "nomt")
7652 return parseSetNoMtDirective();
7653 if (IdVal == "softfloat")
7654 return parseSetSoftFloatDirective();
7655 if (IdVal == "hardfloat")
7656 return parseSetHardFloatDirective();
7658 return parseSetFeature(Mips::FeatureCRC);
7659 if (IdVal == "nocrc")
7660 return parseSetNoCRCDirective();
7661 if (IdVal == "virt")
7662 return parseSetFeature(Mips::FeatureVirt);
7663 if (IdVal == "novirt")
7664 return parseSetNoVirtDirective();
7665 if (IdVal == "ginv")
7666 return parseSetFeature(Mips::FeatureGINV);
7667 if (IdVal == "noginv")
7668 return parseSetNoGINVDirective();
7670 // It is just an identifier, look for an assignment.
7671 return parseSetAssignment();
7674 /// parseDirectiveGpWord
7675 /// ::= .gpword local_sym
7676 bool MipsAsmParser::parseDirectiveGpWord() {
7677 MCAsmParser &Parser = getParser();
7678 const MCExpr *Value;
7679 // EmitGPRel32Value requires an expression, so we are using base class
7680 // method to evaluate the expression.
7681 if (getParser().parseExpression(Value))
7683 getParser().getStreamer().EmitGPRel32Value(Value);
7685 if (getLexer().isNot(AsmToken::EndOfStatement))
7686 return Error(getLexer().getLoc(),
7687 "unexpected token, expected end of statement");
7688 Parser.Lex(); // Eat EndOfStatement token.
7692 /// parseDirectiveGpDWord
7693 /// ::= .gpdword local_sym
7694 bool MipsAsmParser::parseDirectiveGpDWord() {
7695 MCAsmParser &Parser = getParser();
7696 const MCExpr *Value;
7697 // EmitGPRel64Value requires an expression, so we are using base class
7698 // method to evaluate the expression.
7699 if (getParser().parseExpression(Value))
7701 getParser().getStreamer().EmitGPRel64Value(Value);
7703 if (getLexer().isNot(AsmToken::EndOfStatement))
7704 return Error(getLexer().getLoc(),
7705 "unexpected token, expected end of statement");
7706 Parser.Lex(); // Eat EndOfStatement token.
7710 /// parseDirectiveDtpRelWord
7711 /// ::= .dtprelword tls_sym
7712 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7713 MCAsmParser &Parser = getParser();
7714 const MCExpr *Value;
7715 // EmitDTPRel32Value requires an expression, so we are using base class
7716 // method to evaluate the expression.
7717 if (getParser().parseExpression(Value))
7719 getParser().getStreamer().EmitDTPRel32Value(Value);
7721 if (getLexer().isNot(AsmToken::EndOfStatement))
7722 return Error(getLexer().getLoc(),
7723 "unexpected token, expected end of statement");
7724 Parser.Lex(); // Eat EndOfStatement token.
7728 /// parseDirectiveDtpRelDWord
7729 /// ::= .dtpreldword tls_sym
7730 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7731 MCAsmParser &Parser = getParser();
7732 const MCExpr *Value;
7733 // EmitDTPRel64Value requires an expression, so we are using base class
7734 // method to evaluate the expression.
7735 if (getParser().parseExpression(Value))
7737 getParser().getStreamer().EmitDTPRel64Value(Value);
7739 if (getLexer().isNot(AsmToken::EndOfStatement))
7740 return Error(getLexer().getLoc(),
7741 "unexpected token, expected end of statement");
7742 Parser.Lex(); // Eat EndOfStatement token.
7746 /// parseDirectiveTpRelWord
7747 /// ::= .tprelword tls_sym
7748 bool MipsAsmParser::parseDirectiveTpRelWord() {
7749 MCAsmParser &Parser = getParser();
7750 const MCExpr *Value;
7751 // EmitTPRel32Value requires an expression, so we are using base class
7752 // method to evaluate the expression.
7753 if (getParser().parseExpression(Value))
7755 getParser().getStreamer().EmitTPRel32Value(Value);
7757 if (getLexer().isNot(AsmToken::EndOfStatement))
7758 return Error(getLexer().getLoc(),
7759 "unexpected token, expected end of statement");
7760 Parser.Lex(); // Eat EndOfStatement token.
7764 /// parseDirectiveTpRelDWord
7765 /// ::= .tpreldword tls_sym
7766 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7767 MCAsmParser &Parser = getParser();
7768 const MCExpr *Value;
7769 // EmitTPRel64Value requires an expression, so we are using base class
7770 // method to evaluate the expression.
7771 if (getParser().parseExpression(Value))
7773 getParser().getStreamer().EmitTPRel64Value(Value);
7775 if (getLexer().isNot(AsmToken::EndOfStatement))
7776 return Error(getLexer().getLoc(),
7777 "unexpected token, expected end of statement");
7778 Parser.Lex(); // Eat EndOfStatement token.
7782 bool MipsAsmParser::parseDirectiveOption() {
7783 MCAsmParser &Parser = getParser();
7784 // Get the option token.
7785 AsmToken Tok = Parser.getTok();
7786 // At the moment only identifiers are supported.
7787 if (Tok.isNot(AsmToken::Identifier)) {
7788 return Error(Parser.getTok().getLoc(),
7789 "unexpected token, expected identifier");
7792 StringRef Option = Tok.getIdentifier();
7794 if (Option == "pic0") {
7795 // MipsAsmParser needs to know if the current PIC mode changes.
7796 IsPicEnabled = false;
7798 getTargetStreamer().emitDirectiveOptionPic0();
7800 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7801 return Error(Parser.getTok().getLoc(),
7802 "unexpected token, expected end of statement");
7807 if (Option == "pic2") {
7808 // MipsAsmParser needs to know if the current PIC mode changes.
7809 IsPicEnabled = true;
7811 getTargetStreamer().emitDirectiveOptionPic2();
7813 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7814 return Error(Parser.getTok().getLoc(),
7815 "unexpected token, expected end of statement");
7821 Warning(Parser.getTok().getLoc(),
7822 "unknown option, expected 'pic0' or 'pic2'");
7823 Parser.eatToEndOfStatement();
7827 /// parseInsnDirective
7829 bool MipsAsmParser::parseInsnDirective() {
7830 // If this is not the end of the statement, report an error.
7831 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7832 reportParseError("unexpected token, expected end of statement");
7836 // The actual label marking happens in
7837 // MipsELFStreamer::createPendingLabelRelocs().
7838 getTargetStreamer().emitDirectiveInsn();
7840 getParser().Lex(); // Eat EndOfStatement token.
7844 /// parseRSectionDirective
7846 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7847 // If this is not the end of the statement, report an error.
7848 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7849 reportParseError("unexpected token, expected end of statement");
7853 MCSection *ELFSection = getContext().getELFSection(
7854 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7855 getParser().getStreamer().SwitchSection(ELFSection);
7857 getParser().Lex(); // Eat EndOfStatement token.
7861 /// parseSSectionDirective
7864 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7865 // If this is not the end of the statement, report an error.
7866 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7867 reportParseError("unexpected token, expected end of statement");
7871 MCSection *ELFSection = getContext().getELFSection(
7872 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7873 getParser().getStreamer().SwitchSection(ELFSection);
7875 getParser().Lex(); // Eat EndOfStatement token.
7879 /// parseDirectiveModule
7880 /// ::= .module oddspreg
7881 /// ::= .module nooddspreg
7882 /// ::= .module fp=value
7883 /// ::= .module softfloat
7884 /// ::= .module hardfloat
7887 /// ::= .module nocrc
7888 /// ::= .module virt
7889 /// ::= .module novirt
7890 /// ::= .module ginv
7891 /// ::= .module noginv
7892 bool MipsAsmParser::parseDirectiveModule() {
7893 MCAsmParser &Parser = getParser();
7894 MCAsmLexer &Lexer = getLexer();
7895 SMLoc L = Lexer.getLoc();
7897 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7898 // TODO : get a better message.
7899 reportParseError(".module directive must appear before any code");
7904 if (Parser.parseIdentifier(Option)) {
7905 reportParseError("expected .module option identifier");
7909 if (Option == "oddspreg") {
7910 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7912 // Synchronize the abiflags information with the FeatureBits information we
7914 getTargetStreamer().updateABIInfo(*this);
7916 // If printing assembly, use the recently updated abiflags information.
7917 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7918 // emitted at the end).
7919 getTargetStreamer().emitDirectiveModuleOddSPReg();
7921 // If this is not the end of the statement, report an error.
7922 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7923 reportParseError("unexpected token, expected end of statement");
7927 return false; // parseDirectiveModule has finished successfully.
7928 } else if (Option == "nooddspreg") {
7930 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7933 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7935 // Synchronize the abiflags information with the FeatureBits information we
7937 getTargetStreamer().updateABIInfo(*this);
7939 // If printing assembly, use the recently updated abiflags information.
7940 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7941 // emitted at the end).
7942 getTargetStreamer().emitDirectiveModuleOddSPReg();
7944 // If this is not the end of the statement, report an error.
7945 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7946 reportParseError("unexpected token, expected end of statement");
7950 return false; // parseDirectiveModule has finished successfully.
7951 } else if (Option == "fp") {
7952 return parseDirectiveModuleFP();
7953 } else if (Option == "softfloat") {
7954 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7956 // Synchronize the ABI Flags information with the FeatureBits information we
7958 getTargetStreamer().updateABIInfo(*this);
7960 // If printing assembly, use the recently updated ABI Flags information.
7961 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7963 getTargetStreamer().emitDirectiveModuleSoftFloat();
7965 // If this is not the end of the statement, report an error.
7966 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7967 reportParseError("unexpected token, expected end of statement");
7971 return false; // parseDirectiveModule has finished successfully.
7972 } else if (Option == "hardfloat") {
7973 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7975 // Synchronize the ABI Flags information with the FeatureBits information we
7977 getTargetStreamer().updateABIInfo(*this);
7979 // If printing assembly, use the recently updated ABI Flags information.
7980 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7982 getTargetStreamer().emitDirectiveModuleHardFloat();
7984 // If this is not the end of the statement, report an error.
7985 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7986 reportParseError("unexpected token, expected end of statement");
7990 return false; // parseDirectiveModule has finished successfully.
7991 } else if (Option == "mt") {
7992 setModuleFeatureBits(Mips::FeatureMT, "mt");
7994 // Synchronize the ABI Flags information with the FeatureBits information we
7996 getTargetStreamer().updateABIInfo(*this);
7998 // If printing assembly, use the recently updated ABI Flags information.
7999 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8001 getTargetStreamer().emitDirectiveModuleMT();
8003 // If this is not the end of the statement, report an error.
8004 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8005 reportParseError("unexpected token, expected end of statement");
8009 return false; // parseDirectiveModule has finished successfully.
8010 } else if (Option == "crc") {
8011 setModuleFeatureBits(Mips::FeatureCRC, "crc");
8013 // Synchronize the ABI Flags information with the FeatureBits information we
8015 getTargetStreamer().updateABIInfo(*this);
8017 // If printing assembly, use the recently updated ABI Flags information.
8018 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8020 getTargetStreamer().emitDirectiveModuleCRC();
8022 // If this is not the end of the statement, report an error.
8023 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8024 reportParseError("unexpected token, expected end of statement");
8028 return false; // parseDirectiveModule has finished successfully.
8029 } else if (Option == "nocrc") {
8030 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8032 // Synchronize the ABI Flags information with the FeatureBits information we
8034 getTargetStreamer().updateABIInfo(*this);
8036 // If printing assembly, use the recently updated ABI Flags information.
8037 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8039 getTargetStreamer().emitDirectiveModuleNoCRC();
8041 // If this is not the end of the statement, report an error.
8042 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8043 reportParseError("unexpected token, expected end of statement");
8047 return false; // parseDirectiveModule has finished successfully.
8048 } else if (Option == "virt") {
8049 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8051 // Synchronize the ABI Flags information with the FeatureBits information we
8053 getTargetStreamer().updateABIInfo(*this);
8055 // If printing assembly, use the recently updated ABI Flags information.
8056 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8058 getTargetStreamer().emitDirectiveModuleVirt();
8060 // If this is not the end of the statement, report an error.
8061 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8062 reportParseError("unexpected token, expected end of statement");
8066 return false; // parseDirectiveModule has finished successfully.
8067 } else if (Option == "novirt") {
8068 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8070 // Synchronize the ABI Flags information with the FeatureBits information we
8072 getTargetStreamer().updateABIInfo(*this);
8074 // If printing assembly, use the recently updated ABI Flags information.
8075 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8077 getTargetStreamer().emitDirectiveModuleNoVirt();
8079 // If this is not the end of the statement, report an error.
8080 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8081 reportParseError("unexpected token, expected end of statement");
8085 return false; // parseDirectiveModule has finished successfully.
8086 } else if (Option == "ginv") {
8087 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8089 // Synchronize the ABI Flags information with the FeatureBits information we
8091 getTargetStreamer().updateABIInfo(*this);
8093 // If printing assembly, use the recently updated ABI Flags information.
8094 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8096 getTargetStreamer().emitDirectiveModuleGINV();
8098 // If this is not the end of the statement, report an error.
8099 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8100 reportParseError("unexpected token, expected end of statement");
8104 return false; // parseDirectiveModule has finished successfully.
8105 } else if (Option == "noginv") {
8106 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8108 // Synchronize the ABI Flags information with the FeatureBits information we
8110 getTargetStreamer().updateABIInfo(*this);
8112 // If printing assembly, use the recently updated ABI Flags information.
8113 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8115 getTargetStreamer().emitDirectiveModuleNoGINV();
8117 // If this is not the end of the statement, report an error.
8118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8119 reportParseError("unexpected token, expected end of statement");
8123 return false; // parseDirectiveModule has finished successfully.
8125 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8129 /// parseDirectiveModuleFP
8133 bool MipsAsmParser::parseDirectiveModuleFP() {
8134 MCAsmParser &Parser = getParser();
8135 MCAsmLexer &Lexer = getLexer();
8137 if (Lexer.isNot(AsmToken::Equal)) {
8138 reportParseError("unexpected token, expected equals sign '='");
8141 Parser.Lex(); // Eat '=' token.
8143 MipsABIFlagsSection::FpABIKind FpABI;
8144 if (!parseFpABIValue(FpABI, ".module"))
8147 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8148 reportParseError("unexpected token, expected end of statement");
8152 // Synchronize the abiflags information with the FeatureBits information we
8154 getTargetStreamer().updateABIInfo(*this);
8156 // If printing assembly, use the recently updated abiflags information.
8157 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8158 // emitted at the end).
8159 getTargetStreamer().emitDirectiveModuleFP();
8161 Parser.Lex(); // Consume the EndOfStatement.
8165 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8166 StringRef Directive) {
8167 MCAsmParser &Parser = getParser();
8168 MCAsmLexer &Lexer = getLexer();
8169 bool ModuleLevelOptions = Directive == ".module";
8171 if (Lexer.is(AsmToken::Identifier)) {
8172 StringRef Value = Parser.getTok().getString();
8175 if (Value != "xx") {
8176 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8181 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8185 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8186 if (ModuleLevelOptions) {
8187 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8188 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8190 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8191 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8196 if (Lexer.is(AsmToken::Integer)) {
8197 unsigned Value = Parser.getTok().getIntVal();
8200 if (Value != 32 && Value != 64) {
8201 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8207 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8211 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8212 if (ModuleLevelOptions) {
8213 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8214 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8216 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8217 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8220 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8221 if (ModuleLevelOptions) {
8222 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8223 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8225 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8226 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8236 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8237 // This returns false if this function recognizes the directive
8238 // regardless of whether it is successfully handles or reports an
8239 // error. Otherwise it returns true to give the generic parser a
8240 // chance at recognizing it.
8242 MCAsmParser &Parser = getParser();
8243 StringRef IDVal = DirectiveID.getString();
8245 if (IDVal == ".cpload") {
8246 parseDirectiveCpLoad(DirectiveID.getLoc());
8249 if (IDVal == ".cprestore") {
8250 parseDirectiveCpRestore(DirectiveID.getLoc());
8253 if (IDVal == ".cplocal") {
8254 parseDirectiveCpLocal(DirectiveID.getLoc());
8257 if (IDVal == ".ent") {
8258 StringRef SymbolName;
8260 if (Parser.parseIdentifier(SymbolName)) {
8261 reportParseError("expected identifier after .ent");
8265 // There's an undocumented extension that allows an integer to
8266 // follow the name of the procedure which AFAICS is ignored by GAS.
8267 // Example: .ent foo,2
8268 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8269 if (getLexer().isNot(AsmToken::Comma)) {
8270 // Even though we accept this undocumented extension for compatibility
8271 // reasons, the additional integer argument does not actually change
8272 // the behaviour of the '.ent' directive, so we would like to discourage
8273 // its use. We do this by not referring to the extended version in
8274 // error messages which are not directly related to its use.
8275 reportParseError("unexpected token, expected end of statement");
8278 Parser.Lex(); // Eat the comma.
8279 const MCExpr *DummyNumber;
8280 int64_t DummyNumberVal;
8281 // If the user was explicitly trying to use the extended version,
8282 // we still give helpful extension-related error messages.
8283 if (Parser.parseExpression(DummyNumber)) {
8284 reportParseError("expected number after comma");
8287 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8288 reportParseError("expected an absolute expression after comma");
8293 // If this is not the end of the statement, report an error.
8294 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8295 reportParseError("unexpected token, expected end of statement");
8299 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8301 getTargetStreamer().emitDirectiveEnt(*Sym);
8303 IsCpRestoreSet = false;
8307 if (IDVal == ".end") {
8308 StringRef SymbolName;
8310 if (Parser.parseIdentifier(SymbolName)) {
8311 reportParseError("expected identifier after .end");
8315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8316 reportParseError("unexpected token, expected end of statement");
8320 if (CurrentFn == nullptr) {
8321 reportParseError(".end used without .ent");
8325 if ((SymbolName != CurrentFn->getName())) {
8326 reportParseError(".end symbol does not match .ent symbol");
8330 getTargetStreamer().emitDirectiveEnd(SymbolName);
8331 CurrentFn = nullptr;
8332 IsCpRestoreSet = false;
8336 if (IDVal == ".frame") {
8337 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8338 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8339 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
8340 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8341 reportParseError("expected stack register");
8345 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8346 if (!StackRegOpnd.isGPRAsmReg()) {
8347 reportParseError(StackRegOpnd.getStartLoc(),
8348 "expected general purpose register");
8351 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8353 if (Parser.getTok().is(AsmToken::Comma))
8356 reportParseError("unexpected token, expected comma");
8360 // Parse the frame size.
8361 const MCExpr *FrameSize;
8362 int64_t FrameSizeVal;
8364 if (Parser.parseExpression(FrameSize)) {
8365 reportParseError("expected frame size value");
8369 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8370 reportParseError("frame size not an absolute expression");
8374 if (Parser.getTok().is(AsmToken::Comma))
8377 reportParseError("unexpected token, expected comma");
8381 // Parse the return register.
8383 ResTy = parseAnyRegister(TmpReg);
8384 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8385 reportParseError("expected return register");
8389 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8390 if (!ReturnRegOpnd.isGPRAsmReg()) {
8391 reportParseError(ReturnRegOpnd.getStartLoc(),
8392 "expected general purpose register");
8396 // If this is not the end of the statement, report an error.
8397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8398 reportParseError("unexpected token, expected end of statement");
8402 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8403 ReturnRegOpnd.getGPR32Reg());
8404 IsCpRestoreSet = false;
8408 if (IDVal == ".set") {
8409 parseDirectiveSet();
8413 if (IDVal == ".mask" || IDVal == ".fmask") {
8414 // .mask bitmask, frame_offset
8415 // bitmask: One bit for each register used.
8416 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8417 // first register is expected to be saved.
8419 // .mask 0x80000000, -4
8420 // .fmask 0x80000000, -4
8423 // Parse the bitmask
8424 const MCExpr *BitMask;
8427 if (Parser.parseExpression(BitMask)) {
8428 reportParseError("expected bitmask value");
8432 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8433 reportParseError("bitmask not an absolute expression");
8437 if (Parser.getTok().is(AsmToken::Comma))
8440 reportParseError("unexpected token, expected comma");
8444 // Parse the frame_offset
8445 const MCExpr *FrameOffset;
8446 int64_t FrameOffsetVal;
8448 if (Parser.parseExpression(FrameOffset)) {
8449 reportParseError("expected frame offset value");
8453 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8454 reportParseError("frame offset not an absolute expression");
8458 // If this is not the end of the statement, report an error.
8459 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8460 reportParseError("unexpected token, expected end of statement");
8464 if (IDVal == ".mask")
8465 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8467 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8471 if (IDVal == ".nan")
8472 return parseDirectiveNaN();
8474 if (IDVal == ".gpword") {
8475 parseDirectiveGpWord();
8479 if (IDVal == ".gpdword") {
8480 parseDirectiveGpDWord();
8484 if (IDVal == ".dtprelword") {
8485 parseDirectiveDtpRelWord();
8489 if (IDVal == ".dtpreldword") {
8490 parseDirectiveDtpRelDWord();
8494 if (IDVal == ".tprelword") {
8495 parseDirectiveTpRelWord();
8499 if (IDVal == ".tpreldword") {
8500 parseDirectiveTpRelDWord();
8504 if (IDVal == ".option") {
8505 parseDirectiveOption();
8509 if (IDVal == ".abicalls") {
8510 getTargetStreamer().emitDirectiveAbiCalls();
8511 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8512 Error(Parser.getTok().getLoc(),
8513 "unexpected token, expected end of statement");
8518 if (IDVal == ".cpsetup") {
8519 parseDirectiveCPSetup();
8522 if (IDVal == ".cpreturn") {
8523 parseDirectiveCPReturn();
8526 if (IDVal == ".module") {
8527 parseDirectiveModule();
8530 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8531 parseInternalDirectiveReallowModule();
8534 if (IDVal == ".insn") {
8535 parseInsnDirective();
8538 if (IDVal == ".rdata") {
8539 parseRSectionDirective(".rodata");
8542 if (IDVal == ".sbss") {
8543 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8546 if (IDVal == ".sdata") {
8547 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8554 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8555 // If this is not the end of the statement, report an error.
8556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8557 reportParseError("unexpected token, expected end of statement");
8561 getTargetStreamer().reallowModuleDirective();
8563 getParser().Lex(); // Eat EndOfStatement token.
8567 extern "C" void LLVMInitializeMipsAsmParser() {
8568 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8569 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8570 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8571 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8574 #define GET_REGISTER_MATCHER
8575 #define GET_MATCHER_IMPLEMENTATION
8576 #define GET_MNEMONIC_SPELL_CHECKER
8577 #include "MipsGenAsmMatcher.inc"
8579 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8580 // Find the appropriate table for this asm variant.
8581 const MatchEntry *Start, *End;
8582 switch (VariantID) {
8583 default: llvm_unreachable("invalid variant!");
8584 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8586 // Search the table.
8587 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8588 return MnemonicRange.first != MnemonicRange.second;