Bug Summary

File:lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Location:line 2843, column 31
Description:The left operand of '==' is a garbage value

Annotated Source Code

1//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/MipsABIInfo.h"
11#include "MCTargetDesc/MipsMCExpr.h"
12#include "MCTargetDesc/MipsMCTargetDesc.h"
13#include "MipsRegisterInfo.h"
14#include "MipsTargetObjectFile.h"
15#include "MipsTargetStreamer.h"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/StringSwitch.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCExpr.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstBuilder.h"
22#include "llvm/MC/MCParser/MCAsmLexer.h"
23#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24#include "llvm/MC/MCParser/MCTargetAsmParser.h"
25#include "llvm/MC/MCSectionELF.h"
26#include "llvm/MC/MCStreamer.h"
27#include "llvm/MC/MCSubtargetInfo.h"
28#include "llvm/MC/MCSymbol.h"
29#include "llvm/Support/Debug.h"
30#include "llvm/Support/ELF.h"
31#include "llvm/Support/MathExtras.h"
32#include "llvm/Support/SourceMgr.h"
33#include "llvm/Support/TargetRegistry.h"
34#include "llvm/Support/raw_ostream.h"
35#include <memory>
36
37using namespace llvm;
38
39#define DEBUG_TYPE"mips-asm-parser" "mips-asm-parser"
40
41namespace llvm {
42class MCInstrInfo;
43}
44
45namespace {
46class MipsAssemblerOptions {
47public:
48 MipsAssemblerOptions(const FeatureBitset &Features_) :
49 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50
51 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
52 ATReg = Opts->getATRegIndex();
53 Reorder = Opts->isReorder();
54 Macro = Opts->isMacro();
55 Features = Opts->getFeatures();
56 }
57
58 unsigned getATRegIndex() const { return ATReg; }
59 bool setATRegIndex(unsigned Reg) {
60 if (Reg > 31)
61 return false;
62
63 ATReg = Reg;
64 return true;
65 }
66
67 bool isReorder() const { return Reorder; }
68 void setReorder() { Reorder = true; }
69 void setNoReorder() { Reorder = false; }
70
71 bool isMacro() const { return Macro; }
72 void setMacro() { Macro = true; }
73 void setNoMacro() { Macro = false; }
74
75 const FeatureBitset &getFeatures() const { return Features; }
76 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77
78 // Set of features that are either architecture features or referenced
79 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
80 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
81 // The reason we need this mask is explained in the selectArch function.
82 // FIXME: Ideally we would like TableGen to generate this information.
83 static const FeatureBitset AllArchRelatedMask;
84
85private:
86 unsigned ATReg;
87 bool Reorder;
88 bool Macro;
89 FeatureBitset Features;
90};
91}
92
93const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
94 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
95 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
96 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
97 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
98 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
99 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
100 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
101 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
102};
103
104namespace {
105class MipsAsmParser : public MCTargetAsmParser {
106 MipsTargetStreamer &getTargetStreamer() {
107 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
108 return static_cast<MipsTargetStreamer &>(TS);
109 }
110
111 MipsABIInfo ABI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
116 // directive.
117 bool IsLittleEndian;
118 bool IsPicEnabled;
119 bool IsCpRestoreSet;
120 int CpRestoreOffset;
121 unsigned CpSaveLocation;
122 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123 bool CpSaveLocationIsRegister;
124
125 // Print a warning along with its fix-it message at the given range.
126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
127 SMRange Range, bool ShowColors = true);
128
129#define GET_ASSEMBLER_HEADER
130#include "MipsGenAsmMatcher.inc"
131
132 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
133
134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135 OperandVector &Operands, MCStreamer &Out,
136 uint64_t &ErrorInfo,
137 bool MatchingInlineAsm) override;
138
139 /// Parse a register as used in CFI directives
140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
141
142 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
143
144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
145
146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147 SMLoc NameLoc, OperandVector &Operands) override;
148
149 bool ParseDirective(AsmToken DirectiveID) override;
150
151 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
152 OperandMatchResultTy
153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154 StringRef Identifier, SMLoc S);
155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
156 SMLoc S);
157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158 OperandMatchResultTy parseImm(OperandVector &Operands);
159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
163 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
164 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
165
166 bool searchSymbolAlias(OperandVector &Operands);
167
168 bool parseOperand(OperandVector &, StringRef Mnemonic);
169
170 enum MacroExpanderResultTy {
171 MER_NotAMacro,
172 MER_Success,
173 MER_Fail,
174 };
175
176 // Expands assembly pseudo instructions.
177 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
178 MCStreamer &Out,
179 const MCSubtargetInfo *STI);
180
181 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
182 const MCSubtargetInfo *STI);
183
184 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
185 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
186 MCStreamer &Out, const MCSubtargetInfo *STI);
187
188 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
189 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
190 MCStreamer &Out, const MCSubtargetInfo *STI);
191
192 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 MCStreamer &Out, const MCSubtargetInfo *STI);
194
195 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
196 const MCOperand &Offset, bool Is32BitAddress,
197 SMLoc IDLoc, MCStreamer &Out,
198 const MCSubtargetInfo *STI);
199
200 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
201 const MCSubtargetInfo *STI);
202
203 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
204 const MCSubtargetInfo *STI, bool isLoad, bool isImmOpnd);
205
206 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
207 const MCSubtargetInfo *STI);
208
209 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
210 const MCSubtargetInfo *STI);
211
212 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
213 const MCSubtargetInfo *STI);
214
215 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
216 const MCSubtargetInfo *STI);
217
218 bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
219 const MCSubtargetInfo *STI, const bool IsMips64,
220 const bool Signed);
221
222 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
223 MCStreamer &Out, const MCSubtargetInfo *STI);
224
225 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
226 const MCSubtargetInfo *STI);
227
228 bool expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
229 const MCSubtargetInfo *STI);
230
231 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
232 MCStreamer &Out, const MCSubtargetInfo *STI);
233 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
234 const MCSubtargetInfo *STI);
235 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
236 const MCSubtargetInfo *STI);
237 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
238 const MCSubtargetInfo *STI);
239
240 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI);
242
243 void createNop(bool hasShortDelaySlot, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245
246 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
247 bool Is64Bit, MCStreamer &Out, const MCSubtargetInfo *STI);
248
249 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
250 MCStreamer &Out, const MCSubtargetInfo *STI);
251
252 bool reportParseError(Twine ErrorMsg);
253 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
254
255 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
256 bool parseRelocOperand(const MCExpr *&Res);
257
258 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
259
260 bool isEvaluated(const MCExpr *Expr);
261 bool parseSetMips0Directive();
262 bool parseSetArchDirective();
263 bool parseSetFeature(uint64_t Feature);
264 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
265 bool parseDirectiveCpLoad(SMLoc Loc);
266 bool parseDirectiveCpRestore(SMLoc Loc);
267 bool parseDirectiveCPSetup();
268 bool parseDirectiveCPReturn();
269 bool parseDirectiveNaN();
270 bool parseDirectiveSet();
271 bool parseDirectiveOption();
272 bool parseInsnDirective();
273 bool parseSSectionDirective(StringRef Section, unsigned Type);
274
275 bool parseSetAtDirective();
276 bool parseSetNoAtDirective();
277 bool parseSetMacroDirective();
278 bool parseSetNoMacroDirective();
279 bool parseSetMsaDirective();
280 bool parseSetNoMsaDirective();
281 bool parseSetNoDspDirective();
282 bool parseSetReorderDirective();
283 bool parseSetNoReorderDirective();
284 bool parseSetMips16Directive();
285 bool parseSetNoMips16Directive();
286 bool parseSetFpDirective();
287 bool parseSetOddSPRegDirective();
288 bool parseSetNoOddSPRegDirective();
289 bool parseSetPopDirective();
290 bool parseSetPushDirective();
291 bool parseSetSoftFloatDirective();
292 bool parseSetHardFloatDirective();
293
294 bool parseSetAssignment();
295
296 bool parseDataDirective(unsigned Size, SMLoc L);
297 bool parseDirectiveGpWord();
298 bool parseDirectiveGpDWord();
299 bool parseDirectiveModule();
300 bool parseDirectiveModuleFP();
301 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
302 StringRef Directive);
303
304 bool parseInternalDirectiveReallowModule();
305
306 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
307
308 bool eatComma(StringRef ErrorStr);
309
310 int matchCPURegisterName(StringRef Symbol);
311
312 int matchHWRegsRegisterName(StringRef Symbol);
313
314 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
315
316 int matchFPURegisterName(StringRef Name);
317
318 int matchFCCRegisterName(StringRef Name);
319
320 int matchACRegisterName(StringRef Name);
321
322 int matchMSA128RegisterName(StringRef Name);
323
324 int matchMSA128CtrlRegisterName(StringRef Name);
325
326 unsigned getReg(int RC, int RegNo);
327
328 unsigned getGPR(int RegNo);
329
330 /// Returns the internal register number for the current AT. Also checks if
331 /// the current AT is unavailable (set to $0) and gives an error if it is.
332 /// This should be used in pseudo-instruction expansions which need AT.
333 unsigned getATReg(SMLoc Loc);
334
335 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
336 const MCSubtargetInfo *STI);
337
338 // Helper function that checks if the value of a vector index is within the
339 // boundaries of accepted values for each RegisterKind
340 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
341 bool validateMSAIndex(int Val, int RegKind);
342
343 // Selects a new architecture by updating the FeatureBits with the necessary
344 // info including implied dependencies.
345 // Internally, it clears all the feature bits related to *any* architecture
346 // and selects the new one using the ToggleFeature functionality of the
347 // MCSubtargetInfo object that handles implied dependencies. The reason we
348 // clear all the arch related bits manually is because ToggleFeature only
349 // clears the features that imply the feature being cleared and not the
350 // features implied by the feature being cleared. This is easier to see
351 // with an example:
352 // --------------------------------------------------
353 // | Feature | Implies |
354 // | -------------------------------------------------|
355 // | FeatureMips1 | None |
356 // | FeatureMips2 | FeatureMips1 |
357 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
358 // | FeatureMips4 | FeatureMips3 |
359 // | ... | |
360 // --------------------------------------------------
361 //
362 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
363 // FeatureMipsGP64 | FeatureMips1)
364 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
365 void selectArch(StringRef ArchFeature) {
366 MCSubtargetInfo &STI = copySTI();
367 FeatureBitset FeatureBits = STI.getFeatureBits();
368 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
369 STI.setFeatureBits(FeatureBits);
370 setAvailableFeatures(
371 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
372 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
373 }
374
375 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
376 if (!(getSTI().getFeatureBits()[Feature])) {
377 MCSubtargetInfo &STI = copySTI();
378 setAvailableFeatures(
379 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
380 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
381 }
382 }
383
384 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
385 if (getSTI().getFeatureBits()[Feature]) {
386 MCSubtargetInfo &STI = copySTI();
387 setAvailableFeatures(
388 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
389 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
390 }
391 }
392
393 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
394 setFeatureBits(Feature, FeatureString);
395 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
396 }
397
398 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
399 clearFeatureBits(Feature, FeatureString);
400 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
401 }
402
403public:
404 enum MipsMatchResultTy {
405 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
406#define GET_OPERAND_DIAGNOSTIC_TYPES
407#include "MipsGenAsmMatcher.inc"
408#undef GET_OPERAND_DIAGNOSTIC_TYPES
409 };
410
411 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
412 const MCInstrInfo &MII, const MCTargetOptions &Options)
413 : MCTargetAsmParser(Options, sti),
414 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
415 sti.getCPU(), Options)) {
416 MCAsmParserExtension::Initialize(parser);
417
418 parser.addAliasForDirective(".asciiz", ".asciz");
419
420 // Initialize the set of available features.
421 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
422
423 // Remember the initial assembler options. The user can not modify these.
424 AssemblerOptions.push_back(
425 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
426
427 // Create an assembler options environment for the user to modify.
428 AssemblerOptions.push_back(
429 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
430
431 getTargetStreamer().updateABIInfo(*this);
432
433 if (!isABI_O32() && !useOddSPReg() != 0)
434 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
435
436 CurrentFn = nullptr;
437
438 IsPicEnabled =
439 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
440
441 IsCpRestoreSet = false;
442 CpRestoreOffset = -1;
443
444 Triple TheTriple(sti.getTargetTriple());
445 if ((TheTriple.getArch() == Triple::mips) ||
446 (TheTriple.getArch() == Triple::mips64))
447 IsLittleEndian = false;
448 else
449 IsLittleEndian = true;
450 }
451
452 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
453 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
454
455 bool isGP64bit() const {
456 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
457 }
458 bool isFP64bit() const {
459 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
460 }
461 const MipsABIInfo &getABI() const { return ABI; }
462 bool isABI_N32() const { return ABI.IsN32(); }
463 bool isABI_N64() const { return ABI.IsN64(); }
464 bool isABI_O32() const { return ABI.IsO32(); }
465 bool isABI_FPXX() const {
466 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
467 }
468
469 bool useOddSPReg() const {
470 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
471 }
472
473 bool inMicroMipsMode() const {
474 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
475 }
476 bool hasMips1() const {
477 return getSTI().getFeatureBits()[Mips::FeatureMips1];
478 }
479 bool hasMips2() const {
480 return getSTI().getFeatureBits()[Mips::FeatureMips2];
481 }
482 bool hasMips3() const {
483 return getSTI().getFeatureBits()[Mips::FeatureMips3];
484 }
485 bool hasMips4() const {
486 return getSTI().getFeatureBits()[Mips::FeatureMips4];
487 }
488 bool hasMips5() const {
489 return getSTI().getFeatureBits()[Mips::FeatureMips5];
490 }
491 bool hasMips32() const {
492 return getSTI().getFeatureBits()[Mips::FeatureMips32];
493 }
494 bool hasMips64() const {
495 return getSTI().getFeatureBits()[Mips::FeatureMips64];
496 }
497 bool hasMips32r2() const {
498 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
499 }
500 bool hasMips64r2() const {
501 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
502 }
503 bool hasMips32r3() const {
504 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
505 }
506 bool hasMips64r3() const {
507 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
508 }
509 bool hasMips32r5() const {
510 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
511 }
512 bool hasMips64r5() const {
513 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
514 }
515 bool hasMips32r6() const {
516 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
517 }
518 bool hasMips64r6() const {
519 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
520 }
521
522 bool hasDSP() const {
523 return getSTI().getFeatureBits()[Mips::FeatureDSP];
524 }
525 bool hasDSPR2() const {
526 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
527 }
528 bool hasDSPR3() const {
529 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
530 }
531 bool hasMSA() const {
532 return getSTI().getFeatureBits()[Mips::FeatureMSA];
533 }
534 bool hasCnMips() const {
535 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
536 }
537
538 bool inPicMode() {
539 return IsPicEnabled;
540 }
541
542 bool inMips16Mode() const {
543 return getSTI().getFeatureBits()[Mips::FeatureMips16];
544 }
545
546 bool useTraps() const {
547 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
548 }
549
550 bool useSoftFloat() const {
551 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
552 }
553
554 /// Warn if RegIndex is the same as the current AT.
555 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
556
557 void warnIfNoMacro(SMLoc Loc);
558
559 bool isLittle() const { return IsLittleEndian; }
560};
561}
562
563namespace {
564
565/// MipsOperand - Instances of this class represent a parsed Mips machine
566/// instruction.
567class MipsOperand : public MCParsedAsmOperand {
568public:
569 /// Broad categories of register classes
570 /// The exact class is finalized by the render method.
571 enum RegKind {
572 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
573 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
574 /// isFP64bit())
575 RegKind_FCC = 4, /// FCC
576 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
577 RegKind_MSACtrl = 16, /// MSA control registers
578 RegKind_COP2 = 32, /// COP2
579 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
580 /// context).
581 RegKind_CCR = 128, /// CCR
582 RegKind_HWRegs = 256, /// HWRegs
583 RegKind_COP3 = 512, /// COP3
584 RegKind_COP0 = 1024, /// COP0
585 /// Potentially any (e.g. $1)
586 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
587 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
588 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
589 };
590
591private:
592 enum KindTy {
593 k_Immediate, /// An immediate (possibly involving symbol references)
594 k_Memory, /// Base + Offset Memory Address
595 k_PhysRegister, /// A physical register from the Mips namespace
596 k_RegisterIndex, /// A register index in one or more RegKind.
597 k_Token, /// A simple token
598 k_RegList, /// A physical register list
599 k_RegPair /// A pair of physical register
600 } Kind;
601
602public:
603 MipsOperand(KindTy K, MipsAsmParser &Parser)
604 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
605
606private:
607 /// For diagnostics, and checking the assembler temporary
608 MipsAsmParser &AsmParser;
609
610 struct Token {
611 const char *Data;
612 unsigned Length;
613 };
614
615 struct PhysRegOp {
616 unsigned Num; /// Register Number
617 };
618
619 struct RegIdxOp {
620 unsigned Index; /// Index into the register class
621 RegKind Kind; /// Bitfield of the kinds it could possibly be
622 const MCRegisterInfo *RegInfo;
623 };
624
625 struct ImmOp {
626 const MCExpr *Val;
627 };
628
629 struct MemOp {
630 MipsOperand *Base;
631 const MCExpr *Off;
632 };
633
634 struct RegListOp {
635 SmallVector<unsigned, 10> *List;
636 };
637
638 union {
639 struct Token Tok;
640 struct PhysRegOp PhysReg;
641 struct RegIdxOp RegIdx;
642 struct ImmOp Imm;
643 struct MemOp Mem;
644 struct RegListOp RegList;
645 };
646
647 SMLoc StartLoc, EndLoc;
648
649 /// Internal constructor for register kinds
650 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
651 const MCRegisterInfo *RegInfo,
652 SMLoc S, SMLoc E,
653 MipsAsmParser &Parser) {
654 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
655 Op->RegIdx.Index = Index;
656 Op->RegIdx.RegInfo = RegInfo;
657 Op->RegIdx.Kind = RegKind;
658 Op->StartLoc = S;
659 Op->EndLoc = E;
660 return Op;
661 }
662
663public:
664 /// Coerce the register to GPR32 and return the real register for the current
665 /// target.
666 unsigned getGPR32Reg() const {
667 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 667, __PRETTY_FUNCTION__))
;
668 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
669 unsigned ClassID = Mips::GPR32RegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
671 }
672
673 /// Coerce the register to GPR32 and return the real register for the current
674 /// target.
675 unsigned getGPRMM16Reg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 676, __PRETTY_FUNCTION__))
;
677 unsigned ClassID = Mips::GPR32RegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
679 }
680
681 /// Coerce the register to GPR64 and return the real register for the current
682 /// target.
683 unsigned getGPR64Reg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 684, __PRETTY_FUNCTION__))
;
685 unsigned ClassID = Mips::GPR64RegClassID;
686 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
687 }
688
689private:
690 /// Coerce the register to AFGR64 and return the real register for the current
691 /// target.
692 unsigned getAFGR64Reg() const {
693 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 693, __PRETTY_FUNCTION__))
;
694 if (RegIdx.Index % 2 != 0)
695 AsmParser.Warning(StartLoc, "Float register should be even.");
696 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
697 .getRegister(RegIdx.Index / 2);
698 }
699
700 /// Coerce the register to FGR64 and return the real register for the current
701 /// target.
702 unsigned getFGR64Reg() const {
703 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 703, __PRETTY_FUNCTION__))
;
704 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
705 .getRegister(RegIdx.Index);
706 }
707
708 /// Coerce the register to FGR32 and return the real register for the current
709 /// target.
710 unsigned getFGR32Reg() const {
711 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 711, __PRETTY_FUNCTION__))
;
712 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
713 .getRegister(RegIdx.Index);
714 }
715
716 /// Coerce the register to FGRH32 and return the real register for the current
717 /// target.
718 unsigned getFGRH32Reg() const {
719 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 719, __PRETTY_FUNCTION__))
;
720 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
721 .getRegister(RegIdx.Index);
722 }
723
724 /// Coerce the register to FCC and return the real register for the current
725 /// target.
726 unsigned getFCCReg() const {
727 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FCC) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 727, __PRETTY_FUNCTION__))
;
728 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
729 .getRegister(RegIdx.Index);
730 }
731
732 /// Coerce the register to MSA128 and return the real register for the current
733 /// target.
734 unsigned getMSA128Reg() const {
735 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 735, __PRETTY_FUNCTION__))
;
736 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
737 // identical
738 unsigned ClassID = Mips::MSA128BRegClassID;
739 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
740 }
741
742 /// Coerce the register to MSACtrl and return the real register for the
743 /// current target.
744 unsigned getMSACtrlReg() const {
745 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 745, __PRETTY_FUNCTION__))
;
746 unsigned ClassID = Mips::MSACtrlRegClassID;
747 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
748 }
749
750 /// Coerce the register to COP0 and return the real register for the
751 /// current target.
752 unsigned getCOP0Reg() const {
753 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP0) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 753, __PRETTY_FUNCTION__))
;
754 unsigned ClassID = Mips::COP0RegClassID;
755 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
756 }
757
758 /// Coerce the register to COP2 and return the real register for the
759 /// current target.
760 unsigned getCOP2Reg() const {
761 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP2) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 761, __PRETTY_FUNCTION__))
;
762 unsigned ClassID = Mips::COP2RegClassID;
763 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
764 }
765
766 /// Coerce the register to COP3 and return the real register for the
767 /// current target.
768 unsigned getCOP3Reg() const {
769 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP3) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 769, __PRETTY_FUNCTION__))
;
770 unsigned ClassID = Mips::COP3RegClassID;
771 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
772 }
773
774 /// Coerce the register to ACC64DSP and return the real register for the
775 /// current target.
776 unsigned getACC64DSPReg() const {
777 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 777, __PRETTY_FUNCTION__))
;
778 unsigned ClassID = Mips::ACC64DSPRegClassID;
779 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
780 }
781
782 /// Coerce the register to HI32DSP and return the real register for the
783 /// current target.
784 unsigned getHI32DSPReg() const {
785 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 785, __PRETTY_FUNCTION__))
;
786 unsigned ClassID = Mips::HI32DSPRegClassID;
787 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
788 }
789
790 /// Coerce the register to LO32DSP and return the real register for the
791 /// current target.
792 unsigned getLO32DSPReg() const {
793 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 793, __PRETTY_FUNCTION__))
;
794 unsigned ClassID = Mips::LO32DSPRegClassID;
795 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
796 }
797
798 /// Coerce the register to CCR and return the real register for the
799 /// current target.
800 unsigned getCCRReg() const {
801 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_CCR) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 801, __PRETTY_FUNCTION__))
;
802 unsigned ClassID = Mips::CCRRegClassID;
803 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
804 }
805
806 /// Coerce the register to HWRegs and return the real register for the
807 /// current target.
808 unsigned getHWRegsReg() const {
809 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 809, __PRETTY_FUNCTION__))
;
810 unsigned ClassID = Mips::HWRegsRegClassID;
811 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
812 }
813
814public:
815 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
816 // Add as immediate when possible. Null MCExpr = 0.
817 if (!Expr)
818 Inst.addOperand(MCOperand::createImm(0));
819 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
820 Inst.addOperand(MCOperand::createImm(CE->getValue()));
821 else
822 Inst.addOperand(MCOperand::createExpr(Expr));
823 }
824
825 void addRegOperands(MCInst &Inst, unsigned N) const {
826 llvm_unreachable("Use a custom parser instead")::llvm::llvm_unreachable_internal("Use a custom parser instead"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 826)
;
827 }
828
829 /// Render the operand to an MCInst as a GPR32
830 /// Asserts if the wrong number of operands are requested, or the operand
831 /// is not a k_RegisterIndex compatible with RegKind_GPR
832 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 833, __PRETTY_FUNCTION__))
;
834 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
835 }
836
837 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 838, __PRETTY_FUNCTION__))
;
839 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
840 }
841
842 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 843, __PRETTY_FUNCTION__))
;
844 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
845 }
846
847 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 848, __PRETTY_FUNCTION__))
;
849 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
850 }
851
852 /// Render the operand to an MCInst as a GPR64
853 /// Asserts if the wrong number of operands are requested, or the operand
854 /// is not a k_RegisterIndex compatible with RegKind_GPR
855 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 856, __PRETTY_FUNCTION__))
;
857 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
858 }
859
860 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
861 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 861, __PRETTY_FUNCTION__))
;
862 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
863 }
864
865 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
866 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 866, __PRETTY_FUNCTION__))
;
867 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
868 }
869
870 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
871 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 871, __PRETTY_FUNCTION__))
;
872 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
873 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
874 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
875 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
876 "registers");
877 }
878
879 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
880 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 880, __PRETTY_FUNCTION__))
;
881 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
882 }
883
884 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
885 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 885, __PRETTY_FUNCTION__))
;
886 Inst.addOperand(MCOperand::createReg(getFCCReg()));
887 }
888
889 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
890 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 890, __PRETTY_FUNCTION__))
;
891 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
892 }
893
894 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
895 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 895, __PRETTY_FUNCTION__))
;
896 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
897 }
898
899 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
900 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 900, __PRETTY_FUNCTION__))
;
901 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
902 }
903
904 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
905 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 905, __PRETTY_FUNCTION__))
;
906 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
907 }
908
909 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
910 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 910, __PRETTY_FUNCTION__))
;
911 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
912 }
913
914 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
915 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 915, __PRETTY_FUNCTION__))
;
916 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
917 }
918
919 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
920 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 920, __PRETTY_FUNCTION__))
;
921 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
922 }
923
924 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
925 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 925, __PRETTY_FUNCTION__))
;
926 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
927 }
928
929 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
930 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 930, __PRETTY_FUNCTION__))
;
931 Inst.addOperand(MCOperand::createReg(getCCRReg()));
932 }
933
934 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
935 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 935, __PRETTY_FUNCTION__))
;
936 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
937 }
938
939 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
940 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
941 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 941, __PRETTY_FUNCTION__))
;
942 uint64_t Imm = getConstantImm() - Offset;
943 Imm &= (1 << Bits) - 1;
944 Imm += Offset;
945 Imm += AdjustOffset;
946 Inst.addOperand(MCOperand::createImm(Imm));
947 }
948
949 template <unsigned Bits>
950 void addSImmOperands(MCInst &Inst, unsigned N) const {
951 if (isImm() && !isConstantImm()) {
952 addExpr(Inst, getImm());
953 return;
954 }
955 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
956 }
957
958 template <unsigned Bits>
959 void addUImmOperands(MCInst &Inst, unsigned N) const {
960 if (isImm() && !isConstantImm()) {
961 addExpr(Inst, getImm());
962 return;
963 }
964 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
965 }
966
967 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
968 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
969 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 969, __PRETTY_FUNCTION__))
;
970 int64_t Imm = getConstantImm() - Offset;
971 Imm = SignExtend64<Bits>(Imm);
972 Imm += Offset;
973 Imm += AdjustOffset;
974 Inst.addOperand(MCOperand::createImm(Imm));
975 }
976
977 void addImmOperands(MCInst &Inst, unsigned N) const {
978 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 978, __PRETTY_FUNCTION__))
;
979 const MCExpr *Expr = getImm();
980 addExpr(Inst, Expr);
981 }
982
983 void addMemOperands(MCInst &Inst, unsigned N) const {
984 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 984, __PRETTY_FUNCTION__))
;
985
986 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
987 ? getMemBase()->getGPR64Reg()
988 : getMemBase()->getGPR32Reg()));
989
990 const MCExpr *Expr = getMemOff();
991 addExpr(Inst, Expr);
992 }
993
994 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
995 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 995, __PRETTY_FUNCTION__))
;
996
997 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
998
999 const MCExpr *Expr = getMemOff();
1000 addExpr(Inst, Expr);
1001 }
1002
1003 void addRegListOperands(MCInst &Inst, unsigned N) const {
1004 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1004, __PRETTY_FUNCTION__))
;
1005
1006 for (auto RegNo : getRegList())
1007 Inst.addOperand(MCOperand::createReg(RegNo));
1008 }
1009
1010 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1011 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1011, __PRETTY_FUNCTION__))
;
1012 unsigned RegNo = getRegPair();
1013 Inst.addOperand(MCOperand::createReg(RegNo++));
1014 Inst.addOperand(MCOperand::createReg(RegNo));
1015 }
1016
1017 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1018 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1018, __PRETTY_FUNCTION__))
;
1019 for (auto RegNo : getRegList())
1020 Inst.addOperand(MCOperand::createReg(RegNo));
1021 }
1022
1023 bool isReg() const override {
1024 // As a special case until we sort out the definition of div/divu, pretend
1025 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1026 if (isGPRAsmReg() && RegIdx.Index == 0)
1027 return true;
1028
1029 return Kind == k_PhysRegister;
1030 }
1031 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1032 bool isImm() const override { return Kind == k_Immediate; }
1033 bool isConstantImm() const {
1034 return isImm() && isa<MCConstantExpr>(getImm());
1035 }
1036 bool isConstantImmz() const {
1037 return isConstantImm() && getConstantImm() == 0;
1038 }
1039 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1040 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1041 }
1042 template <unsigned Bits> bool isSImm() const {
1043 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1044 }
1045 template <unsigned Bits> bool isUImm() const {
1046 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1047 }
1048 template <unsigned Bits> bool isAnyImm() const {
1049 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1050 isUInt<Bits>(getConstantImm()))
1051 : isImm();
1052 }
1053 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1054 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1055 }
1056 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1057 return isConstantImm() && getConstantImm() >= Bottom &&
1058 getConstantImm() <= Top;
1059 }
1060 bool isToken() const override {
1061 // Note: It's not possible to pretend that other operand kinds are tokens.
1062 // The matcher emitter checks tokens first.
1063 return Kind == k_Token;
1064 }
1065 bool isMem() const override { return Kind == k_Memory; }
1066 bool isConstantMemOff() const {
1067 return isMem() && isa<MCConstantExpr>(getMemOff());
1068 }
1069 template <unsigned Bits, unsigned ShiftAmount = 0>
1070 bool isMemWithSimmOffset() const {
1071 return isMem() && isConstantMemOff() &&
1072 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff()) &&
1073 getMemBase()->isGPRAsmReg();
1074 }
1075 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
1076 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
1077 getMemBase()->isGPRAsmReg();
1078 }
1079 bool isMemWithGRPMM16Base() const {
1080 return isMem() && getMemBase()->isMM16AsmReg();
1081 }
1082 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1083 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1084 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1085 }
1086 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1087 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1088 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1089 && (getMemBase()->getGPR32Reg() == Mips::SP);
1090 }
1091 template <unsigned Bits, unsigned ShiftLeftAmount>
1092 bool isScaledUImm() const {
1093 return isConstantImm() &&
1094 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1095 }
1096 template <unsigned Bits, unsigned ShiftLeftAmount>
1097 bool isScaledSImm() const {
1098 return isConstantImm() &&
1099 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm());
1100 }
1101 bool isRegList16() const {
1102 if (!isRegList())
1103 return false;
1104
1105 int Size = RegList.List->size();
1106 if (Size < 2 || Size > 5)
1107 return false;
1108
1109 unsigned R0 = RegList.List->front();
1110 unsigned R1 = RegList.List->back();
1111 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1112 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1113 return false;
1114
1115 int PrevReg = *RegList.List->begin();
1116 for (int i = 1; i < Size - 1; i++) {
1117 int Reg = (*(RegList.List))[i];
1118 if ( Reg != PrevReg + 1)
1119 return false;
1120 PrevReg = Reg;
1121 }
1122
1123 return true;
1124 }
1125 bool isInvNum() const { return Kind == k_Immediate; }
1126 bool isLSAImm() const {
1127 if (!isConstantImm())
1128 return false;
1129 int64_t Val = getConstantImm();
1130 return 1 <= Val && Val <= 4;
1131 }
1132 bool isRegList() const { return Kind == k_RegList; }
1133 bool isMovePRegPair() const {
1134 if (Kind != k_RegList || RegList.List->size() != 2)
1135 return false;
1136
1137 unsigned R0 = RegList.List->front();
1138 unsigned R1 = RegList.List->back();
1139
1140 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1141 (R0 == Mips::A1 && R1 == Mips::A3) ||
1142 (R0 == Mips::A2 && R1 == Mips::A3) ||
1143 (R0 == Mips::A0 && R1 == Mips::S5) ||
1144 (R0 == Mips::A0 && R1 == Mips::S6) ||
1145 (R0 == Mips::A0 && R1 == Mips::A1) ||
1146 (R0 == Mips::A0 && R1 == Mips::A2) ||
1147 (R0 == Mips::A0 && R1 == Mips::A3) ||
1148 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1149 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1150 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1151 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1152 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1153 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1154 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1155 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1156 return true;
1157
1158 return false;
1159 }
1160
1161 StringRef getToken() const {
1162 assert(Kind == k_Token && "Invalid access!")((Kind == k_Token && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Token && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1162, __PRETTY_FUNCTION__))
;
1163 return StringRef(Tok.Data, Tok.Length);
1164 }
1165 bool isRegPair() const { return Kind == k_RegPair; }
1166
1167 unsigned getReg() const override {
1168 // As a special case until we sort out the definition of div/divu, pretend
1169 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1170 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1171 RegIdx.Kind & RegKind_GPR)
1172 return getGPR32Reg(); // FIXME: GPR64 too
1173
1174 assert(Kind == k_PhysRegister && "Invalid access!")((Kind == k_PhysRegister && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_PhysRegister && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1174, __PRETTY_FUNCTION__))
;
1175 return PhysReg.Num;
1176 }
1177
1178 const MCExpr *getImm() const {
1179 assert((Kind == k_Immediate) && "Invalid access!")(((Kind == k_Immediate) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Immediate) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1179, __PRETTY_FUNCTION__))
;
1180 return Imm.Val;
1181 }
1182
1183 int64_t getConstantImm() const {
1184 const MCExpr *Val = getImm();
1185 return static_cast<const MCConstantExpr *>(Val)->getValue();
1186 }
1187
1188 MipsOperand *getMemBase() const {
1189 assert((Kind == k_Memory) && "Invalid access!")(((Kind == k_Memory) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Memory) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1189, __PRETTY_FUNCTION__))
;
1190 return Mem.Base;
1191 }
1192
1193 const MCExpr *getMemOff() const {
1194 assert((Kind == k_Memory) && "Invalid access!")(((Kind == k_Memory) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Memory) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1194, __PRETTY_FUNCTION__))
;
1195 return Mem.Off;
1196 }
1197
1198 int64_t getConstantMemOff() const {
1199 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1200 }
1201
1202 const SmallVectorImpl<unsigned> &getRegList() const {
1203 assert((Kind == k_RegList) && "Invalid access!")(((Kind == k_RegList) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_RegList) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1203, __PRETTY_FUNCTION__))
;
1204 return *(RegList.List);
1205 }
1206
1207 unsigned getRegPair() const {
1208 assert((Kind == k_RegPair) && "Invalid access!")(((Kind == k_RegPair) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_RegPair) && \"Invalid access!\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1208, __PRETTY_FUNCTION__))
;
1209 return RegIdx.Index;
1210 }
1211
1212 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1213 MipsAsmParser &Parser) {
1214 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1215 Op->Tok.Data = Str.data();
1216 Op->Tok.Length = Str.size();
1217 Op->StartLoc = S;
1218 Op->EndLoc = S;
1219 return Op;
1220 }
1221
1222 /// Create a numeric register (e.g. $1). The exact register remains
1223 /// unresolved until an instruction successfully matches
1224 static std::unique_ptr<MipsOperand>
1225 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1226 SMLoc E, MipsAsmParser &Parser) {
1227 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "createNumericReg(" <<
Index << ", ...)\n"; } } while (0)
;
1228 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1229 }
1230
1231 /// Create a register that is definitely a GPR.
1232 /// This is typically only used for named registers such as $gp.
1233 static std::unique_ptr<MipsOperand>
1234 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1235 MipsAsmParser &Parser) {
1236 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1237 }
1238
1239 /// Create a register that is definitely a FGR.
1240 /// This is typically only used for named registers such as $f0.
1241 static std::unique_ptr<MipsOperand>
1242 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1243 MipsAsmParser &Parser) {
1244 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1245 }
1246
1247 /// Create a register that is definitely a HWReg.
1248 /// This is typically only used for named registers such as $hwr_cpunum.
1249 static std::unique_ptr<MipsOperand>
1250 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1251 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1252 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1253 }
1254
1255 /// Create a register that is definitely an FCC.
1256 /// This is typically only used for named registers such as $fcc0.
1257 static std::unique_ptr<MipsOperand>
1258 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1259 MipsAsmParser &Parser) {
1260 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1261 }
1262
1263 /// Create a register that is definitely an ACC.
1264 /// This is typically only used for named registers such as $ac0.
1265 static std::unique_ptr<MipsOperand>
1266 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1267 MipsAsmParser &Parser) {
1268 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1269 }
1270
1271 /// Create a register that is definitely an MSA128.
1272 /// This is typically only used for named registers such as $w0.
1273 static std::unique_ptr<MipsOperand>
1274 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1275 SMLoc E, MipsAsmParser &Parser) {
1276 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1277 }
1278
1279 /// Create a register that is definitely an MSACtrl.
1280 /// This is typically only used for named registers such as $msaaccess.
1281 static std::unique_ptr<MipsOperand>
1282 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1283 SMLoc E, MipsAsmParser &Parser) {
1284 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1285 }
1286
1287 static std::unique_ptr<MipsOperand>
1288 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1289 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1290 Op->Imm.Val = Val;
1291 Op->StartLoc = S;
1292 Op->EndLoc = E;
1293 return Op;
1294 }
1295
1296 static std::unique_ptr<MipsOperand>
1297 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1298 SMLoc E, MipsAsmParser &Parser) {
1299 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1300 Op->Mem.Base = Base.release();
1301 Op->Mem.Off = Off;
1302 Op->StartLoc = S;
1303 Op->EndLoc = E;
1304 return Op;
1305 }
1306
1307 static std::unique_ptr<MipsOperand>
1308 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1309 MipsAsmParser &Parser) {
1310 assert (Regs.size() > 0 && "Empty list not allowed")((Regs.size() > 0 && "Empty list not allowed") ? static_cast
<void> (0) : __assert_fail ("Regs.size() > 0 && \"Empty list not allowed\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1310, __PRETTY_FUNCTION__))
;
1311
1312 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1313 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1314 Op->StartLoc = StartLoc;
1315 Op->EndLoc = EndLoc;
1316 return Op;
1317 }
1318
1319 static std::unique_ptr<MipsOperand>
1320 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1321 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1322 Op->RegIdx.Index = RegNo;
1323 Op->StartLoc = S;
1324 Op->EndLoc = E;
1325 return Op;
1326 }
1327
1328 bool isGPRAsmReg() const {
1329 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1330 }
1331 bool isMM16AsmReg() const {
1332 if (!(isRegIdx() && RegIdx.Kind))
1333 return false;
1334 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1335 || RegIdx.Index == 16 || RegIdx.Index == 17);
1336 }
1337 bool isMM16AsmRegZero() const {
1338 if (!(isRegIdx() && RegIdx.Kind))
1339 return false;
1340 return (RegIdx.Index == 0 ||
1341 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1342 RegIdx.Index == 17);
1343 }
1344 bool isMM16AsmRegMoveP() const {
1345 if (!(isRegIdx() && RegIdx.Kind))
1346 return false;
1347 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1348 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1349 }
1350 bool isFGRAsmReg() const {
1351 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1352 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1353 }
1354 bool isHWRegsAsmReg() const {
1355 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1356 }
1357 bool isCCRAsmReg() const {
1358 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1359 }
1360 bool isFCCAsmReg() const {
1361 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1362 return false;
1363 if (!AsmParser.hasEightFccRegisters())
1364 return RegIdx.Index == 0;
1365 return RegIdx.Index <= 7;
1366 }
1367 bool isACCAsmReg() const {
1368 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1369 }
1370 bool isCOP0AsmReg() const {
1371 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1372 }
1373 bool isCOP2AsmReg() const {
1374 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1375 }
1376 bool isCOP3AsmReg() const {
1377 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1378 }
1379 bool isMSA128AsmReg() const {
1380 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1381 }
1382 bool isMSACtrlAsmReg() const {
1383 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1384 }
1385
1386 /// getStartLoc - Get the location of the first token of this operand.
1387 SMLoc getStartLoc() const override { return StartLoc; }
1388 /// getEndLoc - Get the location of the last token of this operand.
1389 SMLoc getEndLoc() const override { return EndLoc; }
1390
1391 virtual ~MipsOperand() {
1392 switch (Kind) {
1393 case k_Immediate:
1394 break;
1395 case k_Memory:
1396 delete Mem.Base;
1397 break;
1398 case k_RegList:
1399 delete RegList.List;
1400 case k_PhysRegister:
1401 case k_RegisterIndex:
1402 case k_Token:
1403 case k_RegPair:
1404 break;
1405 }
1406 }
1407
1408 void print(raw_ostream &OS) const override {
1409 switch (Kind) {
1410 case k_Immediate:
1411 OS << "Imm<";
1412 OS << *Imm.Val;
1413 OS << ">";
1414 break;
1415 case k_Memory:
1416 OS << "Mem<";
1417 Mem.Base->print(OS);
1418 OS << ", ";
1419 OS << *Mem.Off;
1420 OS << ">";
1421 break;
1422 case k_PhysRegister:
1423 OS << "PhysReg<" << PhysReg.Num << ">";
1424 break;
1425 case k_RegisterIndex:
1426 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1427 break;
1428 case k_Token:
1429 OS << Tok.Data;
1430 break;
1431 case k_RegList:
1432 OS << "RegList< ";
1433 for (auto Reg : (*RegList.List))
1434 OS << Reg << " ";
1435 OS << ">";
1436 break;
1437 case k_RegPair:
1438 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1439 break;
1440 }
1441 }
1442}; // class MipsOperand
1443} // namespace
1444
1445namespace llvm {
1446extern const MCInstrDesc MipsInsts[];
1447}
1448static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1449 return MipsInsts[Opcode];
1450}
1451
1452static bool hasShortDelaySlot(unsigned Opcode) {
1453 switch (Opcode) {
1454 case Mips::JALS_MM:
1455 case Mips::JALRS_MM:
1456 case Mips::JALRS16_MM:
1457 case Mips::BGEZALS_MM:
1458 case Mips::BLTZALS_MM:
1459 return true;
1460 default:
1461 return false;
1462 }
1463}
1464
1465static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1466 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1467 return &SRExpr->getSymbol();
1468 }
1469
1470 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1471 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1472 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1473
1474 if (LHSSym)
1475 return LHSSym;
1476
1477 if (RHSSym)
1478 return RHSSym;
1479
1480 return nullptr;
1481 }
1482
1483 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1484 return getSingleMCSymbol(UExpr->getSubExpr());
1485
1486 return nullptr;
1487}
1488
1489static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1490 if (isa<MCSymbolRefExpr>(Expr))
1491 return 1;
1492
1493 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1494 return countMCSymbolRefExpr(BExpr->getLHS()) +
1495 countMCSymbolRefExpr(BExpr->getRHS());
1496
1497 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1498 return countMCSymbolRefExpr(UExpr->getSubExpr());
1499
1500 return 0;
1501}
1502
1503namespace {
1504void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1505 MCStreamer &Out, const MCSubtargetInfo *STI) {
1506 MCInst tmpInst;
1507 tmpInst.setOpcode(Opcode);
1508 tmpInst.addOperand(MCOperand::createReg(Reg0));
1509 tmpInst.addOperand(Op1);
1510 tmpInst.setLoc(IDLoc);
1511 Out.EmitInstruction(tmpInst, *STI);
1512}
1513
1514void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1515 MCStreamer &Out, const MCSubtargetInfo *STI) {
1516 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Out, STI);
1517}
1518
1519void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1520 MCStreamer &Out, const MCSubtargetInfo *STI) {
1521 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Out, STI);
1522}
1523
1524void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1525 MCStreamer &Out, const MCSubtargetInfo *STI) {
1526 MCInst tmpInst;
1527 tmpInst.setOpcode(Opcode);
1528 tmpInst.addOperand(MCOperand::createImm(Imm1));
1529 tmpInst.addOperand(MCOperand::createImm(Imm2));
1530 tmpInst.setLoc(IDLoc);
1531 Out.EmitInstruction(tmpInst, *STI);
1532}
1533
1534void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1535 MCStreamer &Out, const MCSubtargetInfo *STI) {
1536 MCInst tmpInst;
1537 tmpInst.setOpcode(Opcode);
1538 tmpInst.addOperand(MCOperand::createReg(Reg0));
1539 tmpInst.setLoc(IDLoc);
1540 Out.EmitInstruction(tmpInst, *STI);
1541}
1542
1543void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1544 SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) {
1545 MCInst tmpInst;
1546 tmpInst.setOpcode(Opcode);
1547 tmpInst.addOperand(MCOperand::createReg(Reg0));
1548 tmpInst.addOperand(MCOperand::createReg(Reg1));
1549 tmpInst.addOperand(Op2);
1550 tmpInst.setLoc(IDLoc);
1551 Out.EmitInstruction(tmpInst, *STI);
1552}
1553
1554void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1555 SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) {
1556 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, Out, STI);
1557}
1558
1559void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1560 SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) {
1561 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, Out, STI);
1562}
1563
1564void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1565 SMLoc IDLoc, MCStreamer &Out,
1566 const MCSubtargetInfo *STI) {
1567 if (ShiftAmount >= 32) {
1568 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, Out, STI);
1569 return;
1570 }
1571
1572 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Out, STI);
1573}
1574} // end anonymous namespace.
1575
1576bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1577 MCStreamer &Out,
1578 const MCSubtargetInfo *STI) {
1579 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1580 bool ExpandedJalSym = false;
1581
1582 Inst.setLoc(IDLoc);
1583
1584 if (MCID.isBranch() || MCID.isCall()) {
1585 const unsigned Opcode = Inst.getOpcode();
1586 MCOperand Offset;
1587
1588 switch (Opcode) {
1589 default:
1590 break;
1591 case Mips::BBIT0:
1592 case Mips::BBIT032:
1593 case Mips::BBIT1:
1594 case Mips::BBIT132:
1595 assert(hasCnMips() && "instruction only valid for octeon cpus")((hasCnMips() && "instruction only valid for octeon cpus"
) ? static_cast<void> (0) : __assert_fail ("hasCnMips() && \"instruction only valid for octeon cpus\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1595, __PRETTY_FUNCTION__))
;
1596 // Fall through
1597
1598 case Mips::BEQ:
1599 case Mips::BNE:
1600 case Mips::BEQ_MM:
1601 case Mips::BNE_MM:
1602 assert(MCID.getNumOperands() == 3 && "unexpected number of operands")((MCID.getNumOperands() == 3 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 3 && \"unexpected number of operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1602, __PRETTY_FUNCTION__))
;
1603 Offset = Inst.getOperand(2);
1604 if (!Offset.isImm())
1605 break; // We'll deal with this situation later on when applying fixups.
1606 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1607 return Error(IDLoc, "branch target out of range");
1608 if (OffsetToAlignment(Offset.getImm(),
1609 1LL << (inMicroMipsMode() ? 1 : 2)))
1610 return Error(IDLoc, "branch to misaligned address");
1611 break;
1612 case Mips::BGEZ:
1613 case Mips::BGTZ:
1614 case Mips::BLEZ:
1615 case Mips::BLTZ:
1616 case Mips::BGEZAL:
1617 case Mips::BLTZAL:
1618 case Mips::BC1F:
1619 case Mips::BC1T:
1620 case Mips::BGEZ_MM:
1621 case Mips::BGTZ_MM:
1622 case Mips::BLEZ_MM:
1623 case Mips::BLTZ_MM:
1624 case Mips::BGEZAL_MM:
1625 case Mips::BLTZAL_MM:
1626 case Mips::BC1F_MM:
1627 case Mips::BC1T_MM:
1628 assert(MCID.getNumOperands() == 2 && "unexpected number of operands")((MCID.getNumOperands() == 2 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 2 && \"unexpected number of operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1628, __PRETTY_FUNCTION__))
;
1629 Offset = Inst.getOperand(1);
1630 if (!Offset.isImm())
1631 break; // We'll deal with this situation later on when applying fixups.
1632 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1633 return Error(IDLoc, "branch target out of range");
1634 if (OffsetToAlignment(Offset.getImm(),
1635 1LL << (inMicroMipsMode() ? 1 : 2)))
1636 return Error(IDLoc, "branch to misaligned address");
1637 break;
1638 case Mips::BEQZ16_MM:
1639 case Mips::BEQZC16_MMR6:
1640 case Mips::BNEZ16_MM:
1641 case Mips::BNEZC16_MMR6:
1642 assert(MCID.getNumOperands() == 2 && "unexpected number of operands")((MCID.getNumOperands() == 2 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 2 && \"unexpected number of operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1642, __PRETTY_FUNCTION__))
;
1643 Offset = Inst.getOperand(1);
1644 if (!Offset.isImm())
1645 break; // We'll deal with this situation later on when applying fixups.
1646 if (!isInt<8>(Offset.getImm()))
1647 return Error(IDLoc, "branch target out of range");
1648 if (OffsetToAlignment(Offset.getImm(), 2LL))
1649 return Error(IDLoc, "branch to misaligned address");
1650 break;
1651 }
1652 }
1653
1654 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1655 // We still accept it but it is a normal nop.
1656 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1657 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1658 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1659 "nop instruction");
1660 }
1661
1662 if (hasCnMips()) {
1663 const unsigned Opcode = Inst.getOpcode();
1664 MCOperand Opnd;
1665 int Imm;
1666
1667 switch (Opcode) {
1668 default:
1669 break;
1670
1671 case Mips::BBIT0:
1672 case Mips::BBIT032:
1673 case Mips::BBIT1:
1674 case Mips::BBIT132:
1675 assert(MCID.getNumOperands() == 3 && "unexpected number of operands")((MCID.getNumOperands() == 3 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 3 && \"unexpected number of operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1675, __PRETTY_FUNCTION__))
;
1676 // The offset is handled above
1677 Opnd = Inst.getOperand(1);
1678 if (!Opnd.isImm())
1679 return Error(IDLoc, "expected immediate operand kind");
1680 Imm = Opnd.getImm();
1681 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1682 Opcode == Mips::BBIT1 ? 63 : 31))
1683 return Error(IDLoc, "immediate operand value out of range");
1684 if (Imm > 31) {
1685 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1686 : Mips::BBIT132);
1687 Inst.getOperand(1).setImm(Imm - 32);
1688 }
1689 break;
1690
1691 case Mips::SEQi:
1692 case Mips::SNEi:
1693 assert(MCID.getNumOperands() == 3 && "unexpected number of operands")((MCID.getNumOperands() == 3 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 3 && \"unexpected number of operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1693, __PRETTY_FUNCTION__))
;
1694 Opnd = Inst.getOperand(2);
1695 if (!Opnd.isImm())
1696 return Error(IDLoc, "expected immediate operand kind");
1697 Imm = Opnd.getImm();
1698 if (!isInt<10>(Imm))
1699 return Error(IDLoc, "immediate operand value out of range");
1700 break;
1701 }
1702 }
1703
1704 // This expansion is not in a function called by tryExpandInstruction()
1705 // because the pseudo-instruction doesn't have a distinct opcode.
1706 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1707 inPicMode()) {
1708 warnIfNoMacro(IDLoc);
1709
1710 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1711
1712 // We can do this expansion if there's only 1 symbol in the argument
1713 // expression.
1714 if (countMCSymbolRefExpr(JalExpr) > 1)
1715 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1716
1717 // FIXME: This is checking the expression can be handled by the later stages
1718 // of the assembler. We ought to leave it to those later stages but
1719 // we can't do that until we stop evaluateRelocExpr() rewriting the
1720 // expressions into non-equivalent forms.
1721 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1722
1723 // FIXME: Add support for label+offset operands (currently causes an error).
1724 // FIXME: Add support for forward-declared local symbols.
1725 // FIXME: Add expansion for when the LargeGOT option is enabled.
1726 if (JalSym->isInSection() || JalSym->isTemporary()) {
1727 if (isABI_O32()) {
1728 // If it's a local symbol and the O32 ABI is being used, we expand to:
1729 // lw $25, 0($gp)
1730 // R_(MICRO)MIPS_GOT16 label
1731 // addiu $25, $25, 0
1732 // R_(MICRO)MIPS_LO16 label
1733 // jalr $25
1734 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1735 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1736
1737 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1738 MCOperand::createExpr(Got16RelocExpr), IDLoc, Out, STI);
1739 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1740 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Out, STI);
1741 } else if (isABI_N32() || isABI_N64()) {
1742 // If it's a local symbol and the N32/N64 ABIs are being used,
1743 // we expand to:
1744 // lw/ld $25, 0($gp)
1745 // R_(MICRO)MIPS_GOT_DISP label
1746 // jalr $25
1747 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1748
1749 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1750 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Out, STI);
1751 }
1752 } else {
1753 // If it's an external/weak symbol, we expand to:
1754 // lw/ld $25, 0($gp)
1755 // R_(MICRO)MIPS_CALL16 label
1756 // jalr $25
1757 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1758
1759 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1760 MCOperand::createExpr(Call16RelocExpr), IDLoc, Out, STI);
1761 }
1762
1763 MCInst JalrInst;
1764 if (IsCpRestoreSet && inMicroMipsMode())
1765 JalrInst.setOpcode(Mips::JALRS_MM);
1766 else
1767 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1768 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1769 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1770
1771 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1772 // This relocation is supposed to be an optimization hint for the linker
1773 // and is not necessary for correctness.
1774
1775 Inst = JalrInst;
1776 ExpandedJalSym = true;
1777 }
1778
1779 if (MCID.mayLoad() || MCID.mayStore()) {
1780 // Check the offset of memory operand, if it is a symbol
1781 // reference or immediate we may have to expand instructions.
1782 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1783 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1784 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1785 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1786 MCOperand &Op = Inst.getOperand(i);
1787 if (Op.isImm()) {
1788 int MemOffset = Op.getImm();
1789 if (MemOffset < -32768 || MemOffset > 32767) {
1790 // Offset can't exceed 16bit value.
1791 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
1792 return false;
1793 }
1794 } else if (Op.isExpr()) {
1795 const MCExpr *Expr = Op.getExpr();
1796 if (Expr->getKind() == MCExpr::SymbolRef) {
1797 const MCSymbolRefExpr *SR =
1798 static_cast<const MCSymbolRefExpr *>(Expr);
1799 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1800 // Expand symbol.
1801 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1802 return false;
1803 }
1804 } else if (!isEvaluated(Expr)) {
1805 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1806 return false;
1807 }
1808 }
1809 }
1810 } // for
1811 } // if load/store
1812
1813 if (inMicroMipsMode()) {
1814 if (MCID.mayLoad()) {
1815 // Try to create 16-bit GP relative load instruction.
1816 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1817 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1818 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1819 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1820 MCOperand &Op = Inst.getOperand(i);
1821 if (Op.isImm()) {
1822 int MemOffset = Op.getImm();
1823 MCOperand &DstReg = Inst.getOperand(0);
1824 MCOperand &BaseReg = Inst.getOperand(1);
1825 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1826 getContext().getRegisterInfo()->getRegClass(
1827 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1828 (BaseReg.getReg() == Mips::GP ||
1829 BaseReg.getReg() == Mips::GP_64)) {
1830
1831 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1832 IDLoc, Out, STI);
1833 return false;
1834 }
1835 }
1836 }
1837 } // for
1838 } // if load
1839
1840 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1841
1842 MCOperand Opnd;
1843 int Imm;
1844
1845 switch (Inst.getOpcode()) {
1846 default:
1847 break;
1848 case Mips::ADDIUSP_MM:
1849 Opnd = Inst.getOperand(0);
1850 if (!Opnd.isImm())
1851 return Error(IDLoc, "expected immediate operand kind");
1852 Imm = Opnd.getImm();
1853 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1854 Imm % 4 != 0)
1855 return Error(IDLoc, "immediate operand value out of range");
1856 break;
1857 case Mips::SLL16_MM:
1858 case Mips::SRL16_MM:
1859 Opnd = Inst.getOperand(2);
1860 if (!Opnd.isImm())
1861 return Error(IDLoc, "expected immediate operand kind");
1862 Imm = Opnd.getImm();
1863 if (Imm < 1 || Imm > 8)
1864 return Error(IDLoc, "immediate operand value out of range");
1865 break;
1866 case Mips::LI16_MM:
1867 Opnd = Inst.getOperand(1);
1868 if (!Opnd.isImm())
1869 return Error(IDLoc, "expected immediate operand kind");
1870 Imm = Opnd.getImm();
1871 if (Imm < -1 || Imm > 126)
1872 return Error(IDLoc, "immediate operand value out of range");
1873 break;
1874 case Mips::ADDIUR2_MM:
1875 Opnd = Inst.getOperand(2);
1876 if (!Opnd.isImm())
1877 return Error(IDLoc, "expected immediate operand kind");
1878 Imm = Opnd.getImm();
1879 if (!(Imm == 1 || Imm == -1 ||
1880 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1881 return Error(IDLoc, "immediate operand value out of range");
1882 break;
1883 case Mips::ANDI16_MM:
1884 Opnd = Inst.getOperand(2);
1885 if (!Opnd.isImm())
1886 return Error(IDLoc, "expected immediate operand kind");
1887 Imm = Opnd.getImm();
1888 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1889 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1890 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1891 return Error(IDLoc, "immediate operand value out of range");
1892 break;
1893 case Mips::LBU16_MM:
1894 Opnd = Inst.getOperand(2);
1895 if (!Opnd.isImm())
1896 return Error(IDLoc, "expected immediate operand kind");
1897 Imm = Opnd.getImm();
1898 if (Imm < -1 || Imm > 14)
1899 return Error(IDLoc, "immediate operand value out of range");
1900 break;
1901 case Mips::SB16_MM:
1902 case Mips::SB16_MMR6:
1903 Opnd = Inst.getOperand(2);
1904 if (!Opnd.isImm())
1905 return Error(IDLoc, "expected immediate operand kind");
1906 Imm = Opnd.getImm();
1907 if (Imm < 0 || Imm > 15)
1908 return Error(IDLoc, "immediate operand value out of range");
1909 break;
1910 case Mips::LHU16_MM:
1911 case Mips::SH16_MM:
1912 case Mips::SH16_MMR6:
1913 Opnd = Inst.getOperand(2);
1914 if (!Opnd.isImm())
1915 return Error(IDLoc, "expected immediate operand kind");
1916 Imm = Opnd.getImm();
1917 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1918 return Error(IDLoc, "immediate operand value out of range");
1919 break;
1920 case Mips::LW16_MM:
1921 case Mips::SW16_MM:
1922 case Mips::SW16_MMR6:
1923 Opnd = Inst.getOperand(2);
1924 if (!Opnd.isImm())
1925 return Error(IDLoc, "expected immediate operand kind");
1926 Imm = Opnd.getImm();
1927 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1928 return Error(IDLoc, "immediate operand value out of range");
1929 break;
1930 case Mips::ADDIUPC_MM:
1931 MCOperand Opnd = Inst.getOperand(1);
1932 if (!Opnd.isImm())
1933 return Error(IDLoc, "expected immediate operand kind");
1934 int Imm = Opnd.getImm();
1935 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1936 return Error(IDLoc, "immediate operand value out of range");
1937 break;
1938 }
1939 }
1940
1941 bool FillDelaySlot =
1942 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
1943 if (FillDelaySlot)
1944 getTargetStreamer().emitDirectiveSetNoReorder();
1945
1946 MacroExpanderResultTy ExpandResult =
1947 tryExpandInstruction(Inst, IDLoc, Out, STI);
1948 switch (ExpandResult) {
1949 case MER_NotAMacro:
1950 Out.EmitInstruction(Inst, *STI);
1951 break;
1952 case MER_Success:
1953 break;
1954 case MER_Fail:
1955 return true;
1956 }
1957
1958 // If this instruction has a delay slot and .set reorder is active,
1959 // emit a NOP after it.
1960 if (FillDelaySlot) {
1961 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Out, STI);
1962 getTargetStreamer().emitDirectiveSetReorder();
1963 }
1964
1965 if ((Inst.getOpcode() == Mips::JalOneReg ||
1966 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1967 isPicAndNotNxxAbi()) {
1968 if (IsCpRestoreSet) {
1969 // We need a NOP between the JALR and the LW:
1970 // If .set reorder has been used, we've already emitted a NOP.
1971 // If .set noreorder has been used, we need to emit a NOP at this point.
1972 if (!AssemblerOptions.back()->isReorder())
1973 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Out, STI);
1974
1975 // Load the $gp from the stack.
1976 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1977 IDLoc, Out, STI);
1978 } else
1979 Warning(IDLoc, "no .cprestore used in PIC mode");
1980 }
1981
1982 return false;
1983}
1984
1985MipsAsmParser::MacroExpanderResultTy
1986MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
1987 const MCSubtargetInfo *STI) {
1988 switch (Inst.getOpcode()) {
1989 default:
1990 return MER_NotAMacro;
1991 case Mips::LoadImm32:
1992 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
1993 case Mips::LoadImm64:
1994 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
1995 case Mips::LoadAddrImm32:
1996 case Mips::LoadAddrImm64:
1997 assert(Inst.getOperand(0).isReg() && "expected register operand kind")((Inst.getOperand(0).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1997, __PRETTY_FUNCTION__))
;
1998 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&(((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1999, __PRETTY_FUNCTION__))
1999 "expected immediate operand kind")(((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1999, __PRETTY_FUNCTION__))
;
2000
2001 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2002 Inst.getOperand(1),
2003 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2004 Out, STI)
2005 ? MER_Fail
2006 : MER_Success;
2007 case Mips::LoadAddrReg32:
2008 case Mips::LoadAddrReg64:
2009 assert(Inst.getOperand(0).isReg() && "expected register operand kind")((Inst.getOperand(0).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2009, __PRETTY_FUNCTION__))
;
2010 assert(Inst.getOperand(1).isReg() && "expected register operand kind")((Inst.getOperand(1).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(1).isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2010, __PRETTY_FUNCTION__))
;
2011 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&(((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2012, __PRETTY_FUNCTION__))
2012 "expected immediate operand kind")(((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2012, __PRETTY_FUNCTION__))
;
2013
2014 return expandLoadAddress(Inst.getOperand(0).getReg(),
2015 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2016 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2017 Out, STI)
2018 ? MER_Fail
2019 : MER_Success;
2020 case Mips::B_MM_Pseudo:
2021 case Mips::B_MMR6_Pseudo:
2022 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2023 : MER_Success;
2024 case Mips::SWM_MM:
2025 case Mips::LWM_MM:
2026 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2027 : MER_Success;
2028 case Mips::JalOneReg:
2029 case Mips::JalTwoReg:
2030 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2031 case Mips::BneImm:
2032 case Mips::BeqImm:
2033 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2034 case Mips::BLT:
2035 case Mips::BLE:
2036 case Mips::BGE:
2037 case Mips::BGT:
2038 case Mips::BLTU:
2039 case Mips::BLEU:
2040 case Mips::BGEU:
2041 case Mips::BGTU:
2042 case Mips::BLTL:
2043 case Mips::BLEL:
2044 case Mips::BGEL:
2045 case Mips::BGTL:
2046 case Mips::BLTUL:
2047 case Mips::BLEUL:
2048 case Mips::BGEUL:
2049 case Mips::BGTUL:
2050 case Mips::BLTImmMacro:
2051 case Mips::BLEImmMacro:
2052 case Mips::BGEImmMacro:
2053 case Mips::BGTImmMacro:
2054 case Mips::BLTUImmMacro:
2055 case Mips::BLEUImmMacro:
2056 case Mips::BGEUImmMacro:
2057 case Mips::BGTUImmMacro:
2058 case Mips::BLTLImmMacro:
2059 case Mips::BLELImmMacro:
2060 case Mips::BGELImmMacro:
2061 case Mips::BGTLImmMacro:
2062 case Mips::BLTULImmMacro:
2063 case Mips::BLEULImmMacro:
2064 case Mips::BGEULImmMacro:
2065 case Mips::BGTULImmMacro:
2066 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2067 case Mips::SDivMacro:
2068 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2069 : MER_Success;
2070 case Mips::DSDivMacro:
2071 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2072 : MER_Success;
2073 case Mips::UDivMacro:
2074 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2075 : MER_Success;
2076 case Mips::DUDivMacro:
2077 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2078 : MER_Success;
2079 case Mips::PseudoTRUNC_W_S:
2080 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2081 : MER_Success;
2082 case Mips::PseudoTRUNC_W_D32:
2083 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2084 : MER_Success;
2085 case Mips::PseudoTRUNC_W_D:
2086 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2087 : MER_Success;
2088 case Mips::Ulh:
2089 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2090 case Mips::Ulhu:
2091 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2092 case Mips::Ulw:
2093 return expandUlw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2094 case Mips::NORImm:
2095 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2096 case Mips::ADDi:
2097 case Mips::ADDiu:
2098 case Mips::SLTi:
2099 case Mips::SLTiu:
2100 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2101 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2102 int64_t ImmValue = Inst.getOperand(2).getImm();
2103 if (isInt<16>(ImmValue))
2104 return MER_NotAMacro;
2105 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2106 : MER_Success;
2107 }
2108 return MER_NotAMacro;
2109 case Mips::ANDi:
2110 case Mips::ORi:
2111 case Mips::XORi:
2112 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2113 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2114 int64_t ImmValue = Inst.getOperand(2).getImm();
2115 if (isUInt<16>(ImmValue))
2116 return MER_NotAMacro;
2117 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2118 : MER_Success;
2119 }
2120 return MER_NotAMacro;
2121 case Mips::ROL:
2122 case Mips::ROR:
2123 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2124 case Mips::ROLImm:
2125 case Mips::RORImm:
2126 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2127 case Mips::DROL:
2128 case Mips::DROR:
2129 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2130 case Mips::DROLImm:
2131 case Mips::DRORImm:
2132 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2133 case Mips::ABSMacro:
2134 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2135 }
2136}
2137
2138bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2139 MCStreamer &Out,
2140 const MCSubtargetInfo *STI) {
2141 // Create a JALR instruction which is going to replace the pseudo-JAL.
2142 MCInst JalrInst;
2143 JalrInst.setLoc(IDLoc);
2144 const MCOperand FirstRegOp = Inst.getOperand(0);
2145 const unsigned Opcode = Inst.getOpcode();
2146
2147 if (Opcode == Mips::JalOneReg) {
2148 // jal $rs => jalr $rs
2149 if (IsCpRestoreSet && inMicroMipsMode()) {
2150 JalrInst.setOpcode(Mips::JALRS16_MM);
2151 JalrInst.addOperand(FirstRegOp);
2152 } else if (inMicroMipsMode()) {
2153 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2154 JalrInst.addOperand(FirstRegOp);
2155 } else {
2156 JalrInst.setOpcode(Mips::JALR);
2157 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2158 JalrInst.addOperand(FirstRegOp);
2159 }
2160 } else if (Opcode == Mips::JalTwoReg) {
2161 // jal $rd, $rs => jalr $rd, $rs
2162 if (IsCpRestoreSet && inMicroMipsMode())
2163 JalrInst.setOpcode(Mips::JALRS_MM);
2164 else
2165 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2166 JalrInst.addOperand(FirstRegOp);
2167 const MCOperand SecondRegOp = Inst.getOperand(1);
2168 JalrInst.addOperand(SecondRegOp);
2169 }
2170 Out.EmitInstruction(JalrInst, *STI);
2171
2172 // If .set reorder is active and branch instruction has a delay slot,
2173 // emit a NOP after it.
2174 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2175 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2176 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Out, STI);
2177 }
2178
2179 return false;
2180}
2181
2182/// Can the value be represented by a unsigned N-bit value and a shift left?
2183template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2184 unsigned BitNum = findFirstSet(x);
2185
2186 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2187}
2188
2189/// Load (or add) an immediate into a register.
2190///
2191/// @param ImmValue The immediate to load.
2192/// @param DstReg The register that will hold the immediate.
2193/// @param SrcReg A register to add to the immediate or Mips::NoRegister
2194/// for a simple initialization.
2195/// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2196/// @param IsAddress True if the immediate represents an address. False if it
2197/// is an integer.
2198/// @param IDLoc Location of the immediate in the source file.
2199bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2200 unsigned SrcReg, bool Is32BitImm,
2201 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2202 const MCSubtargetInfo *STI) {
2203 if (!Is32BitImm && !isGP64bit()) {
2204 Error(IDLoc, "instruction requires a 64-bit architecture");
2205 return true;
2206 }
2207
2208 if (Is32BitImm) {
2209 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2210 // Sign extend up to 64-bit so that the predicates match the hardware
2211 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2212 // true.
2213 ImmValue = SignExtend64<32>(ImmValue);
2214 } else {
2215 Error(IDLoc, "instruction requires a 32-bit immediate");
2216 return true;
2217 }
2218 }
2219
2220 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2221 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2222
2223 bool UseSrcReg = false;
2224 if (SrcReg != Mips::NoRegister)
2225 UseSrcReg = true;
2226
2227 unsigned TmpReg = DstReg;
2228 if (UseSrcReg &&
2229 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2230 // At this point we need AT to perform the expansions and we exit if it is
2231 // not available.
2232 unsigned ATReg = getATReg(IDLoc);
2233 if (!ATReg)
2234 return true;
2235 TmpReg = ATReg;
2236 }
2237
2238 if (isInt<16>(ImmValue)) {
2239 if (!UseSrcReg)
2240 SrcReg = ZeroReg;
2241
2242 // This doesn't quite follow the usual ABI expectations for N32 but matches
2243 // traditional assembler behaviour. N32 would normally use addiu for both
2244 // integers and addresses.
2245 if (IsAddress && !Is32BitImm) {
2246 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Out, STI);
2247 return false;
2248 }
2249
2250 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Out, STI);
2251 return false;
2252 }
2253
2254 if (isUInt<16>(ImmValue)) {
2255 unsigned TmpReg = DstReg;
2256 if (SrcReg == DstReg) {
2257 TmpReg = getATReg(IDLoc);
2258 if (!TmpReg)
2259 return true;
2260 }
2261
2262 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Out, STI);
2263 if (UseSrcReg)
2264 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
2265 return false;
2266 }
2267
2268 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2269 warnIfNoMacro(IDLoc);
2270
2271 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2272 uint16_t Bits15To0 = ImmValue & 0xffff;
2273
2274 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2275 // Traditional behaviour seems to special case this particular value. It's
2276 // not clear why other masks are handled differently.
2277 if (ImmValue == 0xffffffff) {
2278 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Out, STI);
2279 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Out, STI);
2280 if (UseSrcReg)
2281 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
2282 return false;
2283 }
2284
2285 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2286 // upper 32 bits.
2287 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Out, STI);
2288 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Out, STI);
2289 if (Bits15To0)
2290 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Out, STI);
2291 if (UseSrcReg)
2292 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
2293 return false;
2294 }
2295
2296 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Out, STI);
2297 if (Bits15To0)
2298 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Out, STI);
2299 if (UseSrcReg)
2300 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
2301 return false;
2302 }
2303
2304 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2305 if (Is32BitImm) {
2306 Error(IDLoc, "instruction requires a 32-bit immediate");
2307 return true;
2308 }
2309
2310 // Traditionally, these immediates are shifted as little as possible and as
2311 // such we align the most significant bit to bit 15 of our temporary.
2312 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2313 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2314 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2315 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2316 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Out, STI);
2317 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Out, STI);
2318
2319 if (UseSrcReg)
2320 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
2321
2322 return false;
2323 }
2324
2325 warnIfNoMacro(IDLoc);
2326
2327 // The remaining case is packed with a sequence of dsll and ori with zeros
2328 // being omitted and any neighbouring dsll's being coalesced.
2329 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2330
2331 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2332 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2333 IDLoc, Out, STI))
2334 return false;
2335
2336 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2337 // skip it and defer the shift to the next chunk.
2338 unsigned ShiftCarriedForwards = 16;
2339 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2340 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2341
2342 if (ImmChunk != 0) {
2343 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2344 Out, STI);
2345 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Out, STI);
2346 ShiftCarriedForwards = 0;
2347 }
2348
2349 ShiftCarriedForwards += 16;
2350 }
2351 ShiftCarriedForwards -= 16;
2352
2353 // Finish any remaining shifts left by trailing zeros.
2354 if (ShiftCarriedForwards)
2355 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2356 Out, STI);
2357
2358 if (UseSrcReg)
2359 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
2360
2361 return false;
2362}
2363
2364bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2365 MCStreamer &Out, const MCSubtargetInfo *STI) {
2366 const MCOperand &ImmOp = Inst.getOperand(1);
2367 assert(ImmOp.isImm() && "expected immediate operand kind")((ImmOp.isImm() && "expected immediate operand kind")
? static_cast<void> (0) : __assert_fail ("ImmOp.isImm() && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2367, __PRETTY_FUNCTION__))
;
2368 const MCOperand &DstRegOp = Inst.getOperand(0);
2369 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2369, __PRETTY_FUNCTION__))
;
2370
2371 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2372 Is32BitImm, false, IDLoc, Out, STI))
2373 return true;
2374
2375 return false;
2376}
2377
2378bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2379 const MCOperand &Offset,
2380 bool Is32BitAddress, SMLoc IDLoc,
2381 MCStreamer &Out,
2382 const MCSubtargetInfo *STI) {
2383 // la can't produce a usable address when addresses are 64-bit.
2384 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2385 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2386 // We currently can't do this because we depend on the equality
2387 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2388 Error(IDLoc, "la used to load 64-bit address");
2389 // Continue as if we had 'dla' instead.
2390 Is32BitAddress = false;
2391 }
2392
2393 // dla requires 64-bit addresses.
2394 if (!Is32BitAddress && !hasMips3()) {
2395 Error(IDLoc, "instruction requires a 64-bit architecture");
2396 return true;
2397 }
2398
2399 if (!Offset.isImm())
2400 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2401 Is32BitAddress, IDLoc, Out, STI);
2402
2403 if (!ABI.ArePtrs64bit()) {
2404 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2405 Is32BitAddress = true;
2406 }
2407
2408 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2409 IDLoc, Out, STI);
2410}
2411
2412bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2413 unsigned DstReg, unsigned SrcReg,
2414 bool Is32BitSym, SMLoc IDLoc,
2415 MCStreamer &Out,
2416 const MCSubtargetInfo *STI) {
2417 warnIfNoMacro(IDLoc);
2418
2419 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2420 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2421 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2422 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2423 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2424
2425 bool UseSrcReg = SrcReg != Mips::NoRegister;
2426
2427 // This is the 64-bit symbol address expansion.
2428 if (ABI.ArePtrs64bit() && isGP64bit()) {
2429 // We always need AT for the 64-bit expansion.
2430 // If it is not available we exit.
2431 unsigned ATReg = getATReg(IDLoc);
2432 if (!ATReg)
2433 return true;
2434
2435 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2436 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2437 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2438 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2439
2440 if (UseSrcReg &&
2441 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2442 SrcReg)) {
2443 // If $rs is the same as $rd:
2444 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2445 // daddiu $at, $at, %higher(sym)
2446 // dsll $at, $at, 16
2447 // daddiu $at, $at, %hi(sym)
2448 // dsll $at, $at, 16
2449 // daddiu $at, $at, %lo(sym)
2450 // daddu $rd, $at, $rd
2451 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc, Out,
2452 STI);
2453 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2454 IDLoc, Out, STI);
2455 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Out, STI);
2456 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2457 Out, STI);
2458 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Out, STI);
2459 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2460 Out, STI);
2461 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Out, STI);
2462
2463 return false;
2464 }
2465
2466 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2467 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2468 // lui $at, %hi(sym)
2469 // daddiu $rd, $rd, %higher(sym)
2470 // daddiu $at, $at, %lo(sym)
2471 // dsll32 $rd, $rd, 0
2472 // daddu $rd, $rd, $at
2473 // (daddu $rd, $rd, $rs)
2474 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc, Out,
2475 STI);
2476 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, Out, STI);
2477 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2478 IDLoc, Out, STI);
2479 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2480 Out, STI);
2481 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Out, STI);
2482 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Out, STI);
2483 if (UseSrcReg)
2484 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Out, STI);
2485
2486 return false;
2487 }
2488
2489 // And now, the 32-bit symbol address expansion:
2490 // If $rs is the same as $rd:
2491 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2492 // ori $at, $at, %lo(sym)
2493 // addu $rd, $at, $rd
2494 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2495 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2496 // ori $rd, $rd, %lo(sym)
2497 // (addu $rd, $rd, $rs)
2498 unsigned TmpReg = DstReg;
2499 if (UseSrcReg &&
2500 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2501 // If $rs is the same as $rd, we need to use AT.
2502 // If it is not available we exit.
2503 unsigned ATReg = getATReg(IDLoc);
2504 if (!ATReg)
2505 return true;
2506 TmpReg = ATReg;
2507 }
2508
2509 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Out, STI);
2510 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2511 Out, STI);
2512
2513 if (UseSrcReg)
2514 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
2515 else
2516 assert(((getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg)) ? static_cast<void> (0) : __assert_fail ("getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2517, __PRETTY_FUNCTION__))
2517 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg))((getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg)) ? static_cast<void> (0) : __assert_fail ("getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2517, __PRETTY_FUNCTION__))
;
2518
2519 return false;
2520}
2521
2522bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
2523 MCStreamer &Out,
2524 const MCSubtargetInfo *STI) {
2525 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&((getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
"unexpected number of operands") ? static_cast<void> (
0) : __assert_fail ("getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && \"unexpected number of operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2526, __PRETTY_FUNCTION__))
2526 "unexpected number of operands")((getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
"unexpected number of operands") ? static_cast<void> (
0) : __assert_fail ("getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && \"unexpected number of operands\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2526, __PRETTY_FUNCTION__))
;
2527
2528 MCOperand Offset = Inst.getOperand(0);
2529 if (Offset.isExpr()) {
2530 Inst.clear();
2531 Inst.setOpcode(Mips::BEQ_MM);
2532 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2533 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2534 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2535 } else {
2536 assert(Offset.isImm() && "expected immediate operand kind")((Offset.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("Offset.isImm() && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2536, __PRETTY_FUNCTION__))
;
2537 if (isInt<11>(Offset.getImm())) {
2538 // If offset fits into 11 bits then this instruction becomes microMIPS
2539 // 16-bit unconditional branch instruction.
2540 if (inMicroMipsMode())
2541 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2542 } else {
2543 if (!isInt<17>(Offset.getImm()))
2544 Error(IDLoc, "branch target out of range");
2545 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2546 Error(IDLoc, "branch to misaligned address");
2547 Inst.clear();
2548 Inst.setOpcode(Mips::BEQ_MM);
2549 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2550 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2551 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2552 }
2553 }
2554 Out.EmitInstruction(Inst, *STI);
2555
2556 // If .set reorder is active and branch instruction has a delay slot,
2557 // emit a NOP after it.
2558 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2559 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2560 createNop(true, IDLoc, Out, STI);
2561
2562 return false;
2563}
2564
2565bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2566 const MCSubtargetInfo *STI) {
2567 const MCOperand &DstRegOp = Inst.getOperand(0);
2568 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2568, __PRETTY_FUNCTION__))
;
2569
2570 const MCOperand &ImmOp = Inst.getOperand(1);
2571 assert(ImmOp.isImm() && "expected immediate operand kind")((ImmOp.isImm() && "expected immediate operand kind")
? static_cast<void> (0) : __assert_fail ("ImmOp.isImm() && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2571, __PRETTY_FUNCTION__))
;
2572
2573 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2574 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&(((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && "expected immediate or expression operand"
) ? static_cast<void> (0) : __assert_fail ("(MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && \"expected immediate or expression operand\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2575, __PRETTY_FUNCTION__))
2575 "expected immediate or expression operand")(((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && "expected immediate or expression operand"
) ? static_cast<void> (0) : __assert_fail ("(MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && \"expected immediate or expression operand\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2575, __PRETTY_FUNCTION__))
;
2576
2577 unsigned OpCode = 0;
2578 switch(Inst.getOpcode()) {
2579 case Mips::BneImm:
2580 OpCode = Mips::BNE;
2581 break;
2582 case Mips::BeqImm:
2583 OpCode = Mips::BEQ;
2584 break;
2585 default:
2586 llvm_unreachable("Unknown immediate branch pseudo-instruction.")::llvm::llvm_unreachable_internal("Unknown immediate branch pseudo-instruction."
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2586)
;
2587 break;
2588 }
2589
2590 int64_t ImmValue = ImmOp.getImm();
2591 if (ImmValue == 0)
2592 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc, Out,
2593 STI);
2594 else {
2595 warnIfNoMacro(IDLoc);
2596
2597 unsigned ATReg = getATReg(IDLoc);
2598 if (!ATReg)
2599 return true;
2600
2601 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2602 IDLoc, Out, STI))
2603 return true;
2604
2605 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Out, STI);
2606 }
2607 return false;
2608}
2609
2610void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2611 const MCSubtargetInfo *STI, bool isLoad,
2612 bool isImmOpnd) {
2613 MCOperand HiOperand, LoOperand;
2614 unsigned TmpRegNum;
2615 // 1st operand is either the source or destination register.
2616 assert(Inst.getOperand(0).isReg() && "expected register operand kind")((Inst.getOperand(0).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2616, __PRETTY_FUNCTION__))
;
2617 unsigned RegOpNum = Inst.getOperand(0).getReg();
2618 // 2nd operand is the base register.
2619 assert(Inst.getOperand(1).isReg() && "expected register operand kind")((Inst.getOperand(1).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(1).isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2619, __PRETTY_FUNCTION__))
;
2620 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2621 // 3rd operand is either an immediate or expression.
2622 if (isImmOpnd) {
2623 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind")((Inst.getOperand(2).isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2623, __PRETTY_FUNCTION__))
;
2624 unsigned ImmOffset = Inst.getOperand(2).getImm();
2625 unsigned LoOffset = ImmOffset & 0x0000ffff;
2626 unsigned HiOffset = (ImmOffset & 0xffff0000) >> 16;
2627 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2628 if (LoOffset & 0x8000)
2629 HiOffset++;
2630 LoOperand = MCOperand::createImm(LoOffset);
2631 HiOperand = MCOperand::createImm(HiOffset);
2632 } else {
2633 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2634 LoOperand = MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo"));
2635 HiOperand = MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi"));
2636 }
2637 // These are some of the types of expansions we perform here:
2638 // 1) lw $8, sym => lui $8, %hi(sym)
2639 // lw $8, %lo(sym)($8)
2640 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2641 // add $8, $8, $9
2642 // lw $8, %lo(offset)($9)
2643 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2644 // add $at, $at, $8
2645 // lw $8, %lo(offset)($at)
2646 // 4) sw $8, sym => lui $at, %hi(sym)
2647 // sw $8, %lo(sym)($at)
2648 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2649 // add $at, $at, $8
2650 // sw $8, %lo(offset)($at)
2651 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2652 // ldc1 $f0, %lo(sym)($at)
2653 //
2654 // For load instructions we can use the destination register as a temporary
2655 // if base and dst are different (examples 1 and 2) and if the base register
2656 // is general purpose otherwise we must use $at (example 6) and error if it's
2657 // not available. For stores we must use $at (examples 4 and 5) because we
2658 // must not clobber the source register setting up the offset.
2659 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2660 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2661 unsigned RegClassIDOp0 =
2662 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2663 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2664 (RegClassIDOp0 == Mips::GPR64RegClassID);
2665 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2666 TmpRegNum = RegOpNum;
2667 else {
2668 // At this point we need AT to perform the expansions and we exit if it is
2669 // not available.
2670 TmpRegNum = getATReg(IDLoc);
2671 if (!TmpRegNum)
2672 return;
2673 }
2674
2675 emitRX(Mips::LUi, TmpRegNum, HiOperand, IDLoc, Out, STI);
2676 // Add temp register to base.
2677 if (BaseRegNum != Mips::ZERO)
2678 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Out, STI);
2679 // And finally, create original instruction with low part
2680 // of offset and new base.
2681 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum, LoOperand, IDLoc, Out, STI);
2682}
2683
2684bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2685 MCStreamer &Out,
2686 const MCSubtargetInfo *STI) {
2687 unsigned OpNum = Inst.getNumOperands();
2688 unsigned Opcode = Inst.getOpcode();
2689 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2690
2691 assert (Inst.getOperand(OpNum - 1).isImm() &&((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2693, __PRETTY_FUNCTION__))
2692 Inst.getOperand(OpNum - 2).isReg() &&((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2693, __PRETTY_FUNCTION__))
2693 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.")((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2693, __PRETTY_FUNCTION__))
;
2694
2695 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2696 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2697 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2698 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2699 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2700 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2701 // It can be implemented as SWM16 or LWM16 instruction.
2702 if (inMicroMipsMode() && hasMips32r6())
2703 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2704 else
2705 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2706 }
2707
2708 Inst.setOpcode(NewOpcode);
2709 Out.EmitInstruction(Inst, *STI);
2710 return false;
2711}
2712
2713bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2714 MCStreamer &Out,
2715 const MCSubtargetInfo *STI) {
2716 bool EmittedNoMacroWarning = false;
2717 unsigned PseudoOpcode = Inst.getOpcode();
2718 unsigned SrcReg = Inst.getOperand(0).getReg();
2719 const MCOperand &TrgOp = Inst.getOperand(1);
2720 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2721
2722 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2723 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2724
2725 unsigned TrgReg;
1
'TrgReg' declared without an initial value
2726 if (TrgOp.isReg())
2
Taking false branch
2727 TrgReg = TrgOp.getReg();
2728 else if (TrgOp.isImm()) {
3
Taking false branch
2729 warnIfNoMacro(IDLoc);
2730 EmittedNoMacroWarning = true;
2731
2732 TrgReg = getATReg(IDLoc);
2733 if (!TrgReg)
2734 return true;
2735
2736 switch(PseudoOpcode) {
2737 default:
2738 llvm_unreachable("unknown opcode for branch pseudo-instruction")::llvm::llvm_unreachable_internal("unknown opcode for branch pseudo-instruction"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2738)
;
2739 case Mips::BLTImmMacro:
2740 PseudoOpcode = Mips::BLT;
2741 break;
2742 case Mips::BLEImmMacro:
2743 PseudoOpcode = Mips::BLE;
2744 break;
2745 case Mips::BGEImmMacro:
2746 PseudoOpcode = Mips::BGE;
2747 break;
2748 case Mips::BGTImmMacro:
2749 PseudoOpcode = Mips::BGT;
2750 break;
2751 case Mips::BLTUImmMacro:
2752 PseudoOpcode = Mips::BLTU;
2753 break;
2754 case Mips::BLEUImmMacro:
2755 PseudoOpcode = Mips::BLEU;
2756 break;
2757 case Mips::BGEUImmMacro:
2758 PseudoOpcode = Mips::BGEU;
2759 break;
2760 case Mips::BGTUImmMacro:
2761 PseudoOpcode = Mips::BGTU;
2762 break;
2763 case Mips::BLTLImmMacro:
2764 PseudoOpcode = Mips::BLTL;
2765 break;
2766 case Mips::BLELImmMacro:
2767 PseudoOpcode = Mips::BLEL;
2768 break;
2769 case Mips::BGELImmMacro:
2770 PseudoOpcode = Mips::BGEL;
2771 break;
2772 case Mips::BGTLImmMacro:
2773 PseudoOpcode = Mips::BGTL;
2774 break;
2775 case Mips::BLTULImmMacro:
2776 PseudoOpcode = Mips::BLTUL;
2777 break;
2778 case Mips::BLEULImmMacro:
2779 PseudoOpcode = Mips::BLEUL;
2780 break;
2781 case Mips::BGEULImmMacro:
2782 PseudoOpcode = Mips::BGEUL;
2783 break;
2784 case Mips::BGTULImmMacro:
2785 PseudoOpcode = Mips::BGTUL;
2786 break;
2787 }
2788
2789 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2790 false, IDLoc, Out, STI))
2791 return true;
2792 }
2793
2794 switch (PseudoOpcode) {
4
Control jumps to 'case BGTL:' at line 2830
2795 case Mips::BLT:
2796 case Mips::BLTU:
2797 case Mips::BLTL:
2798 case Mips::BLTUL:
2799 AcceptsEquality = false;
2800 ReverseOrderSLT = false;
2801 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2802 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2803 ZeroSrcOpcode = Mips::BGTZ;
2804 ZeroTrgOpcode = Mips::BLTZ;
2805 break;
2806 case Mips::BLE:
2807 case Mips::BLEU:
2808 case Mips::BLEL:
2809 case Mips::BLEUL:
2810 AcceptsEquality = true;
2811 ReverseOrderSLT = true;
2812 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2813 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2814 ZeroSrcOpcode = Mips::BGEZ;
2815 ZeroTrgOpcode = Mips::BLEZ;
2816 break;
2817 case Mips::BGE:
2818 case Mips::BGEU:
2819 case Mips::BGEL:
2820 case Mips::BGEUL:
2821 AcceptsEquality = true;
2822 ReverseOrderSLT = false;
2823 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2824 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2825 ZeroSrcOpcode = Mips::BLEZ;
2826 ZeroTrgOpcode = Mips::BGEZ;
2827 break;
2828 case Mips::BGT:
2829 case Mips::BGTU:
2830 case Mips::BGTL:
2831 case Mips::BGTUL:
2832 AcceptsEquality = false;
2833 ReverseOrderSLT = true;
2834 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2835 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2836 ZeroSrcOpcode = Mips::BLTZ;
2837 ZeroTrgOpcode = Mips::BGTZ;
2838 break;
5
Execution continues on line 2843
2839 default:
2840 llvm_unreachable("unknown opcode for branch pseudo-instruction")::llvm::llvm_unreachable_internal("unknown opcode for branch pseudo-instruction"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2840)
;
2841 }
2842
2843 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
6
The left operand of '==' is a garbage value
2844 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2845 if (IsSrcRegZero && IsTrgRegZero) {
2846 // FIXME: All of these Opcode-specific if's are needed for compatibility
2847 // with GAS' behaviour. However, they may not generate the most efficient
2848 // code in some circumstances.
2849 if (PseudoOpcode == Mips::BLT) {
2850 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2851 Out, STI);
2852 return false;
2853 }
2854 if (PseudoOpcode == Mips::BLE) {
2855 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2856 Out, STI);
2857 Warning(IDLoc, "branch is always taken");
2858 return false;
2859 }
2860 if (PseudoOpcode == Mips::BGE) {
2861 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2862 Out, STI);
2863 Warning(IDLoc, "branch is always taken");
2864 return false;
2865 }
2866 if (PseudoOpcode == Mips::BGT) {
2867 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2868 Out, STI);
2869 return false;
2870 }
2871 if (PseudoOpcode == Mips::BGTU) {
2872 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2873 MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
2874 return false;
2875 }
2876 if (AcceptsEquality) {
2877 // If both registers are $0 and the pseudo-branch accepts equality, it
2878 // will always be taken, so we emit an unconditional branch.
2879 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2880 MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
2881 Warning(IDLoc, "branch is always taken");
2882 return false;
2883 }
2884 // If both registers are $0 and the pseudo-branch does not accept
2885 // equality, it will never be taken, so we don't have to emit anything.
2886 return false;
2887 }
2888 if (IsSrcRegZero || IsTrgRegZero) {
2889 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2890 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2891 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2892 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2893 // the pseudo-branch will never be taken, so we don't emit anything.
2894 // This only applies to unsigned pseudo-branches.
2895 return false;
2896 }
2897 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2898 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2899 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2900 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2901 // the pseudo-branch will always be taken, so we emit an unconditional
2902 // branch.
2903 // This only applies to unsigned pseudo-branches.
2904 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2905 MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
2906 Warning(IDLoc, "branch is always taken");
2907 return false;
2908 }
2909 if (IsUnsigned) {
2910 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2911 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2912 // the pseudo-branch will be taken only when the non-zero register is
2913 // different from 0, so we emit a BNEZ.
2914 //
2915 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2916 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2917 // the pseudo-branch will be taken only when the non-zero register is
2918 // equal to 0, so we emit a BEQZ.
2919 //
2920 // Because only BLEU and BGEU branch on equality, we can use the
2921 // AcceptsEquality variable to decide when to emit the BEQZ.
2922 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2923 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2924 MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
2925 return false;
2926 }
2927 // If we have a signed pseudo-branch and one of the registers is $0,
2928 // we can use an appropriate compare-to-zero branch. We select which one
2929 // to use in the switch statement above.
2930 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2931 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2932 IDLoc, Out, STI);
2933 return false;
2934 }
2935
2936 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2937 // expansions. If it is not available, we return.
2938 unsigned ATRegNum = getATReg(IDLoc);
2939 if (!ATRegNum)
2940 return true;
2941
2942 if (!EmittedNoMacroWarning)
2943 warnIfNoMacro(IDLoc);
2944
2945 // SLT fits well with 2 of our 4 pseudo-branches:
2946 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2947 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2948 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2949 // This is accomplished by using a BNEZ with the result of the SLT.
2950 //
2951 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2952 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2953 // Because only BGE and BLE branch on equality, we can use the
2954 // AcceptsEquality variable to decide when to emit the BEQZ.
2955 // Note that the order of the SLT arguments doesn't change between
2956 // opposites.
2957 //
2958 // The same applies to the unsigned variants, except that SLTu is used
2959 // instead of SLT.
2960 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2961 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2962 IDLoc, Out, STI);
2963
2964 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2965 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2966 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2967 Out, STI);
2968 return false;
2969}
2970
2971bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2972 const MCSubtargetInfo *STI, const bool IsMips64,
2973 const bool Signed) {
2974 if (hasMips32r6()) {
2975 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2976 return false;
2977 }
2978
2979 warnIfNoMacro(IDLoc);
2980
2981 const MCOperand &RsRegOp = Inst.getOperand(0);
2982 assert(RsRegOp.isReg() && "expected register operand kind")((RsRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("RsRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2982, __PRETTY_FUNCTION__))
;
2983 unsigned RsReg = RsRegOp.getReg();
2984
2985 const MCOperand &RtRegOp = Inst.getOperand(1);
2986 assert(RtRegOp.isReg() && "expected register operand kind")((RtRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("RtRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2986, __PRETTY_FUNCTION__))
;
2987 unsigned RtReg = RtRegOp.getReg();
2988 unsigned DivOp;
2989 unsigned ZeroReg;
2990
2991 if (IsMips64) {
2992 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2993 ZeroReg = Mips::ZERO_64;
2994 } else {
2995 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2996 ZeroReg = Mips::ZERO;
2997 }
2998
2999 bool UseTraps = useTraps();
3000
3001 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3002 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
3003 Warning(IDLoc, "dividing zero by zero");
3004 if (IsMips64) {
3005 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3006 if (UseTraps) {
3007 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Out, STI);
3008 return false;
3009 }
3010
3011 emitII(Mips::BREAK, 0x7, 0, IDLoc, Out, STI);
3012 return false;
3013 }
3014 } else {
3015 emitRR(DivOp, RsReg, RtReg, IDLoc, Out, STI);
3016 return false;
3017 }
3018 }
3019
3020 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3021 Warning(IDLoc, "division by zero");
3022 if (Signed) {
3023 if (UseTraps) {
3024 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Out, STI);
3025 return false;
3026 }
3027
3028 emitII(Mips::BREAK, 0x7, 0, IDLoc, Out, STI);
3029 return false;
3030 }
3031 }
3032
3033 // FIXME: The values for these two BranchTarget variables may be different in
3034 // micromips. These magic numbers need to be removed.
3035 unsigned BranchTargetNoTraps;
3036 unsigned BranchTarget;
3037
3038 if (UseTraps) {
3039 BranchTarget = IsMips64 ? 12 : 8;
3040 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Out, STI);
3041 } else {
3042 BranchTarget = IsMips64 ? 20 : 16;
3043 BranchTargetNoTraps = 8;
3044 // Branch to the li instruction.
3045 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, Out, STI);
3046 }
3047
3048 emitRR(DivOp, RsReg, RtReg, IDLoc, Out, STI);
3049
3050 if (!UseTraps)
3051 emitII(Mips::BREAK, 0x7, 0, IDLoc, Out, STI);
3052
3053 if (!Signed) {
3054 emitR(Mips::MFLO, RsReg, IDLoc, Out, STI);
3055 return false;
3056 }
3057
3058 unsigned ATReg = getATReg(IDLoc);
3059 if (!ATReg)
3060 return true;
3061
3062 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Out, STI);
3063 if (IsMips64) {
3064 // Branch to the mflo instruction.
3065 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Out, STI);
3066 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Out, STI);
3067 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Out, STI);
3068 } else {
3069 // Branch to the mflo instruction.
3070 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Out, STI);
3071 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Out, STI);
3072 }
3073
3074 if (UseTraps)
3075 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Out, STI);
3076 else {
3077 // Branch to the mflo instruction.
3078 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Out, STI);
3079 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Out, STI);
3080 emitII(Mips::BREAK, 0x6, 0, IDLoc, Out, STI);
3081 }
3082 emitR(Mips::MFLO, RsReg, IDLoc, Out, STI);
3083 return false;
3084}
3085
3086bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3087 SMLoc IDLoc, MCStreamer &Out,
3088 const MCSubtargetInfo *STI) {
3089
3090 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3090, __PRETTY_FUNCTION__))
;
3091 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3092, __PRETTY_FUNCTION__))
3092 Inst.getOperand(2).isReg() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3092, __PRETTY_FUNCTION__))
;
3093
3094 unsigned FirstReg = Inst.getOperand(0).getReg();
3095 unsigned SecondReg = Inst.getOperand(1).getReg();
3096 unsigned ThirdReg = Inst.getOperand(2).getReg();
3097
3098 if (hasMips1() && !hasMips2()) {
3099 unsigned ATReg = getATReg(IDLoc);
3100 if (!ATReg)
3101 return true;
3102 emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, Out, STI);
3103 emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, Out, STI);
3104 createNop(false, IDLoc, Out, STI);
3105 emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, Out, STI);
3106 emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, Out, STI);
3107 emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, Out, STI);
3108 createNop(false, IDLoc, Out, STI);
3109 emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3110 : Mips::CVT_W_S,
3111 FirstReg, SecondReg, IDLoc, Out, STI);
3112 emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, Out, STI);
3113 createNop(false, IDLoc, Out, STI);
3114 return false;
3115 }
3116
3117 emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3118 : Mips::TRUNC_W_S,
3119 FirstReg, SecondReg, IDLoc, Out, STI);
3120
3121 return false;
3122}
3123
3124bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3125 MCStreamer &Out, const MCSubtargetInfo *STI) {
3126 if (hasMips32r6() || hasMips64r6()) {
3127 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3128 return false;
3129 }
3130
3131 warnIfNoMacro(IDLoc);
3132
3133 const MCOperand &DstRegOp = Inst.getOperand(0);
3134 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3134, __PRETTY_FUNCTION__))
;
3135
3136 const MCOperand &SrcRegOp = Inst.getOperand(1);
3137 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3137, __PRETTY_FUNCTION__))
;
3138
3139 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3140 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3140, __PRETTY_FUNCTION__))
;
3141
3142 unsigned DstReg = DstRegOp.getReg();
3143 unsigned SrcReg = SrcRegOp.getReg();
3144 int64_t OffsetValue = OffsetImmOp.getImm();
3145
3146 // NOTE: We always need AT for ULHU, as it is always used as the source
3147 // register for one of the LBu's.
3148 unsigned ATReg = getATReg(IDLoc);
3149 if (!ATReg)
3150 return true;
3151
3152 // When the value of offset+1 does not fit in 16 bits, we have to load the
3153 // offset in AT, (D)ADDu the original source register (if there was one), and
3154 // then use AT as the source register for the 2 generated LBu's.
3155 bool LoadedOffsetInAT = false;
3156 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3157 LoadedOffsetInAT = true;
3158
3159 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3160 true, IDLoc, Out, STI))
3161 return true;
3162
3163 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3164 // because it will make our output more similar to GAS'. For example,
3165 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3166 // instead of just an "ori $1, $9, 32768".
3167 // NOTE: If there is no source register specified in the ULHU, the parser
3168 // will interpret it as $0.
3169 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3170 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Out, STI);
3171 }
3172
3173 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3174 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3175 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3176
3177 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3178 if (isLittle()) {
3179 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3180 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3181 } else {
3182 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3183 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3184 }
3185
3186 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3187
3188 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3189 FirstLbuOffset, IDLoc, Out, STI);
3190
3191 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc, Out,
3192 STI);
3193
3194 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Out, STI);
3195
3196 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Out, STI);
3197
3198 return false;
3199}
3200
3201bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3202 const MCSubtargetInfo *STI) {
3203 if (hasMips32r6() || hasMips64r6()) {
3204 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3205 return false;
3206 }
3207
3208 const MCOperand &DstRegOp = Inst.getOperand(0);
3209 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3209, __PRETTY_FUNCTION__))
;
3210
3211 const MCOperand &SrcRegOp = Inst.getOperand(1);
3212 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3212, __PRETTY_FUNCTION__))
;
3213
3214 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3215 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3215, __PRETTY_FUNCTION__))
;
3216
3217 unsigned SrcReg = SrcRegOp.getReg();
3218 int64_t OffsetValue = OffsetImmOp.getImm();
3219 unsigned ATReg = 0;
3220
3221 // When the value of offset+3 does not fit in 16 bits, we have to load the
3222 // offset in AT, (D)ADDu the original source register (if there was one), and
3223 // then use AT as the source register for the generated LWL and LWR.
3224 bool LoadedOffsetInAT = false;
3225 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3226 ATReg = getATReg(IDLoc);
3227 if (!ATReg)
3228 return true;
3229 LoadedOffsetInAT = true;
3230
3231 warnIfNoMacro(IDLoc);
3232
3233 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3234 true, IDLoc, Out, STI))
3235 return true;
3236
3237 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3238 // because it will make our output more similar to GAS'. For example,
3239 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3240 // instead of just an "ori $1, $9, 32768".
3241 // NOTE: If there is no source register specified in the ULW, the parser
3242 // will interpret it as $0.
3243 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3244 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Out, STI);
3245 }
3246
3247 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3248 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3249 if (isLittle()) {
3250 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3251 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3252 } else {
3253 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3254 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3255 }
3256
3257 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc, Out,
3258 STI);
3259
3260 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3261 Out, STI);
3262
3263 return false;
3264}
3265
3266bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3267 MCStreamer &Out,
3268 const MCSubtargetInfo *STI) {
3269
3270 assert (Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3270, __PRETTY_FUNCTION__))
;
3271 assert (Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3273, __PRETTY_FUNCTION__))
3272 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3273, __PRETTY_FUNCTION__))
3273 Inst.getOperand(2).isImm() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3273, __PRETTY_FUNCTION__))
;
3274
3275 unsigned ATReg = Mips::NoRegister;
3276 unsigned FinalDstReg = Mips::NoRegister;
3277 unsigned DstReg = Inst.getOperand(0).getReg();
3278 unsigned SrcReg = Inst.getOperand(1).getReg();
3279 int64_t ImmValue = Inst.getOperand(2).getImm();
3280
3281 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3282
3283 unsigned FinalOpcode = Inst.getOpcode();
3284
3285 if (DstReg == SrcReg) {
3286 ATReg = getATReg(Inst.getLoc());
3287 if (!ATReg)
3288 return true;
3289 FinalDstReg = DstReg;
3290 DstReg = ATReg;
3291 }
3292
3293 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
3294 switch (FinalOpcode) {
3295 default:
3296 llvm_unreachable("unimplemented expansion")::llvm::llvm_unreachable_internal("unimplemented expansion", "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3296)
;
3297 case (Mips::ADDi):
3298 FinalOpcode = Mips::ADD;
3299 break;
3300 case (Mips::ADDiu):
3301 FinalOpcode = Mips::ADDu;
3302 break;
3303 case (Mips::ANDi):
3304 FinalOpcode = Mips::AND;
3305 break;
3306 case (Mips::NORImm):
3307 FinalOpcode = Mips::NOR;
3308 break;
3309 case (Mips::ORi):
3310 FinalOpcode = Mips::OR;
3311 break;
3312 case (Mips::SLTi):
3313 FinalOpcode = Mips::SLT;
3314 break;
3315 case (Mips::SLTiu):
3316 FinalOpcode = Mips::SLTu;
3317 break;
3318 case (Mips::XORi):
3319 FinalOpcode = Mips::XOR;
3320 break;
3321 }
3322
3323 if (FinalDstReg == Mips::NoRegister)
3324 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Out, STI);
3325 else
3326 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, Out, STI);
3327 return false;
3328 }
3329 return true;
3330}
3331
3332bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3333 const MCSubtargetInfo *STI) {
3334 unsigned ATReg = Mips::NoRegister;
3335 unsigned DReg = Inst.getOperand(0).getReg();
3336 unsigned SReg = Inst.getOperand(1).getReg();
3337 unsigned TReg = Inst.getOperand(2).getReg();
3338 unsigned TmpReg = DReg;
3339
3340 unsigned FirstShift = Mips::NOP;
3341 unsigned SecondShift = Mips::NOP;
3342
3343 if (hasMips32r2()) {
3344
3345 if (DReg == SReg) {
3346 TmpReg = getATReg(Inst.getLoc());
3347 if (!TmpReg)
3348 return true;
3349 }
3350
3351 if (Inst.getOpcode() == Mips::ROL) {
3352 emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
3353 emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Out, STI);
3354 return false;
3355 }
3356
3357 if (Inst.getOpcode() == Mips::ROR) {
3358 emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
3359 return false;
3360 }
3361
3362 return true;
3363 }
3364
3365 if (hasMips32()) {
3366
3367 switch (Inst.getOpcode()) {
3368 default:
3369 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3369)
;
3370 case Mips::ROL:
3371 FirstShift = Mips::SRLV;
3372 SecondShift = Mips::SLLV;
3373 break;
3374 case Mips::ROR:
3375 FirstShift = Mips::SLLV;
3376 SecondShift = Mips::SRLV;
3377 break;
3378 }
3379
3380 ATReg = getATReg(Inst.getLoc());
3381 if (!ATReg)
3382 return true;
3383
3384 emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
3385 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Out, STI);
3386 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
3387 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
3388
3389 return false;
3390 }
3391
3392 return true;
3393}
3394
3395bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3396 MCStreamer &Out,
3397 const MCSubtargetInfo *STI) {
3398
3399 unsigned ATReg = Mips::NoRegister;
3400 unsigned DReg = Inst.getOperand(0).getReg();
3401 unsigned SReg = Inst.getOperand(1).getReg();
3402 int64_t ImmValue = Inst.getOperand(2).getImm();
3403
3404 unsigned FirstShift = Mips::NOP;
3405 unsigned SecondShift = Mips::NOP;
3406
3407 if (hasMips32r2()) {
3408
3409 if (Inst.getOpcode() == Mips::ROLImm) {
3410 uint64_t MaxShift = 32;
3411 uint64_t ShiftValue = ImmValue;
3412 if (ImmValue != 0)
3413 ShiftValue = MaxShift - ImmValue;
3414 emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), Out, STI);
3415 return false;
3416 }
3417
3418 if (Inst.getOpcode() == Mips::RORImm) {
3419 emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), Out, STI);
3420 return false;
3421 }
3422
3423 return true;
3424 }
3425
3426 if (hasMips32()) {
3427
3428 if (ImmValue == 0) {
3429 emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), Out, STI);
3430 return false;
3431 }
3432
3433 switch (Inst.getOpcode()) {
3434 default:
3435 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3435)
;
3436 case Mips::ROLImm:
3437 FirstShift = Mips::SLL;
3438 SecondShift = Mips::SRL;
3439 break;
3440 case Mips::RORImm:
3441 FirstShift = Mips::SRL;
3442 SecondShift = Mips::SLL;
3443 break;
3444 }
3445
3446 ATReg = getATReg(Inst.getLoc());
3447 if (!ATReg)
3448 return true;
3449
3450 emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), Out, STI);
3451 emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), Out, STI);
3452 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
3453
3454 return false;
3455 }
3456
3457 return true;
3458}
3459
3460bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3461 const MCSubtargetInfo *STI) {
3462
3463 unsigned ATReg = Mips::NoRegister;
3464 unsigned DReg = Inst.getOperand(0).getReg();
3465 unsigned SReg = Inst.getOperand(1).getReg();
3466 unsigned TReg = Inst.getOperand(2).getReg();
3467 unsigned TmpReg = DReg;
3468
3469 unsigned FirstShift = Mips::NOP;
3470 unsigned SecondShift = Mips::NOP;
3471
3472 if (hasMips64r2()) {
3473
3474 if (TmpReg == SReg) {
3475 TmpReg = getATReg(Inst.getLoc());
3476 if (!TmpReg)
3477 return true;
3478 }
3479
3480 if (Inst.getOpcode() == Mips::DROL) {
3481 emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
3482 emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Out, STI);
3483 return false;
3484 }
3485
3486 if (Inst.getOpcode() == Mips::DROR) {
3487 emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
3488 return false;
3489 }
3490
3491 return true;
3492 }
3493
3494 if (hasMips64()) {
3495
3496 switch (Inst.getOpcode()) {
3497 default:
3498 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3498)
;
3499 case Mips::DROL:
3500 FirstShift = Mips::DSRLV;
3501 SecondShift = Mips::DSLLV;
3502 break;
3503 case Mips::DROR:
3504 FirstShift = Mips::DSLLV;
3505 SecondShift = Mips::DSRLV;
3506 break;
3507 }
3508
3509 ATReg = getATReg(Inst.getLoc());
3510 if (!ATReg)
3511 return true;
3512
3513 emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
3514 emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Out, STI);
3515 emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
3516 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
3517
3518 return false;
3519 }
3520
3521 return true;
3522}
3523
3524bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3525 MCStreamer &Out,
3526 const MCSubtargetInfo *STI) {
3527
3528 unsigned ATReg = Mips::NoRegister;
3529 unsigned DReg = Inst.getOperand(0).getReg();
3530 unsigned SReg = Inst.getOperand(1).getReg();
3531 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3532
3533 unsigned FirstShift = Mips::NOP;
3534 unsigned SecondShift = Mips::NOP;
3535
3536 MCInst TmpInst;
3537
3538 if (hasMips64r2()) {
3539
3540 unsigned FinalOpcode = Mips::NOP;
3541 if (ImmValue == 0)
3542 FinalOpcode = Mips::DROTR;
3543 else if (ImmValue % 32 == 0)
3544 FinalOpcode = Mips::DROTR32;
3545 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3546 if (Inst.getOpcode() == Mips::DROLImm)
3547 FinalOpcode = Mips::DROTR32;
3548 else
3549 FinalOpcode = Mips::DROTR;
3550 } else if (ImmValue >= 33) {
3551 if (Inst.getOpcode() == Mips::DROLImm)
3552 FinalOpcode = Mips::DROTR;
3553 else
3554 FinalOpcode = Mips::DROTR32;
3555 }
3556
3557 uint64_t ShiftValue = ImmValue % 32;
3558 if (Inst.getOpcode() == Mips::DROLImm)
3559 ShiftValue = (32 - ImmValue % 32) % 32;
3560
3561 emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), Out, STI);
3562
3563 return false;
3564 }
3565
3566 if (hasMips64()) {
3567
3568 if (ImmValue == 0) {
3569 emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), Out, STI);
3570 return false;
3571 }
3572
3573 switch (Inst.getOpcode()) {
3574 default:
3575 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3575)
;
3576 case Mips::DROLImm:
3577 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3578 FirstShift = Mips::DSLL;
3579 SecondShift = Mips::DSRL32;
3580 }
3581 if (ImmValue == 32) {
3582 FirstShift = Mips::DSLL32;
3583 SecondShift = Mips::DSRL32;
3584 }
3585 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3586 FirstShift = Mips::DSLL32;
3587 SecondShift = Mips::DSRL;
3588 }
3589 break;
3590 case Mips::DRORImm:
3591 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3592 FirstShift = Mips::DSRL;
3593 SecondShift = Mips::DSLL32;
3594 }
3595 if (ImmValue == 32) {
3596 FirstShift = Mips::DSRL32;
3597 SecondShift = Mips::DSLL32;
3598 }
3599 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3600 FirstShift = Mips::DSRL32;
3601 SecondShift = Mips::DSLL;
3602 }
3603 break;
3604 }
3605
3606 ATReg = getATReg(Inst.getLoc());
3607 if (!ATReg)
3608 return true;
3609
3610 emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), Out, STI);
3611 emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, Inst.getLoc(), Out, STI);
3612 emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
3613
3614 return false;
3615 }
3616
3617 return true;
3618}
3619
3620bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3621 const MCSubtargetInfo *STI) {
3622
3623 unsigned FirstRegOp = Inst.getOperand(0).getReg();
3624 unsigned SecondRegOp = Inst.getOperand(1).getReg();
3625
3626 emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, Out, STI);
3627 if (FirstRegOp != SecondRegOp)
3628 emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, Out, STI);
3629 else
3630 createNop(false, IDLoc, Out, STI);
3631 emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, Out, STI);
3632
3633 return false;
3634}
3635
3636void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3637 MCStreamer &Out, const MCSubtargetInfo *STI) {
3638 if (hasShortDelaySlot)
3639 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Out, STI);
3640 else
3641 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Out, STI);
3642}
3643
3644void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3645 unsigned TrgReg, bool Is64Bit, MCStreamer &Out,
3646 const MCSubtargetInfo *STI) {
3647 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3648 Out, STI);
3649}
3650
3651void MipsAsmParser::createCpRestoreMemOp(bool IsLoad, int StackOffset,
3652 SMLoc IDLoc, MCStreamer &Out,
3653 const MCSubtargetInfo *STI) {
3654 // If the offset can not fit into 16 bits, we need to expand.
3655 if (!isInt<16>(StackOffset)) {
3656 MCInst MemInst;
3657 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3658 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3659 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3660 MemInst.addOperand(MCOperand::createImm(StackOffset));
3661 expandMemInst(MemInst, IDLoc, Out, STI, IsLoad, true /*HasImmOpnd*/);
3662 return;
3663 }
3664
3665 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3666 Out, STI);
3667}
3668
3669unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3670 // As described by the Mips32r2 spec, the registers Rd and Rs for
3671 // jalr.hb must be different.
3672 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
3673 unsigned Opcode = Inst.getOpcode();
3674
3675 if ((Opcode == Mips::JALR_HB || Opcode == Mips::JALRC_HB_MMR6) &&
3676 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3677 return Match_RequiresDifferentSrcAndDst;
3678
3679 return Match_Success;
3680}
3681
3682static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3683 uint64_t ErrorInfo) {
3684 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3685 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3686 if (ErrorLoc == SMLoc())
3687 return Loc;
3688 return ErrorLoc;
3689 }
3690 return Loc;
3691}
3692
3693bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3694 OperandVector &Operands,
3695 MCStreamer &Out,
3696 uint64_t &ErrorInfo,
3697 bool MatchingInlineAsm) {
3698
3699 MCInst Inst;
3700 unsigned MatchResult =
3701 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3702
3703 switch (MatchResult) {
3704 case Match_Success: {
3705 if (processInstruction(Inst, IDLoc, Out, STI))
3706 return true;
3707 return false;
3708 }
3709 case Match_MissingFeature:
3710 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3711 return true;
3712 case Match_InvalidOperand: {
3713 SMLoc ErrorLoc = IDLoc;
3714 if (ErrorInfo != ~0ULL) {
3715 if (ErrorInfo >= Operands.size())
3716 return Error(IDLoc, "too few operands for instruction");
3717
3718 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3719 if (ErrorLoc == SMLoc())
3720 ErrorLoc = IDLoc;
3721 }
3722
3723 return Error(ErrorLoc, "invalid operand for instruction");
3724 }
3725 case Match_MnemonicFail:
3726 return Error(IDLoc, "invalid instruction");
3727 case Match_RequiresDifferentSrcAndDst:
3728 return Error(IDLoc, "source and destination must be different");
3729 case Match_Immz:
3730 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3731 case Match_UImm1_0:
3732 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3733 "expected 1-bit unsigned immediate");
3734 case Match_UImm2_0:
3735 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3736 "expected 2-bit unsigned immediate");
3737 case Match_UImm2_1:
3738 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3739 "expected immediate in range 1 .. 4");
3740 case Match_UImm3_0:
3741 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3742 "expected 3-bit unsigned immediate");
3743 case Match_UImm4_0:
3744 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3745 "expected 4-bit unsigned immediate");
3746 case Match_SImm4_0:
3747 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3748 "expected 4-bit signed immediate");
3749 case Match_UImm5_0:
3750 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3751 "expected 5-bit unsigned immediate");
3752 case Match_SImm5_0:
3753 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3754 "expected 5-bit signed immediate");
3755 case Match_UImm5_1:
3756 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3757 "expected immediate in range 1 .. 32");
3758 case Match_UImm5_32:
3759 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3760 "expected immediate in range 32 .. 63");
3761 case Match_UImm5_33:
3762 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3763 "expected immediate in range 33 .. 64");
3764 case Match_UImm5_0_Report_UImm6:
3765 // This is used on UImm5 operands that have a corresponding UImm5_32
3766 // operand to avoid confusing the user.
3767 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3768 "expected 6-bit unsigned immediate");
3769 case Match_UImm5_Lsl2:
3770 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3771 "expected both 7-bit unsigned immediate and multiple of 4");
3772 case Match_UImmRange2_64:
3773 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3774 "expected immediate in range 2 .. 64");
3775 case Match_UImm6_0:
3776 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3777 "expected 6-bit unsigned immediate");
3778 case Match_UImm6_Lsl2:
3779 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3780 "expected both 8-bit unsigned immediate and multiple of 4");
3781 case Match_SImm6_0:
3782 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3783 "expected 6-bit signed immediate");
3784 case Match_UImm7_0:
3785 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3786 "expected 7-bit unsigned immediate");
3787 case Match_UImm7_N1:
3788 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3789 "expected immediate in range -1 .. 126");
3790 case Match_SImm7_Lsl2:
3791 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3792 "expected both 9-bit signed immediate and multiple of 4");
3793 case Match_UImm8_0:
3794 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3795 "expected 8-bit unsigned immediate");
3796 case Match_UImm10_0:
3797 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3798 "expected 10-bit unsigned immediate");
3799 case Match_SImm10_0:
3800 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3801 "expected 10-bit signed immediate");
3802 case Match_SImm11_0:
3803 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3804 "expected 11-bit signed immediate");
3805 case Match_UImm16:
3806 case Match_UImm16_Relaxed:
3807 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3808 "expected 16-bit unsigned immediate");
3809 case Match_SImm16:
3810 case Match_SImm16_Relaxed:
3811 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3812 "expected 16-bit signed immediate");
3813 case Match_UImm20_0:
3814 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3815 "expected 20-bit unsigned immediate");
3816 case Match_UImm26_0:
3817 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3818 "expected 26-bit unsigned immediate");
3819 case Match_SImm32:
3820 case Match_SImm32_Relaxed:
3821 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3822 "expected 32-bit signed immediate");
3823 case Match_MemSImm9:
3824 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3825 "expected memory with 9-bit signed offset");
3826 case Match_MemGPSImm9:
3827 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3828 "expected memory with $gp and 9-bit signed offset");
3829 case Match_MemSImm10:
3830 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3831 "expected memory with 10-bit signed offset");
3832 case Match_MemSImm10Lsl1:
3833 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3834 "expected memory with 11-bit signed offset and multiple of 2");
3835 case Match_MemSImm10Lsl2:
3836 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3837 "expected memory with 12-bit signed offset and multiple of 4");
3838 case Match_MemSImm10Lsl3:
3839 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3840 "expected memory with 13-bit signed offset and multiple of 8");
3841 case Match_MemSImm11:
3842 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3843 "expected memory with 11-bit signed offset");
3844 case Match_MemSImm16:
3845 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3846 "expected memory with 16-bit signed offset");
3847 }
3848
3849 llvm_unreachable("Implement any new match types added!")::llvm::llvm_unreachable_internal("Implement any new match types added!"
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3849)
;
3850}
3851
3852void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3853 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3854 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3855 ") without \".set noat\"");
3856}
3857
3858void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3859 if (!AssemblerOptions.back()->isMacro())
3860 Warning(Loc, "macro instruction expanded into multiple instructions");
3861}
3862
3863void
3864MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3865 SMRange Range, bool ShowColors) {
3866 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3867 Range, SMFixIt(Range, FixMsg),
3868 ShowColors);
3869}
3870
3871int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3872 int CC;
3873
3874 CC = StringSwitch<unsigned>(Name)
3875 .Case("zero", 0)
3876 .Case("at", 1)
3877 .Case("a0", 4)
3878 .Case("a1", 5)
3879 .Case("a2", 6)
3880 .Case("a3", 7)
3881 .Case("v0", 2)
3882 .Case("v1", 3)
3883 .Case("s0", 16)
3884 .Case("s1", 17)
3885 .Case("s2", 18)
3886 .Case("s3", 19)
3887 .Case("s4", 20)
3888 .Case("s5", 21)
3889 .Case("s6", 22)
3890 .Case("s7", 23)
3891 .Case("k0", 26)
3892 .Case("k1", 27)
3893 .Case("gp", 28)
3894 .Case("sp", 29)
3895 .Case("fp", 30)
3896 .Case("s8", 30)
3897 .Case("ra", 31)
3898 .Case("t0", 8)
3899 .Case("t1", 9)
3900 .Case("t2", 10)
3901 .Case("t3", 11)
3902 .Case("t4", 12)
3903 .Case("t5", 13)
3904 .Case("t6", 14)
3905 .Case("t7", 15)
3906 .Case("t8", 24)
3907 .Case("t9", 25)
3908 .Default(-1);
3909
3910 if (!(isABI_N32() || isABI_N64()))
3911 return CC;
3912
3913 if (12 <= CC && CC <= 15) {
3914 // Name is one of t4-t7
3915 AsmToken RegTok = getLexer().peekTok();
3916 SMRange RegRange = RegTok.getLocRange();
3917
3918 StringRef FixedName = StringSwitch<StringRef>(Name)
3919 .Case("t4", "t0")
3920 .Case("t5", "t1")
3921 .Case("t6", "t2")
3922 .Case("t7", "t3")
3923 .Default("");
3924 assert(FixedName != "" && "Register name is not one of t4-t7.")((FixedName != "" && "Register name is not one of t4-t7."
) ? static_cast<void> (0) : __assert_fail ("FixedName != \"\" && \"Register name is not one of t4-t7.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3924, __PRETTY_FUNCTION__))
;
3925
3926 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3927 "Did you mean $" + FixedName + "?", RegRange);
3928 }
3929
3930 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3931 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3932 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3933 if (8 <= CC && CC <= 11)
3934 CC += 4;
3935
3936 if (CC == -1)
3937 CC = StringSwitch<unsigned>(Name)
3938 .Case("a4", 8)
3939 .Case("a5", 9)
3940 .Case("a6", 10)
3941 .Case("a7", 11)
3942 .Case("kt0", 26)
3943 .Case("kt1", 27)
3944 .Default(-1);
3945
3946 return CC;
3947}
3948
3949int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3950 int CC;
3951
3952 CC = StringSwitch<unsigned>(Name)
3953 .Case("hwr_cpunum", 0)
3954 .Case("hwr_synci_step", 1)
3955 .Case("hwr_cc", 2)
3956 .Case("hwr_ccres", 3)
3957 .Case("hwr_ulr", 29)
3958 .Default(-1);
3959
3960 return CC;
3961}
3962
3963int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3964
3965 if (Name[0] == 'f') {
3966 StringRef NumString = Name.substr(1);
3967 unsigned IntVal;
3968 if (NumString.getAsInteger(10, IntVal))
3969 return -1; // This is not an integer.
3970 if (IntVal > 31) // Maximum index for fpu register.
3971 return -1;
3972 return IntVal;
3973 }
3974 return -1;
3975}
3976
3977int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3978
3979 if (Name.startswith("fcc")) {
3980 StringRef NumString = Name.substr(3);
3981 unsigned IntVal;
3982 if (NumString.getAsInteger(10, IntVal))
3983 return -1; // This is not an integer.
3984 if (IntVal > 7) // There are only 8 fcc registers.
3985 return -1;
3986 return IntVal;
3987 }
3988 return -1;
3989}
3990
3991int MipsAsmParser::matchACRegisterName(StringRef Name) {
3992
3993 if (Name.startswith("ac")) {
3994 StringRef NumString = Name.substr(2);
3995 unsigned IntVal;
3996 if (NumString.getAsInteger(10, IntVal))
3997 return -1; // This is not an integer.
3998 if (IntVal > 3) // There are only 3 acc registers.
3999 return -1;
4000 return IntVal;
4001 }
4002 return -1;
4003}
4004
4005int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
4006 unsigned IntVal;
4007
4008 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
4009 return -1;
4010
4011 if (IntVal > 31)
4012 return -1;
4013
4014 return IntVal;
4015}
4016
4017int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4018 int CC;
4019
4020 CC = StringSwitch<unsigned>(Name)
4021 .Case("msair", 0)
4022 .Case("msacsr", 1)
4023 .Case("msaaccess", 2)
4024 .Case("msasave", 3)
4025 .Case("msamodify", 4)
4026 .Case("msarequest", 5)
4027 .Case("msamap", 6)
4028 .Case("msaunmap", 7)
4029 .Default(-1);
4030
4031 return CC;
4032}
4033
4034unsigned MipsAsmParser::getATReg(SMLoc Loc) {
4035 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4036 if (ATIndex == 0) {
4037 reportParseError(Loc,
4038 "pseudo-instruction requires $at, which is not available");
4039 return 0;
4040 }
4041 unsigned AT = getReg(
4042 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4043 return AT;
4044}
4045
4046unsigned MipsAsmParser::getReg(int RC, int RegNo) {
4047 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4048}
4049
4050unsigned MipsAsmParser::getGPR(int RegNo) {
4051 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
4052 RegNo);
4053}
4054
4055int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
4056 if (RegNum >
4057 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
4058 return -1;
4059
4060 return getReg(RegClass, RegNum);
4061}
4062
4063bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
4064 MCAsmParser &Parser = getParser();
4065 DEBUG(dbgs() << "parseOperand\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseOperand\n"; } } while
(0)
;
4066
4067 // Check if the current operand has a custom associated parser, if so, try to
4068 // custom parse the operand, or fallback to the general approach.
4069 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4070 if (ResTy == MatchOperand_Success)
4071 return false;
4072 // If there wasn't a custom match, try the generic matcher below. Otherwise,
4073 // there was a match, but an error occurred, in which case, just return that
4074 // the operand parsing failed.
4075 if (ResTy == MatchOperand_ParseFail)
4076 return true;
4077
4078 DEBUG(dbgs() << ".. Generic Parser\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. Generic Parser\n";
} } while (0)
;
4079
4080 switch (getLexer().getKind()) {
4081 default:
4082 Error(Parser.getTok().getLoc(), "unexpected token in operand");
4083 return true;
4084 case AsmToken::Dollar: {
4085 // Parse the register.
4086 SMLoc S = Parser.getTok().getLoc();
4087
4088 // Almost all registers have been parsed by custom parsers. There is only
4089 // one exception to this. $zero (and it's alias $0) will reach this point
4090 // for div, divu, and similar instructions because it is not an operand
4091 // to the instruction definition but an explicit register. Special case
4092 // this situation for now.
4093 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
4094 return false;
4095
4096 // Maybe it is a symbol reference.
4097 StringRef Identifier;
4098 if (Parser.parseIdentifier(Identifier))
4099 return true;
4100
4101 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4102 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
4103 // Otherwise create a symbol reference.
4104 const MCExpr *Res =
4105 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
4106
4107 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
4108 return false;
4109 }
4110 // Else drop to expression parsing.
4111 case AsmToken::LParen:
4112 case AsmToken::Minus:
4113 case AsmToken::Plus:
4114 case AsmToken::Integer:
4115 case AsmToken::Tilde:
4116 case AsmToken::String: {
4117 DEBUG(dbgs() << ".. generic integer\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. generic integer\n"
; } } while (0)
;
4118 OperandMatchResultTy ResTy = parseImm(Operands);
4119 return ResTy != MatchOperand_Success;
4120 }
4121 case AsmToken::Percent: {
4122 // It is a symbol reference or constant expression.
4123 const MCExpr *IdVal;
4124 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
4125 if (parseRelocOperand(IdVal))
4126 return true;
4127
4128 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4129
4130 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4131 return false;
4132 } // case AsmToken::Percent
4133 } // switch(getLexer().getKind())
4134 return true;
4135}
4136
4137const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
4138 StringRef RelocStr) {
4139 const MCExpr *Res;
4140 // Check the type of the expression.
4141 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
4142 // It's a constant, evaluate reloc value.
4143 int16_t Val;
4144 switch (getVariantKind(RelocStr)) {
4145 case MCSymbolRefExpr::VK_Mips_ABS_LO:
4146 // Get the 1st 16-bits.
4147 Val = MCE->getValue() & 0xffff;
4148 break;
4149 case MCSymbolRefExpr::VK_Mips_ABS_HI:
4150 case MCSymbolRefExpr::VK_Mips_GOT:
4151 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
4152 // 16 bits being negative.
4153 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
4154 break;
4155 case MCSymbolRefExpr::VK_Mips_HIGHER:
4156 // Get the 3rd 16-bits.
4157 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
4158 break;
4159 case MCSymbolRefExpr::VK_Mips_HIGHEST:
4160 // Get the 4th 16-bits.
4161 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
4162 break;
4163 default:
4164 report_fatal_error("unsupported reloc value");
4165 }
4166 return MCConstantExpr::create(Val, getContext());
4167 }
4168
4169 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
4170 // It's a symbol, create a symbolic expression from the symbol.
4171 const MCSymbol *Symbol = &MSRE->getSymbol();
4172 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
4173 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
4174 return Res;
4175 }
4176
4177 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4178 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
4179
4180 // Try to create target expression.
4181 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
4182 return MipsMCExpr::create(VK, Expr, getContext());
4183
4184 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
4185 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
4186 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
4187 return Res;
4188 }
4189
4190 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
4191 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
4192 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
4193 return Res;
4194 }
4195 // Just return the original expression.
4196 return Expr;
4197}
4198
4199bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4200
4201 switch (Expr->getKind()) {
4202 case MCExpr::Constant:
4203 return true;
4204 case MCExpr::SymbolRef:
4205 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4206 case MCExpr::Binary:
4207 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4208 if (!isEvaluated(BE->getLHS()))
4209 return false;
4210 return isEvaluated(BE->getRHS());
4211 }
4212 case MCExpr::Unary:
4213 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4214 case MCExpr::Target:
4215 return true;
4216 }
4217 return false;
4218}
4219
4220bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
4221 MCAsmParser &Parser = getParser();
4222 Parser.Lex(); // Eat the % token.
4223 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
4224 if (Tok.isNot(AsmToken::Identifier))
4225 return true;
4226
4227 std::string Str = Tok.getIdentifier();
4228
4229 Parser.Lex(); // Eat the identifier.
4230 // Now make an expression from the rest of the operand.
4231 const MCExpr *IdVal;
4232 SMLoc EndLoc;
4233
4234 if (getLexer().getKind() == AsmToken::LParen) {
4235 while (1) {
4236 Parser.Lex(); // Eat the '(' token.
4237 if (getLexer().getKind() == AsmToken::Percent) {
4238 Parser.Lex(); // Eat the % token.
4239 const AsmToken &nextTok = Parser.getTok();
4240 if (nextTok.isNot(AsmToken::Identifier))
4241 return true;
4242 Str += "(%";
4243 Str += nextTok.getIdentifier();
4244 Parser.Lex(); // Eat the identifier.
4245 if (getLexer().getKind() != AsmToken::LParen)
4246 return true;
4247 } else
4248 break;
4249 }
4250 if (getParser().parseParenExpression(IdVal, EndLoc))
4251 return true;
4252
4253 while (getLexer().getKind() == AsmToken::RParen)
4254 Parser.Lex(); // Eat the ')' token.
4255
4256 } else
4257 return true; // Parenthesis must follow the relocation operand.
4258
4259 Res = evaluateRelocExpr(IdVal, Str);
4260 return false;
4261}
4262
4263bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4264 SMLoc &EndLoc) {
4265 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4266 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4267 if (ResTy == MatchOperand_Success) {
4268 assert(Operands.size() == 1)((Operands.size() == 1) ? static_cast<void> (0) : __assert_fail
("Operands.size() == 1", "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4268, __PRETTY_FUNCTION__))
;
4269 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4270 StartLoc = Operand.getStartLoc();
4271 EndLoc = Operand.getEndLoc();
4272
4273 // AFAIK, we only support numeric registers and named GPR's in CFI
4274 // directives.
4275 // Don't worry about eating tokens before failing. Using an unrecognised
4276 // register is a parse error.
4277 if (Operand.isGPRAsmReg()) {
4278 // Resolve to GPR32 or GPR64 appropriately.
4279 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4280 }
4281
4282 return (RegNo == (unsigned)-1);
4283 }
4284
4285 assert(Operands.size() == 0)((Operands.size() == 0) ? static_cast<void> (0) : __assert_fail
("Operands.size() == 0", "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4285, __PRETTY_FUNCTION__))
;
4286 return (RegNo == (unsigned)-1);
4287}
4288
4289bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4290 MCAsmParser &Parser = getParser();
4291 SMLoc S;
4292 bool Result = true;
4293 unsigned NumOfLParen = 0;
4294
4295 while (getLexer().getKind() == AsmToken::LParen) {
4296 Parser.Lex();
4297 ++NumOfLParen;
4298 }
4299
4300 switch (getLexer().getKind()) {
4301 default:
4302 return true;
4303 case AsmToken::Identifier:
4304 case AsmToken::LParen:
4305 case AsmToken::Integer:
4306 case AsmToken::Minus:
4307 case AsmToken::Plus:
4308 if (isParenExpr)
4309 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
4310 else
4311 Result = (getParser().parseExpression(Res));
4312 while (getLexer().getKind() == AsmToken::RParen)
4313 Parser.Lex();
4314 break;
4315 case AsmToken::Percent:
4316 Result = parseRelocOperand(Res);
4317 }
4318 return Result;
4319}
4320
4321MipsAsmParser::OperandMatchResultTy
4322MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4323 MCAsmParser &Parser = getParser();
4324 DEBUG(dbgs() << "parseMemOperand\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseMemOperand\n"; }
} while (0)
;
4325 const MCExpr *IdVal = nullptr;
4326 SMLoc S;
4327 bool isParenExpr = false;
4328 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
4329 // First operand is the offset.
4330 S = Parser.getTok().getLoc();
4331
4332 if (getLexer().getKind() == AsmToken::LParen) {
4333 Parser.Lex();
4334 isParenExpr = true;
4335 }
4336
4337 if (getLexer().getKind() != AsmToken::Dollar) {
4338 if (parseMemOffset(IdVal, isParenExpr))
4339 return MatchOperand_ParseFail;
4340
4341 const AsmToken &Tok = Parser.getTok(); // Get the next token.
4342 if (Tok.isNot(AsmToken::LParen)) {
4343 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4344 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4345 SMLoc E =
4346 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4347 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4348 return MatchOperand_Success;
4349 }
4350 if (Tok.is(AsmToken::EndOfStatement)) {
4351 SMLoc E =
4352 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4353
4354 // Zero register assumed, add a memory operand with ZERO as its base.
4355 // "Base" will be managed by k_Memory.
4356 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
4357 S, E, *this);
4358 Operands.push_back(
4359 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4360 return MatchOperand_Success;
4361 }
4362 Error(Parser.getTok().getLoc(), "'(' expected");
4363 return MatchOperand_ParseFail;
4364 }
4365
4366 Parser.Lex(); // Eat the '(' token.
4367 }
4368
4369 Res = parseAnyRegister(Operands);
4370 if (Res != MatchOperand_Success)
4371 return Res;
4372
4373 if (Parser.getTok().isNot(AsmToken::RParen)) {
4374 Error(Parser.getTok().getLoc(), "')' expected");
4375 return MatchOperand_ParseFail;
4376 }
4377
4378 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4379
4380 Parser.Lex(); // Eat the ')' token.
4381
4382 if (!IdVal)
4383 IdVal = MCConstantExpr::create(0, getContext());
4384
4385 // Replace the register operand with the memory operand.
4386 std::unique_ptr<MipsOperand> op(
4387 static_cast<MipsOperand *>(Operands.back().release()));
4388 // Remove the register from the operands.
4389 // "op" will be managed by k_Memory.
4390 Operands.pop_back();
4391 // Add the memory operand.
4392 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4393 int64_t Imm;
4394 if (IdVal->evaluateAsAbsolute(Imm))
4395 IdVal = MCConstantExpr::create(Imm, getContext());
4396 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4397 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4398 getContext());
4399 }
4400
4401 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4402 return MatchOperand_Success;
4403}
4404
4405bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4406 MCAsmParser &Parser = getParser();
4407 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4408 if (Sym) {
4409 SMLoc S = Parser.getTok().getLoc();
4410 const MCExpr *Expr;
4411 if (Sym->isVariable())
4412 Expr = Sym->getVariableValue();
4413 else
4414 return false;
4415 if (Expr->getKind() == MCExpr::SymbolRef) {
4416 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4417 StringRef DefSymbol = Ref->getSymbol().getName();
4418 if (DefSymbol.startswith("$")) {
4419 OperandMatchResultTy ResTy =
4420 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4421 if (ResTy == MatchOperand_Success) {
4422 Parser.Lex();
4423 return true;
4424 } else if (ResTy == MatchOperand_ParseFail)
4425 llvm_unreachable("Should never ParseFail")::llvm::llvm_unreachable_internal("Should never ParseFail", "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4425)
;
4426 return false;
4427 }
4428 } else if (Expr->getKind() == MCExpr::Constant) {
4429 Parser.Lex();
4430 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
4431 Operands.push_back(
4432 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
4433 return true;
4434 }
4435 }
4436 return false;
4437}
4438
4439MipsAsmParser::OperandMatchResultTy
4440MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4441 StringRef Identifier,
4442 SMLoc S) {
4443 int Index = matchCPURegisterName(Identifier);
4444 if (Index != -1) {
4445 Operands.push_back(MipsOperand::createGPRReg(
4446 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4447 return MatchOperand_Success;
4448 }
4449
4450 Index = matchHWRegsRegisterName(Identifier);
4451 if (Index != -1) {
4452 Operands.push_back(MipsOperand::createHWRegsReg(
4453 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4454 return MatchOperand_Success;
4455 }
4456
4457 Index = matchFPURegisterName(Identifier);
4458 if (Index != -1) {
4459 Operands.push_back(MipsOperand::createFGRReg(
4460 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4461 return MatchOperand_Success;
4462 }
4463
4464 Index = matchFCCRegisterName(Identifier);
4465 if (Index != -1) {
4466 Operands.push_back(MipsOperand::createFCCReg(
4467 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4468 return MatchOperand_Success;
4469 }
4470
4471 Index = matchACRegisterName(Identifier);
4472 if (Index != -1) {
4473 Operands.push_back(MipsOperand::createACCReg(
4474 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4475 return MatchOperand_Success;
4476 }
4477
4478 Index = matchMSA128RegisterName(Identifier);
4479 if (Index != -1) {
4480 Operands.push_back(MipsOperand::createMSA128Reg(
4481 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4482 return MatchOperand_Success;
4483 }
4484
4485 Index = matchMSA128CtrlRegisterName(Identifier);
4486 if (Index != -1) {
4487 Operands.push_back(MipsOperand::createMSACtrlReg(
4488 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4489 return MatchOperand_Success;
4490 }
4491
4492 return MatchOperand_NoMatch;
4493}
4494
4495MipsAsmParser::OperandMatchResultTy
4496MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4497 MCAsmParser &Parser = getParser();
4498 auto Token = Parser.getLexer().peekTok(false);
4499
4500 if (Token.is(AsmToken::Identifier)) {
4501 DEBUG(dbgs() << ".. identifier\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. identifier\n"; } }
while (0)
;
4502 StringRef Identifier = Token.getIdentifier();
4503 OperandMatchResultTy ResTy =
4504 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4505 return ResTy;
4506 } else if (Token.is(AsmToken::Integer)) {
4507 DEBUG(dbgs() << ".. integer\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. integer\n"; } } while
(0)
;
4508 Operands.push_back(MipsOperand::createNumericReg(
4509 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
4510 *this));
4511 return MatchOperand_Success;
4512 }
4513
4514 DEBUG(dbgs() << Parser.getTok().getKind() << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << Parser.getTok().getKind
() << "\n"; } } while (0)
;
4515
4516 return MatchOperand_NoMatch;
4517}
4518
4519MipsAsmParser::OperandMatchResultTy
4520MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4521 MCAsmParser &Parser = getParser();
4522 DEBUG(dbgs() << "parseAnyRegister\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseAnyRegister\n"; }
} while (0)
;
4523
4524 auto Token = Parser.getTok();
4525
4526 SMLoc S = Token.getLoc();
4527
4528 if (Token.isNot(AsmToken::Dollar)) {
4529 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. !$ -> try sym aliasing\n"
; } } while (0)
;
4530 if (Token.is(AsmToken::Identifier)) {
4531 if (searchSymbolAlias(Operands))
4532 return MatchOperand_Success;
4533 }
4534 DEBUG(dbgs() << ".. !symalias -> NoMatch\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. !symalias -> NoMatch\n"
; } } while (0)
;
4535 return MatchOperand_NoMatch;
4536 }
4537 DEBUG(dbgs() << ".. $\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << ".. $\n"; } } while (0
)
;
4538
4539 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4540 if (ResTy == MatchOperand_Success) {
4541 Parser.Lex(); // $
4542 Parser.Lex(); // identifier
4543 }
4544 return ResTy;
4545}
4546
4547MipsAsmParser::OperandMatchResultTy
4548MipsAsmParser::parseImm(OperandVector &Operands) {
4549 MCAsmParser &Parser = getParser();
4550 switch (getLexer().getKind()) {
4551 default:
4552 return MatchOperand_NoMatch;
4553 case AsmToken::LParen:
4554 case AsmToken::Minus:
4555 case AsmToken::Plus:
4556 case AsmToken::Integer:
4557 case AsmToken::Tilde:
4558 case AsmToken::String:
4559 break;
4560 }
4561
4562 const MCExpr *IdVal;
4563 SMLoc S = Parser.getTok().getLoc();
4564 if (getParser().parseExpression(IdVal))
4565 return MatchOperand_ParseFail;
4566
4567 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4568 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4569 return MatchOperand_Success;
4570}
4571
4572MipsAsmParser::OperandMatchResultTy
4573MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4574 MCAsmParser &Parser = getParser();
4575 DEBUG(dbgs() << "parseJumpTarget\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "parseJumpTarget\n"; }
} while (0)
;
4576
4577 SMLoc S = getLexer().getLoc();
4578
4579 // Integers and expressions are acceptable
4580 OperandMatchResultTy ResTy = parseImm(Operands);
4581 if (ResTy != MatchOperand_NoMatch)
4582 return ResTy;
4583
4584 // Registers are a valid target and have priority over symbols.
4585 ResTy = parseAnyRegister(Operands);
4586 if (ResTy != MatchOperand_NoMatch)
4587 return ResTy;
4588
4589 const MCExpr *Expr = nullptr;
4590 if (Parser.parseExpression(Expr)) {
4591 // We have no way of knowing if a symbol was consumed so we must ParseFail
4592 return MatchOperand_ParseFail;
4593 }
4594 Operands.push_back(
4595 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4596 return MatchOperand_Success;
4597}
4598
4599MipsAsmParser::OperandMatchResultTy
4600MipsAsmParser::parseInvNum(OperandVector &Operands) {
4601 MCAsmParser &Parser = getParser();
4602 const MCExpr *IdVal;
4603 // If the first token is '$' we may have register operand.
4604 if (Parser.getTok().is(AsmToken::Dollar))
4605 return MatchOperand_NoMatch;
4606 SMLoc S = Parser.getTok().getLoc();
4607 if (getParser().parseExpression(IdVal))
4608 return MatchOperand_ParseFail;
4609 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4610 assert(MCE && "Unexpected MCExpr type.")((MCE && "Unexpected MCExpr type.") ? static_cast<
void> (0) : __assert_fail ("MCE && \"Unexpected MCExpr type.\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4610, __PRETTY_FUNCTION__))
;
4611 int64_t Val = MCE->getValue();
4612 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4613 Operands.push_back(MipsOperand::CreateImm(
4614 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4615 return MatchOperand_Success;
4616}
4617
4618MipsAsmParser::OperandMatchResultTy
4619MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4620 MCAsmParser &Parser = getParser();
4621 switch (getLexer().getKind()) {
4622 default:
4623 return MatchOperand_NoMatch;
4624 case AsmToken::LParen:
4625 case AsmToken::Plus:
4626 case AsmToken::Minus:
4627 case AsmToken::Integer:
4628 break;
4629 }
4630
4631 const MCExpr *Expr;
4632 SMLoc S = Parser.getTok().getLoc();
4633
4634 if (getParser().parseExpression(Expr))
4635 return MatchOperand_ParseFail;
4636
4637 int64_t Val;
4638 if (!Expr->evaluateAsAbsolute(Val)) {
4639 Error(S, "expected immediate value");
4640 return MatchOperand_ParseFail;
4641 }
4642
4643 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4644 // and because the CPU always adds one to the immediate field, the allowed
4645 // range becomes 1..4. We'll only check the range here and will deal
4646 // with the addition/subtraction when actually decoding/encoding
4647 // the instruction.
4648 if (Val < 1 || Val > 4) {
4649 Error(S, "immediate not in range (1..4)");
4650 return MatchOperand_ParseFail;
4651 }
4652
4653 Operands.push_back(
4654 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4655 return MatchOperand_Success;
4656}
4657
4658MipsAsmParser::OperandMatchResultTy
4659MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4660 MCAsmParser &Parser = getParser();
4661 SmallVector<unsigned, 10> Regs;
4662 unsigned RegNo;
4663 unsigned PrevReg = Mips::NoRegister;
4664 bool RegRange = false;
4665 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4666
4667 if (Parser.getTok().isNot(AsmToken::Dollar))
4668 return MatchOperand_ParseFail;
4669
4670 SMLoc S = Parser.getTok().getLoc();
4671 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4672 SMLoc E = getLexer().getLoc();
4673 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4674 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4675 if (RegRange) {
4676 // Remove last register operand because registers from register range
4677 // should be inserted first.
4678 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4679 (!isGP64bit() && RegNo == Mips::RA)) {
4680 Regs.push_back(RegNo);
4681 } else {
4682 unsigned TmpReg = PrevReg + 1;
4683 while (TmpReg <= RegNo) {
4684 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4685 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4686 isGP64bit())) {
4687 Error(E, "invalid register operand");
4688 return MatchOperand_ParseFail;
4689 }
4690
4691 PrevReg = TmpReg;
4692 Regs.push_back(TmpReg++);
4693 }
4694 }
4695
4696 RegRange = false;
4697 } else {
4698 if ((PrevReg == Mips::NoRegister) &&
4699 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4700 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4701 Error(E, "$16 or $31 expected");
4702 return MatchOperand_ParseFail;
4703 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4704 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4705 !isGP64bit()) ||
4706 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4707 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4708 isGP64bit()))) {
4709 Error(E, "invalid register operand");
4710 return MatchOperand_ParseFail;
4711 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4712 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4713 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4714 isGP64bit()))) {
4715 Error(E, "consecutive register numbers expected");
4716 return MatchOperand_ParseFail;
4717 }
4718
4719 Regs.push_back(RegNo);
4720 }
4721
4722 if (Parser.getTok().is(AsmToken::Minus))
4723 RegRange = true;
4724
4725 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4726 !Parser.getTok().isNot(AsmToken::Comma)) {
4727 Error(E, "',' or '-' expected");
4728 return MatchOperand_ParseFail;
4729 }
4730
4731 Lex(); // Consume comma or minus
4732 if (Parser.getTok().isNot(AsmToken::Dollar))
4733 break;
4734
4735 PrevReg = RegNo;
4736 }
4737
4738 SMLoc E = Parser.getTok().getLoc();
4739 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4740 parseMemOperand(Operands);
4741 return MatchOperand_Success;
4742}
4743
4744MipsAsmParser::OperandMatchResultTy
4745MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4746 MCAsmParser &Parser = getParser();
4747
4748 SMLoc S = Parser.getTok().getLoc();
4749 if (parseAnyRegister(Operands) != MatchOperand_Success)
4750 return MatchOperand_ParseFail;
4751
4752 SMLoc E = Parser.getTok().getLoc();
4753 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4754 unsigned Reg = Op.getGPR32Reg();
4755 Operands.pop_back();
4756 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4757 return MatchOperand_Success;
4758}
4759
4760MipsAsmParser::OperandMatchResultTy
4761MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4762 MCAsmParser &Parser = getParser();
4763 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4764 SmallVector<unsigned, 10> Regs;
4765
4766 if (Parser.getTok().isNot(AsmToken::Dollar))
4767 return MatchOperand_ParseFail;
4768
4769 SMLoc S = Parser.getTok().getLoc();
4770
4771 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4772 return MatchOperand_ParseFail;
4773
4774 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4775 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4776 Regs.push_back(RegNo);
4777
4778 SMLoc E = Parser.getTok().getLoc();
4779 if (Parser.getTok().isNot(AsmToken::Comma)) {
4780 Error(E, "',' expected");
4781 return MatchOperand_ParseFail;
4782 }
4783
4784 // Remove comma.
4785 Parser.Lex();
4786
4787 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4788 return MatchOperand_ParseFail;
4789
4790 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4791 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4792 Regs.push_back(RegNo);
4793
4794 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4795
4796 return MatchOperand_Success;
4797}
4798
4799MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4800
4801 MCSymbolRefExpr::VariantKind VK =
4802 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4803 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4804 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4805 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4806 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4807 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4808 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4809 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4810 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4811 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4812 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4813 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4814 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4815 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4816 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4817 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4818 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4819 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4820 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4821 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4822 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4823 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4824 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4825 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4826 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4827 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4828 .Default(MCSymbolRefExpr::VK_None);
4829
4830 assert(VK != MCSymbolRefExpr::VK_None)((VK != MCSymbolRefExpr::VK_None) ? static_cast<void> (
0) : __assert_fail ("VK != MCSymbolRefExpr::VK_None", "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4830, __PRETTY_FUNCTION__))
;
4831
4832 return VK;
4833}
4834
4835/// Sometimes (i.e. load/stores) the operand may be followed immediately by
4836/// either this.
4837/// ::= '(', register, ')'
4838/// handle it before we iterate so we don't get tripped up by the lack of
4839/// a comma.
4840bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4841 MCAsmParser &Parser = getParser();
4842 if (getLexer().is(AsmToken::LParen)) {
4843 Operands.push_back(
4844 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4845 Parser.Lex();
4846 if (parseOperand(Operands, Name)) {
4847 SMLoc Loc = getLexer().getLoc();
4848 Parser.eatToEndOfStatement();
4849 return Error(Loc, "unexpected token in argument list");
4850 }
4851 if (Parser.getTok().isNot(AsmToken::RParen)) {
4852 SMLoc Loc = getLexer().getLoc();
4853 Parser.eatToEndOfStatement();
4854 return Error(Loc, "unexpected token, expected ')'");
4855 }
4856 Operands.push_back(
4857 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4858 Parser.Lex();
4859 }
4860 return false;
4861}
4862
4863/// Sometimes (i.e. in MSA) the operand may be followed immediately by
4864/// either one of these.
4865/// ::= '[', register, ']'
4866/// ::= '[', integer, ']'
4867/// handle it before we iterate so we don't get tripped up by the lack of
4868/// a comma.
4869bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4870 OperandVector &Operands) {
4871 MCAsmParser &Parser = getParser();
4872 if (getLexer().is(AsmToken::LBrac)) {
4873 Operands.push_back(
4874 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4875 Parser.Lex();
4876 if (parseOperand(Operands, Name)) {
4877 SMLoc Loc = getLexer().getLoc();
4878 Parser.eatToEndOfStatement();
4879 return Error(Loc, "unexpected token in argument list");
4880 }
4881 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4882 SMLoc Loc = getLexer().getLoc();
4883 Parser.eatToEndOfStatement();
4884 return Error(Loc, "unexpected token, expected ']'");
4885 }
4886 Operands.push_back(
4887 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4888 Parser.Lex();
4889 }
4890 return false;
4891}
4892
4893bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4894 SMLoc NameLoc, OperandVector &Operands) {
4895 MCAsmParser &Parser = getParser();
4896 DEBUG(dbgs() << "ParseInstruction\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "ParseInstruction\n"; }
} while (0)
;
4897
4898 // We have reached first instruction, module directive are now forbidden.
4899 getTargetStreamer().forbidModuleDirective();
4900
4901 // Check if we have valid mnemonic
4902 if (!mnemonicIsValid(Name, 0)) {
4903 Parser.eatToEndOfStatement();
4904 return Error(NameLoc, "unknown instruction");
4905 }
4906 // First operand in MCInst is instruction mnemonic.
4907 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4908
4909 // Read the remaining operands.
4910 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4911 // Read the first operand.
4912 if (parseOperand(Operands, Name)) {
4913 SMLoc Loc = getLexer().getLoc();
4914 Parser.eatToEndOfStatement();
4915 return Error(Loc, "unexpected token in argument list");
4916 }
4917 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4918 return true;
4919 // AFAIK, parenthesis suffixes are never on the first operand
4920
4921 while (getLexer().is(AsmToken::Comma)) {
4922 Parser.Lex(); // Eat the comma.
4923 // Parse and remember the operand.
4924 if (parseOperand(Operands, Name)) {
4925 SMLoc Loc = getLexer().getLoc();
4926 Parser.eatToEndOfStatement();
4927 return Error(Loc, "unexpected token in argument list");
4928 }
4929 // Parse bracket and parenthesis suffixes before we iterate
4930 if (getLexer().is(AsmToken::LBrac)) {
4931 if (parseBracketSuffix(Name, Operands))
4932 return true;
4933 } else if (getLexer().is(AsmToken::LParen) &&
4934 parseParenSuffix(Name, Operands))
4935 return true;
4936 }
4937 }
4938 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4939 SMLoc Loc = getLexer().getLoc();
4940 Parser.eatToEndOfStatement();
4941 return Error(Loc, "unexpected token in argument list");
4942 }
4943 Parser.Lex(); // Consume the EndOfStatement.
4944 return false;
4945}
4946
4947bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4948 MCAsmParser &Parser = getParser();
4949 SMLoc Loc = getLexer().getLoc();
4950 Parser.eatToEndOfStatement();
4951 return Error(Loc, ErrorMsg);
4952}
4953
4954bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4955 return Error(Loc, ErrorMsg);
4956}
4957
4958bool MipsAsmParser::parseSetNoAtDirective() {
4959 MCAsmParser &Parser = getParser();
4960 // Line should look like: ".set noat".
4961
4962 // Set the $at register to $0.
4963 AssemblerOptions.back()->setATRegIndex(0);
4964
4965 Parser.Lex(); // Eat "noat".
4966
4967 // If this is not the end of the statement, report an error.
4968 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4969 reportParseError("unexpected token, expected end of statement");
4970 return false;
4971 }
4972
4973 getTargetStreamer().emitDirectiveSetNoAt();
4974 Parser.Lex(); // Consume the EndOfStatement.
4975 return false;
4976}
4977
4978bool MipsAsmParser::parseSetAtDirective() {
4979 // Line can be: ".set at", which sets $at to $1
4980 // or ".set at=$reg", which sets $at to $reg.
4981 MCAsmParser &Parser = getParser();
4982 Parser.Lex(); // Eat "at".
4983
4984 if (getLexer().is(AsmToken::EndOfStatement)) {
4985 // No register was specified, so we set $at to $1.
4986 AssemblerOptions.back()->setATRegIndex(1);
4987
4988 getTargetStreamer().emitDirectiveSetAt();
4989 Parser.Lex(); // Consume the EndOfStatement.
4990 return false;
4991 }
4992
4993 if (getLexer().isNot(AsmToken::Equal)) {
4994 reportParseError("unexpected token, expected equals sign");
4995 return false;
4996 }
4997 Parser.Lex(); // Eat "=".
4998
4999 if (getLexer().isNot(AsmToken::Dollar)) {
5000 if (getLexer().is(AsmToken::EndOfStatement)) {
5001 reportParseError("no register specified");
5002 return false;
5003 } else {
5004 reportParseError("unexpected token, expected dollar sign '$'");
5005 return false;
5006 }
5007 }
5008 Parser.Lex(); // Eat "$".
5009
5010 // Find out what "reg" is.
5011 unsigned AtRegNo;
5012 const AsmToken &Reg = Parser.getTok();
5013 if (Reg.is(AsmToken::Identifier)) {
5014 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
5015 } else if (Reg.is(AsmToken::Integer)) {
5016 AtRegNo = Reg.getIntVal();
5017 } else {
5018 reportParseError("unexpected token, expected identifier or integer");
5019 return false;
5020 }
5021
5022 // Check if $reg is a valid register. If it is, set $at to $reg.
5023 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
5024 reportParseError("invalid register");
5025 return false;
5026 }
5027 Parser.Lex(); // Eat "reg".
5028
5029 // If this is not the end of the statement, report an error.
5030 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5031 reportParseError("unexpected token, expected end of statement");
5032 return false;
5033 }
5034
5035 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
5036
5037 Parser.Lex(); // Consume the EndOfStatement.
5038 return false;
5039}
5040
5041bool MipsAsmParser::parseSetReorderDirective() {
5042 MCAsmParser &Parser = getParser();
5043 Parser.Lex();
5044 // If this is not the end of the statement, report an error.
5045 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5046 reportParseError("unexpected token, expected end of statement");
5047 return false;
5048 }
5049 AssemblerOptions.back()->setReorder();
5050 getTargetStreamer().emitDirectiveSetReorder();
5051 Parser.Lex(); // Consume the EndOfStatement.
5052 return false;
5053}
5054
5055bool MipsAsmParser::parseSetNoReorderDirective() {
5056 MCAsmParser &Parser = getParser();
5057 Parser.Lex();
5058 // If this is not the end of the statement, report an error.
5059 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5060 reportParseError("unexpected token, expected end of statement");
5061 return false;
5062 }
5063 AssemblerOptions.back()->setNoReorder();
5064 getTargetStreamer().emitDirectiveSetNoReorder();
5065 Parser.Lex(); // Consume the EndOfStatement.
5066 return false;
5067}
5068
5069bool MipsAsmParser::parseSetMacroDirective() {
5070 MCAsmParser &Parser = getParser();
5071 Parser.Lex();
5072 // If this is not the end of the statement, report an error.
5073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5074 reportParseError("unexpected token, expected end of statement");
5075 return false;
5076 }
5077 AssemblerOptions.back()->setMacro();
5078 getTargetStreamer().emitDirectiveSetMacro();
5079 Parser.Lex(); // Consume the EndOfStatement.
5080 return false;
5081}
5082
5083bool MipsAsmParser::parseSetNoMacroDirective() {
5084 MCAsmParser &Parser = getParser();
5085 Parser.Lex();
5086 // If this is not the end of the statement, report an error.
5087 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5088 reportParseError("unexpected token, expected end of statement");
5089 return false;
5090 }
5091 if (AssemblerOptions.back()->isReorder()) {
5092 reportParseError("`noreorder' must be set before `nomacro'");
5093 return false;
5094 }
5095 AssemblerOptions.back()->setNoMacro();
5096 getTargetStreamer().emitDirectiveSetNoMacro();
5097 Parser.Lex(); // Consume the EndOfStatement.
5098 return false;
5099}
5100
5101bool MipsAsmParser::parseSetMsaDirective() {
5102 MCAsmParser &Parser = getParser();
5103 Parser.Lex();
5104
5105 // If this is not the end of the statement, report an error.
5106 if (getLexer().isNot(AsmToken::EndOfStatement))
5107 return reportParseError("unexpected token, expected end of statement");
5108
5109 setFeatureBits(Mips::FeatureMSA, "msa");
5110 getTargetStreamer().emitDirectiveSetMsa();
5111 return false;
5112}
5113
5114bool MipsAsmParser::parseSetNoMsaDirective() {
5115 MCAsmParser &Parser = getParser();
5116 Parser.Lex();
5117
5118 // If this is not the end of the statement, report an error.
5119 if (getLexer().isNot(AsmToken::EndOfStatement))
5120 return reportParseError("unexpected token, expected end of statement");
5121
5122 clearFeatureBits(Mips::FeatureMSA, "msa");
5123 getTargetStreamer().emitDirectiveSetNoMsa();
5124 return false;
5125}
5126
5127bool MipsAsmParser::parseSetNoDspDirective() {
5128 MCAsmParser &Parser = getParser();
5129 Parser.Lex(); // Eat "nodsp".
5130
5131 // If this is not the end of the statement, report an error.
5132 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5133 reportParseError("unexpected token, expected end of statement");
5134 return false;
5135 }
5136
5137 clearFeatureBits(Mips::FeatureDSP, "dsp");
5138 getTargetStreamer().emitDirectiveSetNoDsp();
5139 return false;
5140}
5141
5142bool MipsAsmParser::parseSetMips16Directive() {
5143 MCAsmParser &Parser = getParser();
5144 Parser.Lex(); // Eat "mips16".
5145
5146 // If this is not the end of the statement, report an error.
5147 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5148 reportParseError("unexpected token, expected end of statement");
5149 return false;
5150 }
5151
5152 setFeatureBits(Mips::FeatureMips16, "mips16");
5153 getTargetStreamer().emitDirectiveSetMips16();
5154 Parser.Lex(); // Consume the EndOfStatement.
5155 return false;
5156}
5157
5158bool MipsAsmParser::parseSetNoMips16Directive() {
5159 MCAsmParser &Parser = getParser();
5160 Parser.Lex(); // Eat "nomips16".
5161
5162 // If this is not the end of the statement, report an error.
5163 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5164 reportParseError("unexpected token, expected end of statement");
5165 return false;
5166 }
5167
5168 clearFeatureBits(Mips::FeatureMips16, "mips16");
5169 getTargetStreamer().emitDirectiveSetNoMips16();
5170 Parser.Lex(); // Consume the EndOfStatement.
5171 return false;
5172}
5173
5174bool MipsAsmParser::parseSetFpDirective() {
5175 MCAsmParser &Parser = getParser();
5176 MipsABIFlagsSection::FpABIKind FpAbiVal;
5177 // Line can be: .set fp=32
5178 // .set fp=xx
5179 // .set fp=64
5180 Parser.Lex(); // Eat fp token
5181 AsmToken Tok = Parser.getTok();
5182 if (Tok.isNot(AsmToken::Equal)) {
5183 reportParseError("unexpected token, expected equals sign '='");
5184 return false;
5185 }
5186 Parser.Lex(); // Eat '=' token.
5187 Tok = Parser.getTok();
5188
5189 if (!parseFpABIValue(FpAbiVal, ".set"))
5190 return false;
5191
5192 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5193 reportParseError("unexpected token, expected end of statement");
5194 return false;
5195 }
5196 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5197 Parser.Lex(); // Consume the EndOfStatement.
5198 return false;
5199}
5200
5201bool MipsAsmParser::parseSetOddSPRegDirective() {
5202 MCAsmParser &Parser = getParser();
5203
5204 Parser.Lex(); // Eat "oddspreg".
5205 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5206 reportParseError("unexpected token, expected end of statement");
5207 return false;
5208 }
5209
5210 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5211 getTargetStreamer().emitDirectiveSetOddSPReg();
5212 return false;
5213}
5214
5215bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5216 MCAsmParser &Parser = getParser();
5217
5218 Parser.Lex(); // Eat "nooddspreg".
5219 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5220 reportParseError("unexpected token, expected end of statement");
5221 return false;
5222 }
5223
5224 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5225 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5226 return false;
5227}
5228
5229bool MipsAsmParser::parseSetPopDirective() {
5230 MCAsmParser &Parser = getParser();
5231 SMLoc Loc = getLexer().getLoc();
5232
5233 Parser.Lex();
5234 if (getLexer().isNot(AsmToken::EndOfStatement))
5235 return reportParseError("unexpected token, expected end of statement");
5236
5237 // Always keep an element on the options "stack" to prevent the user
5238 // from changing the initial options. This is how we remember them.
5239 if (AssemblerOptions.size() == 2)
5240 return reportParseError(Loc, ".set pop with no .set push");
5241
5242 MCSubtargetInfo &STI = copySTI();
5243 AssemblerOptions.pop_back();
5244 setAvailableFeatures(
5245 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5246 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5247
5248 getTargetStreamer().emitDirectiveSetPop();
5249 return false;
5250}
5251
5252bool MipsAsmParser::parseSetPushDirective() {
5253 MCAsmParser &Parser = getParser();
5254 Parser.Lex();
5255 if (getLexer().isNot(AsmToken::EndOfStatement))
5256 return reportParseError("unexpected token, expected end of statement");
5257
5258 // Create a copy of the current assembler options environment and push it.
5259 AssemblerOptions.push_back(
5260 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5261
5262 getTargetStreamer().emitDirectiveSetPush();
5263 return false;
5264}
5265
5266bool MipsAsmParser::parseSetSoftFloatDirective() {
5267 MCAsmParser &Parser = getParser();
5268 Parser.Lex();
5269 if (getLexer().isNot(AsmToken::EndOfStatement))
5270 return reportParseError("unexpected token, expected end of statement");
5271
5272 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5273 getTargetStreamer().emitDirectiveSetSoftFloat();
5274 return false;
5275}
5276
5277bool MipsAsmParser::parseSetHardFloatDirective() {
5278 MCAsmParser &Parser = getParser();
5279 Parser.Lex();
5280 if (getLexer().isNot(AsmToken::EndOfStatement))
5281 return reportParseError("unexpected token, expected end of statement");
5282
5283 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5284 getTargetStreamer().emitDirectiveSetHardFloat();
5285 return false;
5286}
5287
5288bool MipsAsmParser::parseSetAssignment() {
5289 StringRef Name;
5290 const MCExpr *Value;
5291 MCAsmParser &Parser = getParser();
5292
5293 if (Parser.parseIdentifier(Name))
5294 reportParseError("expected identifier after .set");
5295
5296 if (getLexer().isNot(AsmToken::Comma))
5297 return reportParseError("unexpected token, expected comma");
5298 Lex(); // Eat comma
5299
5300 if (Parser.parseExpression(Value))
5301 return reportParseError("expected valid expression after comma");
5302
5303 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5304 Sym->setVariableValue(Value);
5305
5306 return false;
5307}
5308
5309bool MipsAsmParser::parseSetMips0Directive() {
5310 MCAsmParser &Parser = getParser();
5311 Parser.Lex();
5312 if (getLexer().isNot(AsmToken::EndOfStatement))
5313 return reportParseError("unexpected token, expected end of statement");
5314
5315 // Reset assembler options to their initial values.
5316 MCSubtargetInfo &STI = copySTI();
5317 setAvailableFeatures(
5318 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5319 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5320 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5321
5322 getTargetStreamer().emitDirectiveSetMips0();
5323 return false;
5324}
5325
5326bool MipsAsmParser::parseSetArchDirective() {
5327 MCAsmParser &Parser = getParser();
5328 Parser.Lex();
5329 if (getLexer().isNot(AsmToken::Equal))
5330 return reportParseError("unexpected token, expected equals sign");
5331
5332 Parser.Lex();
5333 StringRef Arch;
5334 if (Parser.parseIdentifier(Arch))
5335 return reportParseError("expected arch identifier");
5336
5337 StringRef ArchFeatureName =
5338 StringSwitch<StringRef>(Arch)
5339 .Case("mips1", "mips1")
5340 .Case("mips2", "mips2")
5341 .Case("mips3", "mips3")
5342 .Case("mips4", "mips4")
5343 .Case("mips5", "mips5")
5344 .Case("mips32", "mips32")
5345 .Case("mips32r2", "mips32r2")
5346 .Case("mips32r3", "mips32r3")
5347 .Case("mips32r5", "mips32r5")
5348 .Case("mips32r6", "mips32r6")
5349 .Case("mips64", "mips64")
5350 .Case("mips64r2", "mips64r2")
5351 .Case("mips64r3", "mips64r3")
5352 .Case("mips64r5", "mips64r5")
5353 .Case("mips64r6", "mips64r6")
5354 .Case("octeon", "cnmips")
5355 .Case("r4000", "mips3") // This is an implementation of Mips3.
5356 .Default("");
5357
5358 if (ArchFeatureName.empty())
5359 return reportParseError("unsupported architecture");
5360
5361 selectArch(ArchFeatureName);
5362 getTargetStreamer().emitDirectiveSetArch(Arch);
5363 return false;
5364}
5365
5366bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5367 MCAsmParser &Parser = getParser();
5368 Parser.Lex();
5369 if (getLexer().isNot(AsmToken::EndOfStatement))
5370 return reportParseError("unexpected token, expected end of statement");
5371
5372 switch (Feature) {
5373 default:
5374 llvm_unreachable("Unimplemented feature")::llvm::llvm_unreachable_internal("Unimplemented feature", "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5374)
;
5375 case Mips::FeatureDSP:
5376 setFeatureBits(Mips::FeatureDSP, "dsp");
5377 getTargetStreamer().emitDirectiveSetDsp();
5378 break;
5379 case Mips::FeatureMicroMips:
5380 getTargetStreamer().emitDirectiveSetMicroMips();
5381 break;
5382 case Mips::FeatureMips1:
5383 selectArch("mips1");
5384 getTargetStreamer().emitDirectiveSetMips1();
5385 break;
5386 case Mips::FeatureMips2:
5387 selectArch("mips2");
5388 getTargetStreamer().emitDirectiveSetMips2();
5389 break;
5390 case Mips::FeatureMips3:
5391 selectArch("mips3");
5392 getTargetStreamer().emitDirectiveSetMips3();
5393 break;
5394 case Mips::FeatureMips4:
5395 selectArch("mips4");
5396 getTargetStreamer().emitDirectiveSetMips4();
5397 break;
5398 case Mips::FeatureMips5:
5399 selectArch("mips5");
5400 getTargetStreamer().emitDirectiveSetMips5();
5401 break;
5402 case Mips::FeatureMips32:
5403 selectArch("mips32");
5404 getTargetStreamer().emitDirectiveSetMips32();
5405 break;
5406 case Mips::FeatureMips32r2:
5407 selectArch("mips32r2");
5408 getTargetStreamer().emitDirectiveSetMips32R2();
5409 break;
5410 case Mips::FeatureMips32r3:
5411 selectArch("mips32r3");
5412 getTargetStreamer().emitDirectiveSetMips32R3();
5413 break;
5414 case Mips::FeatureMips32r5:
5415 selectArch("mips32r5");
5416 getTargetStreamer().emitDirectiveSetMips32R5();
5417 break;
5418 case Mips::FeatureMips32r6:
5419 selectArch("mips32r6");
5420 getTargetStreamer().emitDirectiveSetMips32R6();
5421 break;
5422 case Mips::FeatureMips64:
5423 selectArch("mips64");
5424 getTargetStreamer().emitDirectiveSetMips64();
5425 break;
5426 case Mips::FeatureMips64r2:
5427 selectArch("mips64r2");
5428 getTargetStreamer().emitDirectiveSetMips64R2();
5429 break;
5430 case Mips::FeatureMips64r3:
5431 selectArch("mips64r3");
5432 getTargetStreamer().emitDirectiveSetMips64R3();
5433 break;
5434 case Mips::FeatureMips64r5:
5435 selectArch("mips64r5");
5436 getTargetStreamer().emitDirectiveSetMips64R5();
5437 break;
5438 case Mips::FeatureMips64r6:
5439 selectArch("mips64r6");
5440 getTargetStreamer().emitDirectiveSetMips64R6();
5441 break;
5442 }
5443 return false;
5444}
5445
5446bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5447 MCAsmParser &Parser = getParser();
5448 if (getLexer().isNot(AsmToken::Comma)) {
5449 SMLoc Loc = getLexer().getLoc();
5450 Parser.eatToEndOfStatement();
5451 return Error(Loc, ErrorStr);
5452 }
5453
5454 Parser.Lex(); // Eat the comma.
5455 return true;
5456}
5457
5458// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5459// In this class, it is only used for .cprestore.
5460// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5461// MipsTargetELFStreamer and MipsAsmParser.
5462bool MipsAsmParser::isPicAndNotNxxAbi() {
5463 return inPicMode() && !(isABI_N32() || isABI_N64());
5464}
5465
5466bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5467 if (AssemblerOptions.back()->isReorder())
5468 Warning(Loc, ".cpload should be inside a noreorder section");
5469
5470 if (inMips16Mode()) {
5471 reportParseError(".cpload is not supported in Mips16 mode");
5472 return false;
5473 }
5474
5475 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5476 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5477 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5478 reportParseError("expected register containing function address");
5479 return false;
5480 }
5481
5482 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5483 if (!RegOpnd.isGPRAsmReg()) {
5484 reportParseError(RegOpnd.getStartLoc(), "invalid register");
5485 return false;
5486 }
5487
5488 // If this is not the end of the statement, report an error.
5489 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5490 reportParseError("unexpected token, expected end of statement");
5491 return false;
5492 }
5493
5494 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5495 return false;
5496}
5497
5498bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5499 MCAsmParser &Parser = getParser();
5500
5501 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5502 // is used in non-PIC mode.
5503
5504 if (inMips16Mode()) {
5505 reportParseError(".cprestore is not supported in Mips16 mode");
5506 return false;
5507 }
5508
5509 // Get the stack offset value.
5510 const MCExpr *StackOffset;
5511 int64_t StackOffsetVal;
5512 if (Parser.parseExpression(StackOffset)) {
5513 reportParseError("expected stack offset value");
5514 return false;
5515 }
5516
5517 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5518 reportParseError("stack offset is not an absolute expression");
5519 return false;
5520 }
5521
5522 if (StackOffsetVal < 0) {
5523 Warning(Loc, ".cprestore with negative stack offset has no effect");
5524 IsCpRestoreSet = false;
5525 } else {
5526 IsCpRestoreSet = true;
5527 CpRestoreOffset = StackOffsetVal;
5528 }
5529
5530 // If this is not the end of the statement, report an error.
5531 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5532 reportParseError("unexpected token, expected end of statement");
5533 return false;
5534 }
5535
5536 // Store the $gp on the stack.
5537 if (getStreamer().isIntegratedAssemblerRequired()) {
5538 const MCSubtargetInfo &STI = getSTI();
5539 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5540 getStreamer(), &STI);
5541 }
5542
5543 getTargetStreamer().emitDirectiveCpRestore(CpRestoreOffset);
5544 Parser.Lex(); // Consume the EndOfStatement.
5545 return false;
5546}
5547
5548bool MipsAsmParser::parseDirectiveCPSetup() {
5549 MCAsmParser &Parser = getParser();
5550 unsigned FuncReg;
5551 unsigned Save;
5552 bool SaveIsReg = true;
5553
5554 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5555 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5556 if (ResTy == MatchOperand_NoMatch) {
5557 reportParseError("expected register containing function address");
5558 Parser.eatToEndOfStatement();
5559 return false;
5560 }
5561
5562 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5563 if (!FuncRegOpnd.isGPRAsmReg()) {
5564 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5565 Parser.eatToEndOfStatement();
5566 return false;
5567 }
5568
5569 FuncReg = FuncRegOpnd.getGPR32Reg();
5570 TmpReg.clear();
5571
5572 if (!eatComma("unexpected token, expected comma"))
5573 return true;
5574
5575 ResTy = parseAnyRegister(TmpReg);
5576 if (ResTy == MatchOperand_NoMatch) {
5577 const MCExpr *OffsetExpr;
5578 int64_t OffsetVal;
5579 SMLoc ExprLoc = getLexer().getLoc();
5580
5581 if (Parser.parseExpression(OffsetExpr) ||
5582 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5583 reportParseError(ExprLoc, "expected save register or stack offset");
5584 Parser.eatToEndOfStatement();
5585 return false;
5586 }
5587
5588 Save = OffsetVal;
5589 SaveIsReg = false;
5590 } else {
5591 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5592 if (!SaveOpnd.isGPRAsmReg()) {
5593 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5594 Parser.eatToEndOfStatement();
5595 return false;
5596 }
5597 Save = SaveOpnd.getGPR32Reg();
5598 }
5599
5600 if (!eatComma("unexpected token, expected comma"))
5601 return true;
5602
5603 const MCExpr *Expr;
5604 if (Parser.parseExpression(Expr)) {
5605 reportParseError("expected expression");
5606 return false;
5607 }
5608
5609 if (Expr->getKind() != MCExpr::SymbolRef) {
5610 reportParseError("expected symbol");
5611 return false;
5612 }
5613 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5614
5615 CpSaveLocation = Save;
5616 CpSaveLocationIsRegister = SaveIsReg;
5617
5618 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5619 SaveIsReg);
5620 return false;
5621}
5622
5623bool MipsAsmParser::parseDirectiveCPReturn() {
5624 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5625 CpSaveLocationIsRegister);
5626 return false;
5627}
5628
5629bool MipsAsmParser::parseDirectiveNaN() {
5630 MCAsmParser &Parser = getParser();
5631 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5632 const AsmToken &Tok = Parser.getTok();
5633
5634 if (Tok.getString() == "2008") {
5635 Parser.Lex();
5636 getTargetStreamer().emitDirectiveNaN2008();
5637 return false;
5638 } else if (Tok.getString() == "legacy") {
5639 Parser.Lex();
5640 getTargetStreamer().emitDirectiveNaNLegacy();
5641 return false;
5642 }
5643 }
5644 // If we don't recognize the option passed to the .nan
5645 // directive (e.g. no option or unknown option), emit an error.
5646 reportParseError("invalid option in .nan directive");
5647 return false;
5648}
5649
5650bool MipsAsmParser::parseDirectiveSet() {
5651 MCAsmParser &Parser = getParser();
5652 // Get the next token.
5653 const AsmToken &Tok = Parser.getTok();
5654
5655 if (Tok.getString() == "noat") {
5656 return parseSetNoAtDirective();
5657 } else if (Tok.getString() == "at") {
5658 return parseSetAtDirective();
5659 } else if (Tok.getString() == "arch") {
5660 return parseSetArchDirective();
5661 } else if (Tok.getString() == "fp") {
5662 return parseSetFpDirective();
5663 } else if (Tok.getString() == "oddspreg") {
5664 return parseSetOddSPRegDirective();
5665 } else if (Tok.getString() == "nooddspreg") {
5666 return parseSetNoOddSPRegDirective();
5667 } else if (Tok.getString() == "pop") {
5668 return parseSetPopDirective();
5669 } else if (Tok.getString() == "push") {
5670 return parseSetPushDirective();
5671 } else if (Tok.getString() == "reorder") {
5672 return parseSetReorderDirective();
5673 } else if (Tok.getString() == "noreorder") {
5674 return parseSetNoReorderDirective();
5675 } else if (Tok.getString() == "macro") {
5676 return parseSetMacroDirective();
5677 } else if (Tok.getString() == "nomacro") {
5678 return parseSetNoMacroDirective();
5679 } else if (Tok.getString() == "mips16") {
5680 return parseSetMips16Directive();
5681 } else if (Tok.getString() == "nomips16") {
5682 return parseSetNoMips16Directive();
5683 } else if (Tok.getString() == "nomicromips") {
5684 getTargetStreamer().emitDirectiveSetNoMicroMips();
5685 Parser.eatToEndOfStatement();
5686 return false;
5687 } else if (Tok.getString() == "micromips") {
5688 return parseSetFeature(Mips::FeatureMicroMips);
5689 } else if (Tok.getString() == "mips0") {
5690 return parseSetMips0Directive();
5691 } else if (Tok.getString() == "mips1") {
5692 return parseSetFeature(Mips::FeatureMips1);
5693 } else if (Tok.getString() == "mips2") {
5694 return parseSetFeature(Mips::FeatureMips2);
5695 } else if (Tok.getString() == "mips3") {
5696 return parseSetFeature(Mips::FeatureMips3);
5697 } else if (Tok.getString() == "mips4") {
5698 return parseSetFeature(Mips::FeatureMips4);
5699 } else if (Tok.getString() == "mips5") {
5700 return parseSetFeature(Mips::FeatureMips5);
5701 } else if (Tok.getString() == "mips32") {
5702 return parseSetFeature(Mips::FeatureMips32);
5703 } else if (Tok.getString() == "mips32r2") {
5704 return parseSetFeature(Mips::FeatureMips32r2);
5705 } else if (Tok.getString() == "mips32r3") {
5706 return parseSetFeature(Mips::FeatureMips32r3);
5707 } else if (Tok.getString() == "mips32r5") {
5708 return parseSetFeature(Mips::FeatureMips32r5);
5709 } else if (Tok.getString() == "mips32r6") {
5710 return parseSetFeature(Mips::FeatureMips32r6);
5711 } else if (Tok.getString() == "mips64") {
5712 return parseSetFeature(Mips::FeatureMips64);
5713 } else if (Tok.getString() == "mips64r2") {
5714 return parseSetFeature(Mips::FeatureMips64r2);
5715 } else if (Tok.getString() == "mips64r3") {
5716 return parseSetFeature(Mips::FeatureMips64r3);
5717 } else if (Tok.getString() == "mips64r5") {
5718 return parseSetFeature(Mips::FeatureMips64r5);
5719 } else if (Tok.getString() == "mips64r6") {
5720 return parseSetFeature(Mips::FeatureMips64r6);
5721 } else if (Tok.getString() == "dsp") {
5722 return parseSetFeature(Mips::FeatureDSP);
5723 } else if (Tok.getString() == "nodsp") {
5724 return parseSetNoDspDirective();
5725 } else if (Tok.getString() == "msa") {
5726 return parseSetMsaDirective();
5727 } else if (Tok.getString() == "nomsa") {
5728 return parseSetNoMsaDirective();
5729 } else if (Tok.getString() == "softfloat") {
5730 return parseSetSoftFloatDirective();
5731 } else if (Tok.getString() == "hardfloat") {
5732 return parseSetHardFloatDirective();
5733 } else {
5734 // It is just an identifier, look for an assignment.
5735 parseSetAssignment();
5736 return false;
5737 }
5738
5739 return true;
5740}
5741
5742/// parseDataDirective
5743/// ::= .word [ expression (, expression)* ]
5744bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5745 MCAsmParser &Parser = getParser();
5746 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5747 for (;;) {
5748 const MCExpr *Value;
5749 if (getParser().parseExpression(Value))
5750 return true;
5751
5752 getParser().getStreamer().EmitValue(Value, Size);
5753
5754 if (getLexer().is(AsmToken::EndOfStatement))
5755 break;
5756
5757 if (getLexer().isNot(AsmToken::Comma))
5758 return Error(L, "unexpected token, expected comma");
5759 Parser.Lex();
5760 }
5761 }
5762
5763 Parser.Lex();
5764 return false;
5765}
5766
5767/// parseDirectiveGpWord
5768/// ::= .gpword local_sym
5769bool MipsAsmParser::parseDirectiveGpWord() {
5770 MCAsmParser &Parser = getParser();
5771 const MCExpr *Value;
5772 // EmitGPRel32Value requires an expression, so we are using base class
5773 // method to evaluate the expression.
5774 if (getParser().parseExpression(Value))
5775 return true;
5776 getParser().getStreamer().EmitGPRel32Value(Value);
5777
5778 if (getLexer().isNot(AsmToken::EndOfStatement))
5779 return Error(getLexer().getLoc(),
5780 "unexpected token, expected end of statement");
5781 Parser.Lex(); // Eat EndOfStatement token.
5782 return false;
5783}
5784
5785/// parseDirectiveGpDWord
5786/// ::= .gpdword local_sym
5787bool MipsAsmParser::parseDirectiveGpDWord() {
5788 MCAsmParser &Parser = getParser();
5789 const MCExpr *Value;
5790 // EmitGPRel64Value requires an expression, so we are using base class
5791 // method to evaluate the expression.
5792 if (getParser().parseExpression(Value))
5793 return true;
5794 getParser().getStreamer().EmitGPRel64Value(Value);
5795
5796 if (getLexer().isNot(AsmToken::EndOfStatement))
5797 return Error(getLexer().getLoc(),
5798 "unexpected token, expected end of statement");
5799 Parser.Lex(); // Eat EndOfStatement token.
5800 return false;
5801}
5802
5803bool MipsAsmParser::parseDirectiveOption() {
5804 MCAsmParser &Parser = getParser();
5805 // Get the option token.
5806 AsmToken Tok = Parser.getTok();
5807 // At the moment only identifiers are supported.
5808 if (Tok.isNot(AsmToken::Identifier)) {
5809 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5810 Parser.eatToEndOfStatement();
5811 return false;
5812 }
5813
5814 StringRef Option = Tok.getIdentifier();
5815
5816 if (Option == "pic0") {
5817 // MipsAsmParser needs to know if the current PIC mode changes.
5818 IsPicEnabled = false;
5819
5820 getTargetStreamer().emitDirectiveOptionPic0();
5821 Parser.Lex();
5822 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5823 Error(Parser.getTok().getLoc(),
5824 "unexpected token, expected end of statement");
5825 Parser.eatToEndOfStatement();
5826 }
5827 return false;
5828 }
5829
5830 if (Option == "pic2") {
5831 // MipsAsmParser needs to know if the current PIC mode changes.
5832 IsPicEnabled = true;
5833
5834 getTargetStreamer().emitDirectiveOptionPic2();
5835 Parser.Lex();
5836 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5837 Error(Parser.getTok().getLoc(),
5838 "unexpected token, expected end of statement");
5839 Parser.eatToEndOfStatement();
5840 }
5841 return false;
5842 }
5843
5844 // Unknown option.
5845 Warning(Parser.getTok().getLoc(),
5846 "unknown option, expected 'pic0' or 'pic2'");
5847 Parser.eatToEndOfStatement();
5848 return false;
5849}
5850
5851/// parseInsnDirective
5852/// ::= .insn
5853bool MipsAsmParser::parseInsnDirective() {
5854 // If this is not the end of the statement, report an error.
5855 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5856 reportParseError("unexpected token, expected end of statement");
5857 return false;
5858 }
5859
5860 // The actual label marking happens in
5861 // MipsELFStreamer::createPendingLabelRelocs().
5862 getTargetStreamer().emitDirectiveInsn();
5863
5864 getParser().Lex(); // Eat EndOfStatement token.
5865 return false;
5866}
5867
5868/// parseSSectionDirective
5869/// ::= .sbss
5870/// ::= .sdata
5871bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
5872 // If this is not the end of the statement, report an error.
5873 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5874 reportParseError("unexpected token, expected end of statement");
5875 return false;
5876 }
5877
5878 MCSection *ELFSection = getContext().getELFSection(
5879 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
5880 getParser().getStreamer().SwitchSection(ELFSection);
5881
5882 getParser().Lex(); // Eat EndOfStatement token.
5883 return false;
5884}
5885
5886/// parseDirectiveModule
5887/// ::= .module oddspreg
5888/// ::= .module nooddspreg
5889/// ::= .module fp=value
5890/// ::= .module softfloat
5891/// ::= .module hardfloat
5892bool MipsAsmParser::parseDirectiveModule() {
5893 MCAsmParser &Parser = getParser();
5894 MCAsmLexer &Lexer = getLexer();
5895 SMLoc L = Lexer.getLoc();
5896
5897 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5898 // TODO : get a better message.
5899 reportParseError(".module directive must appear before any code");
5900 return false;
5901 }
5902
5903 StringRef Option;
5904 if (Parser.parseIdentifier(Option)) {
5905 reportParseError("expected .module option identifier");
5906 return false;
5907 }
5908
5909 if (Option == "oddspreg") {
5910 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5911
5912 // Synchronize the abiflags information with the FeatureBits information we
5913 // changed above.
5914 getTargetStreamer().updateABIInfo(*this);
5915
5916 // If printing assembly, use the recently updated abiflags information.
5917 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5918 // emitted at the end).
5919 getTargetStreamer().emitDirectiveModuleOddSPReg();
5920
5921 // If this is not the end of the statement, report an error.
5922 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5923 reportParseError("unexpected token, expected end of statement");
5924 return false;
5925 }
5926
5927 return false; // parseDirectiveModule has finished successfully.
5928 } else if (Option == "nooddspreg") {
5929 if (!isABI_O32()) {
5930 Error(L, "'.module nooddspreg' requires the O32 ABI");
5931 return false;
5932 }
5933
5934 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5935
5936 // Synchronize the abiflags information with the FeatureBits information we
5937 // changed above.
5938 getTargetStreamer().updateABIInfo(*this);
5939
5940 // If printing assembly, use the recently updated abiflags information.
5941 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5942 // emitted at the end).
5943 getTargetStreamer().emitDirectiveModuleOddSPReg();
5944
5945 // If this is not the end of the statement, report an error.
5946 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5947 reportParseError("unexpected token, expected end of statement");
5948 return false;
5949 }
5950
5951 return false; // parseDirectiveModule has finished successfully.
5952 } else if (Option == "fp") {
5953 return parseDirectiveModuleFP();
5954 } else if (Option == "softfloat") {
5955 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5956
5957 // Synchronize the ABI Flags information with the FeatureBits information we
5958 // updated above.
5959 getTargetStreamer().updateABIInfo(*this);
5960
5961 // If printing assembly, use the recently updated ABI Flags information.
5962 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5963 // emitted later).
5964 getTargetStreamer().emitDirectiveModuleSoftFloat();
5965
5966 // If this is not the end of the statement, report an error.
5967 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5968 reportParseError("unexpected token, expected end of statement");
5969 return false;
5970 }
5971
5972 return false; // parseDirectiveModule has finished successfully.
5973 } else if (Option == "hardfloat") {
5974 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5975
5976 // Synchronize the ABI Flags information with the FeatureBits information we
5977 // updated above.
5978 getTargetStreamer().updateABIInfo(*this);
5979
5980 // If printing assembly, use the recently updated ABI Flags information.
5981 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5982 // emitted later).
5983 getTargetStreamer().emitDirectiveModuleHardFloat();
5984
5985 // If this is not the end of the statement, report an error.
5986 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5987 reportParseError("unexpected token, expected end of statement");
5988 return false;
5989 }
5990
5991 return false; // parseDirectiveModule has finished successfully.
5992 } else {
5993 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5994 }
5995}
5996
5997/// parseDirectiveModuleFP
5998/// ::= =32
5999/// ::= =xx
6000/// ::= =64
6001bool MipsAsmParser::parseDirectiveModuleFP() {
6002 MCAsmParser &Parser = getParser();
6003 MCAsmLexer &Lexer = getLexer();
6004
6005 if (Lexer.isNot(AsmToken::Equal)) {
6006 reportParseError("unexpected token, expected equals sign '='");
6007 return false;
6008 }
6009 Parser.Lex(); // Eat '=' token.
6010
6011 MipsABIFlagsSection::FpABIKind FpABI;
6012 if (!parseFpABIValue(FpABI, ".module"))
6013 return false;
6014
6015 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6016 reportParseError("unexpected token, expected end of statement");
6017 return false;
6018 }
6019
6020 // Synchronize the abiflags information with the FeatureBits information we
6021 // changed above.
6022 getTargetStreamer().updateABIInfo(*this);
6023
6024 // If printing assembly, use the recently updated abiflags information.
6025 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6026 // emitted at the end).
6027 getTargetStreamer().emitDirectiveModuleFP();
6028
6029 Parser.Lex(); // Consume the EndOfStatement.
6030 return false;
6031}
6032
6033bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
6034 StringRef Directive) {
6035 MCAsmParser &Parser = getParser();
6036 MCAsmLexer &Lexer = getLexer();
6037 bool ModuleLevelOptions = Directive == ".module";
6038
6039 if (Lexer.is(AsmToken::Identifier)) {
6040 StringRef Value = Parser.getTok().getString();
6041 Parser.Lex();
6042
6043 if (Value != "xx") {
6044 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6045 return false;
6046 }
6047
6048 if (!isABI_O32()) {
6049 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
6050 return false;
6051 }
6052
6053 FpABI = MipsABIFlagsSection::FpABIKind::XX;
6054 if (ModuleLevelOptions) {
6055 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6056 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6057 } else {
6058 setFeatureBits(Mips::FeatureFPXX, "fpxx");
6059 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6060 }
6061 return true;
6062 }
6063
6064 if (Lexer.is(AsmToken::Integer)) {
6065 unsigned Value = Parser.getTok().getIntVal();
6066 Parser.Lex();
6067
6068 if (Value != 32 && Value != 64) {
6069 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6070 return false;
6071 }
6072
6073 if (Value == 32) {
6074 if (!isABI_O32()) {
6075 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6076 return false;
6077 }
6078
6079 FpABI = MipsABIFlagsSection::FpABIKind::S32;
6080 if (ModuleLevelOptions) {
6081 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6082 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6083 } else {
6084 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6085 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6086 }
6087 } else {
6088 FpABI = MipsABIFlagsSection::FpABIKind::S64;
6089 if (ModuleLevelOptions) {
6090 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6091 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6092 } else {
6093 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6094 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6095 }
6096 }
6097
6098 return true;
6099 }
6100
6101 return false;
6102}
6103
6104bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6105 MCAsmParser &Parser = getParser();
6106 StringRef IDVal = DirectiveID.getString();
6107
6108 if (IDVal == ".cpload")
6109 return parseDirectiveCpLoad(DirectiveID.getLoc());
6110 if (IDVal == ".cprestore")
6111 return parseDirectiveCpRestore(DirectiveID.getLoc());
6112 if (IDVal == ".dword") {
6113 parseDataDirective(8, DirectiveID.getLoc());
6114 return false;
6115 }
6116 if (IDVal == ".ent") {
6117 StringRef SymbolName;
6118
6119 if (Parser.parseIdentifier(SymbolName)) {
6120 reportParseError("expected identifier after .ent");
6121 return false;
6122 }
6123
6124 // There's an undocumented extension that allows an integer to
6125 // follow the name of the procedure which AFAICS is ignored by GAS.
6126 // Example: .ent foo,2
6127 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6128 if (getLexer().isNot(AsmToken::Comma)) {
6129 // Even though we accept this undocumented extension for compatibility
6130 // reasons, the additional integer argument does not actually change
6131 // the behaviour of the '.ent' directive, so we would like to discourage
6132 // its use. We do this by not referring to the extended version in
6133 // error messages which are not directly related to its use.
6134 reportParseError("unexpected token, expected end of statement");
6135 return false;
6136 }
6137 Parser.Lex(); // Eat the comma.
6138 const MCExpr *DummyNumber;
6139 int64_t DummyNumberVal;
6140 // If the user was explicitly trying to use the extended version,
6141 // we still give helpful extension-related error messages.
6142 if (Parser.parseExpression(DummyNumber)) {
6143 reportParseError("expected number after comma");
6144 return false;
6145 }
6146 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6147 reportParseError("expected an absolute expression after comma");
6148 return false;
6149 }
6150 }
6151
6152 // If this is not the end of the statement, report an error.
6153 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6154 reportParseError("unexpected token, expected end of statement");
6155 return false;
6156 }
6157
6158 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6159
6160 getTargetStreamer().emitDirectiveEnt(*Sym);
6161 CurrentFn = Sym;
6162 IsCpRestoreSet = false;
6163 return false;
6164 }
6165
6166 if (IDVal == ".end") {
6167 StringRef SymbolName;
6168
6169 if (Parser.parseIdentifier(SymbolName)) {
6170 reportParseError("expected identifier after .end");
6171 return false;
6172 }
6173
6174 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6175 reportParseError("unexpected token, expected end of statement");
6176 return false;
6177 }
6178
6179 if (CurrentFn == nullptr) {
6180 reportParseError(".end used without .ent");
6181 return false;
6182 }
6183
6184 if ((SymbolName != CurrentFn->getName())) {
6185 reportParseError(".end symbol does not match .ent symbol");
6186 return false;
6187 }
6188
6189 getTargetStreamer().emitDirectiveEnd(SymbolName);
6190 CurrentFn = nullptr;
6191 IsCpRestoreSet = false;
6192 return false;
6193 }
6194
6195 if (IDVal == ".frame") {
6196 // .frame $stack_reg, frame_size_in_bytes, $return_reg
6197 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6198 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6199 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6200 reportParseError("expected stack register");
6201 return false;
6202 }
6203
6204 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6205 if (!StackRegOpnd.isGPRAsmReg()) {
6206 reportParseError(StackRegOpnd.getStartLoc(),
6207 "expected general purpose register");
6208 return false;
6209 }
6210 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6211
6212 if (Parser.getTok().is(AsmToken::Comma))
6213 Parser.Lex();
6214 else {
6215 reportParseError("unexpected token, expected comma");
6216 return false;
6217 }
6218
6219 // Parse the frame size.
6220 const MCExpr *FrameSize;
6221 int64_t FrameSizeVal;
6222
6223 if (Parser.parseExpression(FrameSize)) {
6224 reportParseError("expected frame size value");
6225 return false;
6226 }
6227
6228 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6229 reportParseError("frame size not an absolute expression");
6230 return false;
6231 }
6232
6233 if (Parser.getTok().is(AsmToken::Comma))
6234 Parser.Lex();
6235 else {
6236 reportParseError("unexpected token, expected comma");
6237 return false;
6238 }
6239
6240 // Parse the return register.
6241 TmpReg.clear();
6242 ResTy = parseAnyRegister(TmpReg);
6243 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6244 reportParseError("expected return register");
6245 return false;
6246 }
6247
6248 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6249 if (!ReturnRegOpnd.isGPRAsmReg()) {
6250 reportParseError(ReturnRegOpnd.getStartLoc(),
6251 "expected general purpose register");
6252 return false;
6253 }
6254
6255 // If this is not the end of the statement, report an error.
6256 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6257 reportParseError("unexpected token, expected end of statement");
6258 return false;
6259 }
6260
6261 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6262 ReturnRegOpnd.getGPR32Reg());
6263 IsCpRestoreSet = false;
6264 return false;
6265 }
6266
6267 if (IDVal == ".set") {
6268 return parseDirectiveSet();
6269 }
6270
6271 if (IDVal == ".mask" || IDVal == ".fmask") {
6272 // .mask bitmask, frame_offset
6273 // bitmask: One bit for each register used.
6274 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6275 // first register is expected to be saved.
6276 // Examples:
6277 // .mask 0x80000000, -4
6278 // .fmask 0x80000000, -4
6279 //
6280
6281 // Parse the bitmask
6282 const MCExpr *BitMask;
6283 int64_t BitMaskVal;
6284
6285 if (Parser.parseExpression(BitMask)) {
6286 reportParseError("expected bitmask value");
6287 return false;
6288 }
6289
6290 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6291 reportParseError("bitmask not an absolute expression");
6292 return false;
6293 }
6294
6295 if (Parser.getTok().is(AsmToken::Comma))
6296 Parser.Lex();
6297 else {
6298 reportParseError("unexpected token, expected comma");
6299 return false;
6300 }
6301
6302 // Parse the frame_offset
6303 const MCExpr *FrameOffset;
6304 int64_t FrameOffsetVal;
6305
6306 if (Parser.parseExpression(FrameOffset)) {
6307 reportParseError("expected frame offset value");
6308 return false;
6309 }
6310
6311 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6312 reportParseError("frame offset not an absolute expression");
6313 return false;
6314 }
6315
6316 // If this is not the end of the statement, report an error.
6317 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6318 reportParseError("unexpected token, expected end of statement");
6319 return false;
6320 }
6321
6322 if (IDVal == ".mask")
6323 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6324 else
6325 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6326 return false;
6327 }
6328
6329 if (IDVal == ".nan")
6330 return parseDirectiveNaN();
6331
6332 if (IDVal == ".gpword") {
6333 parseDirectiveGpWord();
6334 return false;
6335 }
6336
6337 if (IDVal == ".gpdword") {
6338 parseDirectiveGpDWord();
6339 return false;
6340 }
6341
6342 if (IDVal == ".word") {
6343 parseDataDirective(4, DirectiveID.getLoc());
6344 return false;
6345 }
6346
6347 if (IDVal == ".hword") {
6348 parseDataDirective(2, DirectiveID.getLoc());
6349 return false;
6350 }
6351
6352 if (IDVal == ".option")
6353 return parseDirectiveOption();
6354
6355 if (IDVal == ".abicalls") {
6356 getTargetStreamer().emitDirectiveAbiCalls();
6357 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6358 Error(Parser.getTok().getLoc(),
6359 "unexpected token, expected end of statement");
6360 // Clear line
6361 Parser.eatToEndOfStatement();
6362 }
6363 return false;
6364 }
6365
6366 if (IDVal == ".cpsetup")
6367 return parseDirectiveCPSetup();
6368
6369 if (IDVal == ".cpreturn")
6370 return parseDirectiveCPReturn();
6371
6372 if (IDVal == ".module")
6373 return parseDirectiveModule();
6374
6375 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
6376 return parseInternalDirectiveReallowModule();
6377
6378 if (IDVal == ".insn")
6379 return parseInsnDirective();
6380
6381 if (IDVal == ".sbss")
6382 return parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
6383 if (IDVal == ".sdata")
6384 return parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
6385
6386 return true;
6387}
6388
6389bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6390 // If this is not the end of the statement, report an error.
6391 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6392 reportParseError("unexpected token, expected end of statement");
6393 return false;
6394 }
6395
6396 getTargetStreamer().reallowModuleDirective();
6397
6398 getParser().Lex(); // Eat EndOfStatement token.
6399 return false;
6400}
6401
6402extern "C" void LLVMInitializeMipsAsmParser() {
6403 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
6404 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
6405 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
6406 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
6407}
6408
6409#define GET_REGISTER_MATCHER
6410#define GET_MATCHER_IMPLEMENTATION
6411#include "MipsGenAsmMatcher.inc"