Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
35294 views
1
//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "MCTargetDesc/MipsABIFlagsSection.h"
10
#include "MCTargetDesc/MipsABIInfo.h"
11
#include "MCTargetDesc/MipsBaseInfo.h"
12
#include "MCTargetDesc/MipsMCExpr.h"
13
#include "MCTargetDesc/MipsMCTargetDesc.h"
14
#include "MipsTargetStreamer.h"
15
#include "TargetInfo/MipsTargetInfo.h"
16
#include "llvm/ADT/APFloat.h"
17
#include "llvm/ADT/STLExtras.h"
18
#include "llvm/ADT/SmallVector.h"
19
#include "llvm/ADT/StringRef.h"
20
#include "llvm/ADT/StringSwitch.h"
21
#include "llvm/ADT/Twine.h"
22
#include "llvm/BinaryFormat/ELF.h"
23
#include "llvm/MC/MCContext.h"
24
#include "llvm/MC/MCExpr.h"
25
#include "llvm/MC/MCInst.h"
26
#include "llvm/MC/MCInstrDesc.h"
27
#include "llvm/MC/MCInstrInfo.h"
28
#include "llvm/MC/MCObjectFileInfo.h"
29
#include "llvm/MC/MCParser/MCAsmLexer.h"
30
#include "llvm/MC/MCParser/MCAsmParser.h"
31
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
32
#include "llvm/MC/MCParser/MCAsmParserUtils.h"
33
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
35
#include "llvm/MC/MCSectionELF.h"
36
#include "llvm/MC/MCStreamer.h"
37
#include "llvm/MC/MCSubtargetInfo.h"
38
#include "llvm/MC/MCSymbol.h"
39
#include "llvm/MC/MCSymbolELF.h"
40
#include "llvm/MC/MCValue.h"
41
#include "llvm/MC/TargetRegistry.h"
42
#include "llvm/Support/Alignment.h"
43
#include "llvm/Support/Casting.h"
44
#include "llvm/Support/CommandLine.h"
45
#include "llvm/Support/Compiler.h"
46
#include "llvm/Support/Debug.h"
47
#include "llvm/Support/ErrorHandling.h"
48
#include "llvm/Support/MathExtras.h"
49
#include "llvm/Support/SMLoc.h"
50
#include "llvm/Support/SourceMgr.h"
51
#include "llvm/Support/raw_ostream.h"
52
#include "llvm/TargetParser/SubtargetFeature.h"
53
#include "llvm/TargetParser/Triple.h"
54
#include <algorithm>
55
#include <cassert>
56
#include <cstdint>
57
#include <memory>
58
#include <string>
59
#include <utility>
60
61
using namespace llvm;
62
63
#define DEBUG_TYPE "mips-asm-parser"
64
65
namespace llvm {
66
67
class MCInstrInfo;
68
69
} // end namespace llvm
70
71
extern cl::opt<bool> EmitJalrReloc;
72
73
namespace {
74
75
class MipsAssemblerOptions {
76
public:
77
MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
78
79
MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
80
ATReg = Opts->getATRegIndex();
81
Reorder = Opts->isReorder();
82
Macro = Opts->isMacro();
83
Features = Opts->getFeatures();
84
}
85
86
unsigned getATRegIndex() const { return ATReg; }
87
bool setATRegIndex(unsigned Reg) {
88
if (Reg > 31)
89
return false;
90
91
ATReg = Reg;
92
return true;
93
}
94
95
bool isReorder() const { return Reorder; }
96
void setReorder() { Reorder = true; }
97
void setNoReorder() { Reorder = false; }
98
99
bool isMacro() const { return Macro; }
100
void setMacro() { Macro = true; }
101
void setNoMacro() { Macro = false; }
102
103
const FeatureBitset &getFeatures() const { return Features; }
104
void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
105
106
// Set of features that are either architecture features or referenced
107
// by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
108
// The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
109
// The reason we need this mask is explained in the selectArch function.
110
// FIXME: Ideally we would like TableGen to generate this information.
111
static const FeatureBitset AllArchRelatedMask;
112
113
private:
114
unsigned ATReg = 1;
115
bool Reorder = true;
116
bool Macro = true;
117
FeatureBitset Features;
118
};
119
120
} // end anonymous namespace
121
122
const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123
Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124
Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125
Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126
Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127
Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128
Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129
Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130
Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
131
Mips::FeatureNaN2008
132
};
133
134
namespace {
135
136
class MipsAsmParser : public MCTargetAsmParser {
137
MipsTargetStreamer &getTargetStreamer() {
138
assert(getParser().getStreamer().getTargetStreamer() &&
139
"do not have a target streamer");
140
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141
return static_cast<MipsTargetStreamer &>(TS);
142
}
143
144
MipsABIInfo ABI;
145
SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
146
MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
147
// nullptr, which indicates that no function is currently
148
// selected. This usually happens after an '.end func'
149
// directive.
150
bool IsLittleEndian;
151
bool IsPicEnabled;
152
bool IsCpRestoreSet;
153
bool CurForbiddenSlotAttr;
154
int CpRestoreOffset;
155
unsigned GPReg;
156
unsigned CpSaveLocation;
157
/// If true, then CpSaveLocation is a register, otherwise it's an offset.
158
bool CpSaveLocationIsRegister;
159
160
// Map of register aliases created via the .set directive.
161
StringMap<AsmToken> RegisterSets;
162
163
// Print a warning along with its fix-it message at the given range.
164
void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
165
SMRange Range, bool ShowColors = true);
166
167
void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
168
169
#define GET_ASSEMBLER_HEADER
170
#include "MipsGenAsmMatcher.inc"
171
172
unsigned
173
checkEarlyTargetMatchPredicate(MCInst &Inst,
174
const OperandVector &Operands) override;
175
unsigned checkTargetMatchPredicate(MCInst &Inst) override;
176
177
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
178
OperandVector &Operands, MCStreamer &Out,
179
uint64_t &ErrorInfo,
180
bool MatchingInlineAsm) override;
181
182
/// Parse a register as used in CFI directives
183
bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
184
ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
185
SMLoc &EndLoc) override;
186
187
bool parseParenSuffix(StringRef Name, OperandVector &Operands);
188
189
bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
190
191
bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
192
193
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
194
SMLoc NameLoc, OperandVector &Operands) override;
195
196
bool ParseDirective(AsmToken DirectiveID) override;
197
198
ParseStatus parseMemOperand(OperandVector &Operands);
199
ParseStatus matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
200
StringRef Identifier, SMLoc S);
201
ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands,
202
const AsmToken &Token, SMLoc S);
203
ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
204
ParseStatus parseAnyRegister(OperandVector &Operands);
205
ParseStatus parseImm(OperandVector &Operands);
206
ParseStatus parseJumpTarget(OperandVector &Operands);
207
ParseStatus parseInvNum(OperandVector &Operands);
208
ParseStatus parseRegisterList(OperandVector &Operands);
209
210
bool searchSymbolAlias(OperandVector &Operands);
211
212
bool parseOperand(OperandVector &, StringRef Mnemonic);
213
214
enum MacroExpanderResultTy {
215
MER_NotAMacro,
216
MER_Success,
217
MER_Fail,
218
};
219
220
// Expands assembly pseudo instructions.
221
MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
222
MCStreamer &Out,
223
const MCSubtargetInfo *STI);
224
225
bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
226
const MCSubtargetInfo *STI);
227
228
bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
229
bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
230
MCStreamer &Out, const MCSubtargetInfo *STI);
231
232
bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
233
unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
234
MCStreamer &Out, const MCSubtargetInfo *STI);
235
236
bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
237
238
bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
239
MCStreamer &Out, const MCSubtargetInfo *STI);
240
241
bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
242
const MCSubtargetInfo *STI);
243
bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244
const MCSubtargetInfo *STI);
245
bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246
const MCSubtargetInfo *STI);
247
bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
248
MCStreamer &Out, const MCSubtargetInfo *STI);
249
250
bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
251
const MCOperand &Offset, bool Is32BitAddress,
252
SMLoc IDLoc, MCStreamer &Out,
253
const MCSubtargetInfo *STI);
254
255
bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256
const MCSubtargetInfo *STI);
257
258
void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259
const MCSubtargetInfo *STI, bool IsLoad);
260
void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261
const MCSubtargetInfo *STI, bool IsLoad);
262
263
bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264
const MCSubtargetInfo *STI);
265
266
bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
267
const MCSubtargetInfo *STI);
268
269
bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270
const MCSubtargetInfo *STI);
271
272
bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
273
const MCSubtargetInfo *STI);
274
275
bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
276
const MCSubtargetInfo *STI, const bool IsMips64,
277
const bool Signed);
278
279
bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
280
MCStreamer &Out, const MCSubtargetInfo *STI);
281
282
bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
283
const MCSubtargetInfo *STI);
284
285
bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286
const MCSubtargetInfo *STI);
287
288
bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289
const MCSubtargetInfo *STI);
290
291
bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292
const MCSubtargetInfo *STI);
293
294
bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295
const MCSubtargetInfo *STI);
296
297
bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298
const MCSubtargetInfo *STI);
299
300
bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301
const MCSubtargetInfo *STI);
302
303
bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304
const MCSubtargetInfo *STI);
305
306
bool expandRotation(MCInst &Inst, SMLoc IDLoc,
307
MCStreamer &Out, const MCSubtargetInfo *STI);
308
bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
309
const MCSubtargetInfo *STI);
310
bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311
const MCSubtargetInfo *STI);
312
bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313
const MCSubtargetInfo *STI);
314
315
bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316
const MCSubtargetInfo *STI);
317
318
bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319
const MCSubtargetInfo *STI);
320
321
bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322
const MCSubtargetInfo *STI);
323
324
bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325
const MCSubtargetInfo *STI);
326
327
bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
328
const MCSubtargetInfo *STI);
329
330
bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
331
const MCSubtargetInfo *STI, bool IsLoad);
332
333
bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
334
const MCSubtargetInfo *STI);
335
336
bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
337
const MCSubtargetInfo *STI);
338
339
bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
340
const MCSubtargetInfo *STI);
341
342
bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
343
const MCSubtargetInfo *STI);
344
345
bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
346
const MCSubtargetInfo *STI);
347
348
bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
349
const MCSubtargetInfo *STI);
350
351
bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
352
const MCSubtargetInfo *STI);
353
354
bool reportParseError(const Twine &ErrorMsg);
355
bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
356
357
bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
358
359
bool parseSetMips0Directive();
360
bool parseSetArchDirective();
361
bool parseSetFeature(uint64_t Feature);
362
bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
363
bool parseDirectiveCpAdd(SMLoc Loc);
364
bool parseDirectiveCpLoad(SMLoc Loc);
365
bool parseDirectiveCpLocal(SMLoc Loc);
366
bool parseDirectiveCpRestore(SMLoc Loc);
367
bool parseDirectiveCPSetup();
368
bool parseDirectiveCPReturn();
369
bool parseDirectiveNaN();
370
bool parseDirectiveSet();
371
bool parseDirectiveOption();
372
bool parseInsnDirective();
373
bool parseRSectionDirective(StringRef Section);
374
bool parseSSectionDirective(StringRef Section, unsigned Type);
375
376
bool parseSetAtDirective();
377
bool parseSetNoAtDirective();
378
bool parseSetMacroDirective();
379
bool parseSetNoMacroDirective();
380
bool parseSetMsaDirective();
381
bool parseSetNoMsaDirective();
382
bool parseSetNoDspDirective();
383
bool parseSetNoMips3DDirective();
384
bool parseSetReorderDirective();
385
bool parseSetNoReorderDirective();
386
bool parseSetMips16Directive();
387
bool parseSetNoMips16Directive();
388
bool parseSetFpDirective();
389
bool parseSetOddSPRegDirective();
390
bool parseSetNoOddSPRegDirective();
391
bool parseSetPopDirective();
392
bool parseSetPushDirective();
393
bool parseSetSoftFloatDirective();
394
bool parseSetHardFloatDirective();
395
bool parseSetMtDirective();
396
bool parseSetNoMtDirective();
397
bool parseSetNoCRCDirective();
398
bool parseSetNoVirtDirective();
399
bool parseSetNoGINVDirective();
400
401
bool parseSetAssignment();
402
403
bool parseDirectiveGpWord();
404
bool parseDirectiveGpDWord();
405
bool parseDirectiveDtpRelWord();
406
bool parseDirectiveDtpRelDWord();
407
bool parseDirectiveTpRelWord();
408
bool parseDirectiveTpRelDWord();
409
bool parseDirectiveModule();
410
bool parseDirectiveModuleFP();
411
bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
412
StringRef Directive);
413
414
bool parseInternalDirectiveReallowModule();
415
416
bool eatComma(StringRef ErrorStr);
417
418
int matchCPURegisterName(StringRef Symbol);
419
420
int matchHWRegsRegisterName(StringRef Symbol);
421
422
int matchFPURegisterName(StringRef Name);
423
424
int matchFCCRegisterName(StringRef Name);
425
426
int matchACRegisterName(StringRef Name);
427
428
int matchMSA128RegisterName(StringRef Name);
429
430
int matchMSA128CtrlRegisterName(StringRef Name);
431
432
unsigned getReg(int RC, int RegNo);
433
434
/// Returns the internal register number for the current AT. Also checks if
435
/// the current AT is unavailable (set to $0) and gives an error if it is.
436
/// This should be used in pseudo-instruction expansions which need AT.
437
unsigned getATReg(SMLoc Loc);
438
439
bool canUseATReg();
440
441
bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
442
const MCSubtargetInfo *STI);
443
444
// Helper function that checks if the value of a vector index is within the
445
// boundaries of accepted values for each RegisterKind
446
// Example: INSERT.B $w0[n], $1 => 16 > n >= 0
447
bool validateMSAIndex(int Val, int RegKind);
448
449
// Selects a new architecture by updating the FeatureBits with the necessary
450
// info including implied dependencies.
451
// Internally, it clears all the feature bits related to *any* architecture
452
// and selects the new one using the ToggleFeature functionality of the
453
// MCSubtargetInfo object that handles implied dependencies. The reason we
454
// clear all the arch related bits manually is because ToggleFeature only
455
// clears the features that imply the feature being cleared and not the
456
// features implied by the feature being cleared. This is easier to see
457
// with an example:
458
// --------------------------------------------------
459
// | Feature | Implies |
460
// | -------------------------------------------------|
461
// | FeatureMips1 | None |
462
// | FeatureMips2 | FeatureMips1 |
463
// | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
464
// | FeatureMips4 | FeatureMips3 |
465
// | ... | |
466
// --------------------------------------------------
467
//
468
// Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
469
// FeatureMipsGP64 | FeatureMips1)
470
// Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
471
void selectArch(StringRef ArchFeature) {
472
MCSubtargetInfo &STI = copySTI();
473
FeatureBitset FeatureBits = STI.getFeatureBits();
474
FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
475
STI.setFeatureBits(FeatureBits);
476
setAvailableFeatures(
477
ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
478
AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
479
}
480
481
void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
482
if (!(getSTI().hasFeature(Feature))) {
483
MCSubtargetInfo &STI = copySTI();
484
setAvailableFeatures(
485
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
486
AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
487
}
488
}
489
490
void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
491
if (getSTI().hasFeature(Feature)) {
492
MCSubtargetInfo &STI = copySTI();
493
setAvailableFeatures(
494
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
495
AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
496
}
497
}
498
499
void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
500
setFeatureBits(Feature, FeatureString);
501
AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
502
}
503
504
void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
505
clearFeatureBits(Feature, FeatureString);
506
AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
507
}
508
509
public:
510
enum MipsMatchResultTy {
511
Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
512
Match_RequiresDifferentOperands,
513
Match_RequiresNoZeroRegister,
514
Match_RequiresSameSrcAndDst,
515
Match_NoFCCRegisterForCurrentISA,
516
Match_NonZeroOperandForSync,
517
Match_NonZeroOperandForMTCX,
518
Match_RequiresPosSizeRange0_32,
519
Match_RequiresPosSizeRange33_64,
520
Match_RequiresPosSizeUImm6,
521
#define GET_OPERAND_DIAGNOSTIC_TYPES
522
#include "MipsGenAsmMatcher.inc"
523
#undef GET_OPERAND_DIAGNOSTIC_TYPES
524
};
525
526
MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
527
const MCInstrInfo &MII, const MCTargetOptions &Options)
528
: MCTargetAsmParser(Options, sti, MII),
529
ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
530
sti.getCPU(), Options)) {
531
MCAsmParserExtension::Initialize(parser);
532
533
parser.addAliasForDirective(".asciiz", ".asciz");
534
parser.addAliasForDirective(".hword", ".2byte");
535
parser.addAliasForDirective(".word", ".4byte");
536
parser.addAliasForDirective(".dword", ".8byte");
537
538
// Initialize the set of available features.
539
setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
540
541
// Remember the initial assembler options. The user can not modify these.
542
AssemblerOptions.push_back(
543
std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
544
545
// Create an assembler options environment for the user to modify.
546
AssemblerOptions.push_back(
547
std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
548
549
getTargetStreamer().updateABIInfo(*this);
550
551
if (!isABI_O32() && !useOddSPReg() != 0)
552
report_fatal_error("-mno-odd-spreg requires the O32 ABI");
553
554
CurrentFn = nullptr;
555
556
CurForbiddenSlotAttr = false;
557
IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
558
559
IsCpRestoreSet = false;
560
CpRestoreOffset = -1;
561
GPReg = ABI.GetGlobalPtr();
562
563
const Triple &TheTriple = sti.getTargetTriple();
564
IsLittleEndian = TheTriple.isLittleEndian();
565
566
if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
567
report_fatal_error("microMIPS64R6 is not supported", false);
568
569
if (!isABI_O32() && inMicroMipsMode())
570
report_fatal_error("microMIPS64 is not supported", false);
571
}
572
573
/// True if all of $fcc0 - $fcc7 exist for the current ISA.
574
bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
575
576
bool isGP64bit() const {
577
return getSTI().hasFeature(Mips::FeatureGP64Bit);
578
}
579
580
bool isFP64bit() const {
581
return getSTI().hasFeature(Mips::FeatureFP64Bit);
582
}
583
584
bool isJalrRelocAvailable(const MCExpr *JalExpr) {
585
if (!EmitJalrReloc)
586
return false;
587
MCValue Res;
588
if (!JalExpr->evaluateAsRelocatable(Res, nullptr, nullptr))
589
return false;
590
if (Res.getSymB() != nullptr)
591
return false;
592
if (Res.getConstant() != 0)
593
return ABI.IsN32() || ABI.IsN64();
594
return true;
595
}
596
597
const MipsABIInfo &getABI() const { return ABI; }
598
bool isABI_N32() const { return ABI.IsN32(); }
599
bool isABI_N64() const { return ABI.IsN64(); }
600
bool isABI_O32() const { return ABI.IsO32(); }
601
bool isABI_FPXX() const {
602
return getSTI().hasFeature(Mips::FeatureFPXX);
603
}
604
605
bool useOddSPReg() const {
606
return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
607
}
608
609
bool inMicroMipsMode() const {
610
return getSTI().hasFeature(Mips::FeatureMicroMips);
611
}
612
613
bool hasMips1() const {
614
return getSTI().hasFeature(Mips::FeatureMips1);
615
}
616
617
bool hasMips2() const {
618
return getSTI().hasFeature(Mips::FeatureMips2);
619
}
620
621
bool hasMips3() const {
622
return getSTI().hasFeature(Mips::FeatureMips3);
623
}
624
625
bool hasMips4() const {
626
return getSTI().hasFeature(Mips::FeatureMips4);
627
}
628
629
bool hasMips5() const {
630
return getSTI().hasFeature(Mips::FeatureMips5);
631
}
632
633
bool hasMips32() const {
634
return getSTI().hasFeature(Mips::FeatureMips32);
635
}
636
637
bool hasMips64() const {
638
return getSTI().hasFeature(Mips::FeatureMips64);
639
}
640
641
bool hasMips32r2() const {
642
return getSTI().hasFeature(Mips::FeatureMips32r2);
643
}
644
645
bool hasMips64r2() const {
646
return getSTI().hasFeature(Mips::FeatureMips64r2);
647
}
648
649
bool hasMips32r3() const {
650
return (getSTI().hasFeature(Mips::FeatureMips32r3));
651
}
652
653
bool hasMips64r3() const {
654
return (getSTI().hasFeature(Mips::FeatureMips64r3));
655
}
656
657
bool hasMips32r5() const {
658
return (getSTI().hasFeature(Mips::FeatureMips32r5));
659
}
660
661
bool hasMips64r5() const {
662
return (getSTI().hasFeature(Mips::FeatureMips64r5));
663
}
664
665
bool hasMips32r6() const {
666
return getSTI().hasFeature(Mips::FeatureMips32r6);
667
}
668
669
bool hasMips64r6() const {
670
return getSTI().hasFeature(Mips::FeatureMips64r6);
671
}
672
673
bool hasDSP() const {
674
return getSTI().hasFeature(Mips::FeatureDSP);
675
}
676
677
bool hasDSPR2() const {
678
return getSTI().hasFeature(Mips::FeatureDSPR2);
679
}
680
681
bool hasDSPR3() const {
682
return getSTI().hasFeature(Mips::FeatureDSPR3);
683
}
684
685
bool hasMSA() const {
686
return getSTI().hasFeature(Mips::FeatureMSA);
687
}
688
689
bool hasCnMips() const {
690
return (getSTI().hasFeature(Mips::FeatureCnMips));
691
}
692
693
bool hasCnMipsP() const {
694
return (getSTI().hasFeature(Mips::FeatureCnMipsP));
695
}
696
697
bool inPicMode() {
698
return IsPicEnabled;
699
}
700
701
bool inMips16Mode() const {
702
return getSTI().hasFeature(Mips::FeatureMips16);
703
}
704
705
bool useTraps() const {
706
return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
707
}
708
709
bool useSoftFloat() const {
710
return getSTI().hasFeature(Mips::FeatureSoftFloat);
711
}
712
bool hasMT() const {
713
return getSTI().hasFeature(Mips::FeatureMT);
714
}
715
716
bool hasCRC() const {
717
return getSTI().hasFeature(Mips::FeatureCRC);
718
}
719
720
bool hasVirt() const {
721
return getSTI().hasFeature(Mips::FeatureVirt);
722
}
723
724
bool hasGINV() const {
725
return getSTI().hasFeature(Mips::FeatureGINV);
726
}
727
728
bool hasForbiddenSlot(const MCInstrDesc &MCID) const {
729
return !inMicroMipsMode() && (MCID.TSFlags & MipsII::HasForbiddenSlot);
730
}
731
732
bool SafeInForbiddenSlot(const MCInstrDesc &MCID) const {
733
return !(MCID.TSFlags & MipsII::IsCTI);
734
}
735
736
void onEndOfFile() override;
737
738
/// Warn if RegIndex is the same as the current AT.
739
void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
740
741
void warnIfNoMacro(SMLoc Loc);
742
743
bool isLittle() const { return IsLittleEndian; }
744
745
const MCExpr *createTargetUnaryExpr(const MCExpr *E,
746
AsmToken::TokenKind OperatorToken,
747
MCContext &Ctx) override {
748
switch(OperatorToken) {
749
default:
750
llvm_unreachable("Unknown token");
751
return nullptr;
752
case AsmToken::PercentCall16:
753
return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
754
case AsmToken::PercentCall_Hi:
755
return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
756
case AsmToken::PercentCall_Lo:
757
return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
758
case AsmToken::PercentDtprel_Hi:
759
return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
760
case AsmToken::PercentDtprel_Lo:
761
return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
762
case AsmToken::PercentGot:
763
return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
764
case AsmToken::PercentGot_Disp:
765
return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
766
case AsmToken::PercentGot_Hi:
767
return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
768
case AsmToken::PercentGot_Lo:
769
return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
770
case AsmToken::PercentGot_Ofst:
771
return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
772
case AsmToken::PercentGot_Page:
773
return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
774
case AsmToken::PercentGottprel:
775
return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
776
case AsmToken::PercentGp_Rel:
777
return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
778
case AsmToken::PercentHi:
779
return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
780
case AsmToken::PercentHigher:
781
return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
782
case AsmToken::PercentHighest:
783
return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
784
case AsmToken::PercentLo:
785
return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
786
case AsmToken::PercentNeg:
787
return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
788
case AsmToken::PercentPcrel_Hi:
789
return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
790
case AsmToken::PercentPcrel_Lo:
791
return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
792
case AsmToken::PercentTlsgd:
793
return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
794
case AsmToken::PercentTlsldm:
795
return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
796
case AsmToken::PercentTprel_Hi:
797
return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
798
case AsmToken::PercentTprel_Lo:
799
return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
800
}
801
}
802
803
bool areEqualRegs(const MCParsedAsmOperand &Op1,
804
const MCParsedAsmOperand &Op2) const override;
805
};
806
807
/// MipsOperand - Instances of this class represent a parsed Mips machine
808
/// instruction.
809
class MipsOperand : public MCParsedAsmOperand {
810
public:
811
/// Broad categories of register classes
812
/// The exact class is finalized by the render method.
813
enum RegKind {
814
RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
815
RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
816
/// isFP64bit())
817
RegKind_FCC = 4, /// FCC
818
RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
819
RegKind_MSACtrl = 16, /// MSA control registers
820
RegKind_COP2 = 32, /// COP2
821
RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
822
/// context).
823
RegKind_CCR = 128, /// CCR
824
RegKind_HWRegs = 256, /// HWRegs
825
RegKind_COP3 = 512, /// COP3
826
RegKind_COP0 = 1024, /// COP0
827
/// Potentially any (e.g. $1)
828
RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
829
RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
830
RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
831
};
832
833
private:
834
enum KindTy {
835
k_Immediate, /// An immediate (possibly involving symbol references)
836
k_Memory, /// Base + Offset Memory Address
837
k_RegisterIndex, /// A register index in one or more RegKind.
838
k_Token, /// A simple token
839
k_RegList, /// A physical register list
840
} Kind;
841
842
public:
843
MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(K), AsmParser(Parser) {}
844
845
~MipsOperand() override {
846
switch (Kind) {
847
case k_Memory:
848
delete Mem.Base;
849
break;
850
case k_RegList:
851
delete RegList.List;
852
break;
853
case k_Immediate:
854
case k_RegisterIndex:
855
case k_Token:
856
break;
857
}
858
}
859
860
private:
861
/// For diagnostics, and checking the assembler temporary
862
MipsAsmParser &AsmParser;
863
864
struct Token {
865
const char *Data;
866
unsigned Length;
867
};
868
869
struct RegIdxOp {
870
unsigned Index; /// Index into the register class
871
RegKind Kind; /// Bitfield of the kinds it could possibly be
872
struct Token Tok; /// The input token this operand originated from.
873
const MCRegisterInfo *RegInfo;
874
};
875
876
struct ImmOp {
877
const MCExpr *Val;
878
};
879
880
struct MemOp {
881
MipsOperand *Base;
882
const MCExpr *Off;
883
};
884
885
struct RegListOp {
886
SmallVector<unsigned, 10> *List;
887
};
888
889
union {
890
struct Token Tok;
891
struct RegIdxOp RegIdx;
892
struct ImmOp Imm;
893
struct MemOp Mem;
894
struct RegListOp RegList;
895
};
896
897
SMLoc StartLoc, EndLoc;
898
899
/// Internal constructor for register kinds
900
static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
901
RegKind RegKind,
902
const MCRegisterInfo *RegInfo,
903
SMLoc S, SMLoc E,
904
MipsAsmParser &Parser) {
905
auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
906
Op->RegIdx.Index = Index;
907
Op->RegIdx.RegInfo = RegInfo;
908
Op->RegIdx.Kind = RegKind;
909
Op->RegIdx.Tok.Data = Str.data();
910
Op->RegIdx.Tok.Length = Str.size();
911
Op->StartLoc = S;
912
Op->EndLoc = E;
913
return Op;
914
}
915
916
public:
917
/// Coerce the register to GPR32 and return the real register for the current
918
/// target.
919
unsigned getGPR32Reg() const {
920
assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
921
AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
922
unsigned ClassID = Mips::GPR32RegClassID;
923
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
924
}
925
926
/// Coerce the register to GPR32 and return the real register for the current
927
/// target.
928
unsigned getGPRMM16Reg() const {
929
assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
930
unsigned ClassID = Mips::GPR32RegClassID;
931
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
932
}
933
934
/// Coerce the register to GPR64 and return the real register for the current
935
/// target.
936
unsigned getGPR64Reg() const {
937
assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
938
unsigned ClassID = Mips::GPR64RegClassID;
939
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
940
}
941
942
private:
943
/// Coerce the register to AFGR64 and return the real register for the current
944
/// target.
945
unsigned getAFGR64Reg() const {
946
assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
947
if (RegIdx.Index % 2 != 0)
948
AsmParser.Warning(StartLoc, "Float register should be even.");
949
return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
950
.getRegister(RegIdx.Index / 2);
951
}
952
953
/// Coerce the register to FGR64 and return the real register for the current
954
/// target.
955
unsigned getFGR64Reg() const {
956
assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
957
return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
958
.getRegister(RegIdx.Index);
959
}
960
961
/// Coerce the register to FGR32 and return the real register for the current
962
/// target.
963
unsigned getFGR32Reg() const {
964
assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
965
return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
966
.getRegister(RegIdx.Index);
967
}
968
969
/// Coerce the register to FCC and return the real register for the current
970
/// target.
971
unsigned getFCCReg() const {
972
assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
973
return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
974
.getRegister(RegIdx.Index);
975
}
976
977
/// Coerce the register to MSA128 and return the real register for the current
978
/// target.
979
unsigned getMSA128Reg() const {
980
assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
981
// It doesn't matter which of the MSA128[BHWD] classes we use. They are all
982
// identical
983
unsigned ClassID = Mips::MSA128BRegClassID;
984
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985
}
986
987
/// Coerce the register to MSACtrl and return the real register for the
988
/// current target.
989
unsigned getMSACtrlReg() const {
990
assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
991
unsigned ClassID = Mips::MSACtrlRegClassID;
992
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
993
}
994
995
/// Coerce the register to COP0 and return the real register for the
996
/// current target.
997
unsigned getCOP0Reg() const {
998
assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
999
unsigned ClassID = Mips::COP0RegClassID;
1000
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1001
}
1002
1003
/// Coerce the register to COP2 and return the real register for the
1004
/// current target.
1005
unsigned getCOP2Reg() const {
1006
assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
1007
unsigned ClassID = Mips::COP2RegClassID;
1008
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1009
}
1010
1011
/// Coerce the register to COP3 and return the real register for the
1012
/// current target.
1013
unsigned getCOP3Reg() const {
1014
assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
1015
unsigned ClassID = Mips::COP3RegClassID;
1016
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1017
}
1018
1019
/// Coerce the register to ACC64DSP and return the real register for the
1020
/// current target.
1021
unsigned getACC64DSPReg() const {
1022
assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1023
unsigned ClassID = Mips::ACC64DSPRegClassID;
1024
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1025
}
1026
1027
/// Coerce the register to HI32DSP and return the real register for the
1028
/// current target.
1029
unsigned getHI32DSPReg() const {
1030
assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1031
unsigned ClassID = Mips::HI32DSPRegClassID;
1032
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1033
}
1034
1035
/// Coerce the register to LO32DSP and return the real register for the
1036
/// current target.
1037
unsigned getLO32DSPReg() const {
1038
assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1039
unsigned ClassID = Mips::LO32DSPRegClassID;
1040
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1041
}
1042
1043
/// Coerce the register to CCR and return the real register for the
1044
/// current target.
1045
unsigned getCCRReg() const {
1046
assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
1047
unsigned ClassID = Mips::CCRRegClassID;
1048
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1049
}
1050
1051
/// Coerce the register to HWRegs and return the real register for the
1052
/// current target.
1053
unsigned getHWRegsReg() const {
1054
assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
1055
unsigned ClassID = Mips::HWRegsRegClassID;
1056
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1057
}
1058
1059
public:
1060
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1061
// Add as immediate when possible. Null MCExpr = 0.
1062
if (!Expr)
1063
Inst.addOperand(MCOperand::createImm(0));
1064
else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1065
Inst.addOperand(MCOperand::createImm(CE->getValue()));
1066
else
1067
Inst.addOperand(MCOperand::createExpr(Expr));
1068
}
1069
1070
void addRegOperands(MCInst &Inst, unsigned N) const {
1071
llvm_unreachable("Use a custom parser instead");
1072
}
1073
1074
/// Render the operand to an MCInst as a GPR32
1075
/// Asserts if the wrong number of operands are requested, or the operand
1076
/// is not a k_RegisterIndex compatible with RegKind_GPR
1077
void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1078
assert(N == 1 && "Invalid number of operands!");
1079
Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1080
}
1081
1082
void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1083
assert(N == 1 && "Invalid number of operands!");
1084
Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1085
}
1086
1087
void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1088
assert(N == 1 && "Invalid number of operands!");
1089
Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1090
}
1091
1092
void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1093
assert(N == 1 && "Invalid number of operands!");
1094
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1095
}
1096
1097
void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1098
assert(N == 1 && "Invalid number of operands!");
1099
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1100
}
1101
1102
void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1103
assert(N == 1 && "Invalid number of operands!");
1104
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1105
}
1106
1107
void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1108
assert(N == 1 && "Invalid number of operands!");
1109
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1110
}
1111
1112
void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1113
unsigned N) const {
1114
assert(N == 1 && "Invalid number of operands!");
1115
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1116
}
1117
1118
/// Render the operand to an MCInst as a GPR64
1119
/// Asserts if the wrong number of operands are requested, or the operand
1120
/// is not a k_RegisterIndex compatible with RegKind_GPR
1121
void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1122
assert(N == 1 && "Invalid number of operands!");
1123
Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1124
}
1125
1126
void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1127
assert(N == 1 && "Invalid number of operands!");
1128
Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1129
}
1130
1131
void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1132
assert(N == 1 && "Invalid number of operands!");
1133
Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1134
}
1135
1136
void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1137
assert(N == 1 && "Invalid number of operands!");
1138
Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1139
}
1140
1141
void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1142
assert(N == 1 && "Invalid number of operands!");
1143
Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1144
}
1145
1146
void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1147
assert(N == 1 && "Invalid number of operands!");
1148
Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1149
// FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1150
// FIXME: This should propagate failure up to parseStatement.
1151
if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1152
AsmParser.getParser().printError(
1153
StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1154
"registers");
1155
}
1156
1157
void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1158
assert(N == 1 && "Invalid number of operands!");
1159
Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1160
// FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1161
if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1162
AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1163
"registers");
1164
}
1165
1166
void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1167
assert(N == 1 && "Invalid number of operands!");
1168
Inst.addOperand(MCOperand::createReg(getFCCReg()));
1169
}
1170
1171
void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1172
assert(N == 1 && "Invalid number of operands!");
1173
Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1174
}
1175
1176
void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1177
assert(N == 1 && "Invalid number of operands!");
1178
Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1179
}
1180
1181
void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1182
assert(N == 1 && "Invalid number of operands!");
1183
Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1184
}
1185
1186
void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1187
assert(N == 1 && "Invalid number of operands!");
1188
Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1189
}
1190
1191
void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1192
assert(N == 1 && "Invalid number of operands!");
1193
Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1194
}
1195
1196
void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1197
assert(N == 1 && "Invalid number of operands!");
1198
Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1199
}
1200
1201
void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1202
assert(N == 1 && "Invalid number of operands!");
1203
Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1204
}
1205
1206
void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1207
assert(N == 1 && "Invalid number of operands!");
1208
Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1209
}
1210
1211
void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1212
assert(N == 1 && "Invalid number of operands!");
1213
Inst.addOperand(MCOperand::createReg(getCCRReg()));
1214
}
1215
1216
void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1217
assert(N == 1 && "Invalid number of operands!");
1218
Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1219
}
1220
1221
template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1222
void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1223
assert(N == 1 && "Invalid number of operands!");
1224
uint64_t Imm = getConstantImm() - Offset;
1225
Imm &= (1ULL << Bits) - 1;
1226
Imm += Offset;
1227
Imm += AdjustOffset;
1228
Inst.addOperand(MCOperand::createImm(Imm));
1229
}
1230
1231
template <unsigned Bits>
1232
void addSImmOperands(MCInst &Inst, unsigned N) const {
1233
if (isImm() && !isConstantImm()) {
1234
addExpr(Inst, getImm());
1235
return;
1236
}
1237
addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1238
}
1239
1240
template <unsigned Bits>
1241
void addUImmOperands(MCInst &Inst, unsigned N) const {
1242
if (isImm() && !isConstantImm()) {
1243
addExpr(Inst, getImm());
1244
return;
1245
}
1246
addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1247
}
1248
1249
template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1250
void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1251
assert(N == 1 && "Invalid number of operands!");
1252
int64_t Imm = getConstantImm() - Offset;
1253
Imm = SignExtend64<Bits>(Imm);
1254
Imm += Offset;
1255
Imm += AdjustOffset;
1256
Inst.addOperand(MCOperand::createImm(Imm));
1257
}
1258
1259
void addImmOperands(MCInst &Inst, unsigned N) const {
1260
assert(N == 1 && "Invalid number of operands!");
1261
const MCExpr *Expr = getImm();
1262
addExpr(Inst, Expr);
1263
}
1264
1265
void addMemOperands(MCInst &Inst, unsigned N) const {
1266
assert(N == 2 && "Invalid number of operands!");
1267
1268
Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1269
? getMemBase()->getGPR64Reg()
1270
: getMemBase()->getGPR32Reg()));
1271
1272
const MCExpr *Expr = getMemOff();
1273
addExpr(Inst, Expr);
1274
}
1275
1276
void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1277
assert(N == 2 && "Invalid number of operands!");
1278
1279
Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1280
1281
const MCExpr *Expr = getMemOff();
1282
addExpr(Inst, Expr);
1283
}
1284
1285
void addRegListOperands(MCInst &Inst, unsigned N) const {
1286
assert(N == 1 && "Invalid number of operands!");
1287
1288
for (auto RegNo : getRegList())
1289
Inst.addOperand(MCOperand::createReg(RegNo));
1290
}
1291
1292
bool isReg() const override {
1293
// As a special case until we sort out the definition of div/divu, accept
1294
// $0/$zero here so that MCK_ZERO works correctly.
1295
return isGPRAsmReg() && RegIdx.Index == 0;
1296
}
1297
1298
bool isRegIdx() const { return Kind == k_RegisterIndex; }
1299
bool isImm() const override { return Kind == k_Immediate; }
1300
1301
bool isConstantImm() const {
1302
int64_t Res;
1303
return isImm() && getImm()->evaluateAsAbsolute(Res);
1304
}
1305
1306
bool isConstantImmz() const {
1307
return isConstantImm() && getConstantImm() == 0;
1308
}
1309
1310
template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1311
return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1312
}
1313
1314
template <unsigned Bits> bool isSImm() const {
1315
return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1316
}
1317
1318
template <unsigned Bits> bool isUImm() const {
1319
return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1320
}
1321
1322
template <unsigned Bits> bool isAnyImm() const {
1323
return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1324
isUInt<Bits>(getConstantImm()))
1325
: isImm();
1326
}
1327
1328
template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1329
return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1330
}
1331
1332
template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1333
return isConstantImm() && getConstantImm() >= Bottom &&
1334
getConstantImm() <= Top;
1335
}
1336
1337
bool isToken() const override {
1338
// Note: It's not possible to pretend that other operand kinds are tokens.
1339
// The matcher emitter checks tokens first.
1340
return Kind == k_Token;
1341
}
1342
1343
bool isMem() const override { return Kind == k_Memory; }
1344
1345
bool isConstantMemOff() const {
1346
return isMem() && isa<MCConstantExpr>(getMemOff());
1347
}
1348
1349
// Allow relocation operators.
1350
template <unsigned Bits, unsigned ShiftAmount = 0>
1351
bool isMemWithSimmOffset() const {
1352
if (!isMem())
1353
return false;
1354
if (!getMemBase()->isGPRAsmReg())
1355
return false;
1356
if (isa<MCTargetExpr>(getMemOff()) ||
1357
(isConstantMemOff() &&
1358
isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1359
return true;
1360
MCValue Res;
1361
bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1362
return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1363
}
1364
1365
bool isMemWithPtrSizeOffset() const {
1366
if (!isMem())
1367
return false;
1368
if (!getMemBase()->isGPRAsmReg())
1369
return false;
1370
const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1371
if (isa<MCTargetExpr>(getMemOff()) ||
1372
(isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1373
return true;
1374
MCValue Res;
1375
bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1376
return IsReloc && isIntN(PtrBits, Res.getConstant());
1377
}
1378
1379
bool isMemWithGRPMM16Base() const {
1380
return isMem() && getMemBase()->isMM16AsmReg();
1381
}
1382
1383
template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1384
return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1385
&& getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1386
}
1387
1388
template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1389
return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1390
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1391
&& (getMemBase()->getGPR32Reg() == Mips::SP);
1392
}
1393
1394
template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1395
return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1396
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1397
&& (getMemBase()->getGPR32Reg() == Mips::GP);
1398
}
1399
1400
template <unsigned Bits, unsigned ShiftLeftAmount>
1401
bool isScaledUImm() const {
1402
return isConstantImm() &&
1403
isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1404
}
1405
1406
template <unsigned Bits, unsigned ShiftLeftAmount>
1407
bool isScaledSImm() const {
1408
if (isConstantImm() &&
1409
isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1410
return true;
1411
// Operand can also be a symbol or symbol plus
1412
// offset in case of relocations.
1413
if (Kind != k_Immediate)
1414
return false;
1415
MCValue Res;
1416
bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1417
return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1418
}
1419
1420
bool isRegList16() const {
1421
if (!isRegList())
1422
return false;
1423
1424
int Size = RegList.List->size();
1425
if (Size < 2 || Size > 5)
1426
return false;
1427
1428
unsigned R0 = RegList.List->front();
1429
unsigned R1 = RegList.List->back();
1430
if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1431
(R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1432
return false;
1433
1434
int PrevReg = *RegList.List->begin();
1435
for (int i = 1; i < Size - 1; i++) {
1436
int Reg = (*(RegList.List))[i];
1437
if ( Reg != PrevReg + 1)
1438
return false;
1439
PrevReg = Reg;
1440
}
1441
1442
return true;
1443
}
1444
1445
bool isInvNum() const { return Kind == k_Immediate; }
1446
1447
bool isLSAImm() const {
1448
if (!isConstantImm())
1449
return false;
1450
int64_t Val = getConstantImm();
1451
return 1 <= Val && Val <= 4;
1452
}
1453
1454
bool isRegList() const { return Kind == k_RegList; }
1455
1456
StringRef getToken() const {
1457
assert(Kind == k_Token && "Invalid access!");
1458
return StringRef(Tok.Data, Tok.Length);
1459
}
1460
1461
MCRegister getReg() const override {
1462
// As a special case until we sort out the definition of div/divu, accept
1463
// $0/$zero here so that MCK_ZERO works correctly.
1464
if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1465
RegIdx.Kind & RegKind_GPR)
1466
return getGPR32Reg(); // FIXME: GPR64 too
1467
1468
llvm_unreachable("Invalid access!");
1469
return 0;
1470
}
1471
1472
const MCExpr *getImm() const {
1473
assert((Kind == k_Immediate) && "Invalid access!");
1474
return Imm.Val;
1475
}
1476
1477
int64_t getConstantImm() const {
1478
const MCExpr *Val = getImm();
1479
int64_t Value = 0;
1480
(void)Val->evaluateAsAbsolute(Value);
1481
return Value;
1482
}
1483
1484
MipsOperand *getMemBase() const {
1485
assert((Kind == k_Memory) && "Invalid access!");
1486
return Mem.Base;
1487
}
1488
1489
const MCExpr *getMemOff() const {
1490
assert((Kind == k_Memory) && "Invalid access!");
1491
return Mem.Off;
1492
}
1493
1494
int64_t getConstantMemOff() const {
1495
return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1496
}
1497
1498
const SmallVectorImpl<unsigned> &getRegList() const {
1499
assert((Kind == k_RegList) && "Invalid access!");
1500
return *(RegList.List);
1501
}
1502
1503
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1504
MipsAsmParser &Parser) {
1505
auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1506
Op->Tok.Data = Str.data();
1507
Op->Tok.Length = Str.size();
1508
Op->StartLoc = S;
1509
Op->EndLoc = S;
1510
return Op;
1511
}
1512
1513
/// Create a numeric register (e.g. $1). The exact register remains
1514
/// unresolved until an instruction successfully matches
1515
static std::unique_ptr<MipsOperand>
1516
createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1517
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1518
LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1519
return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1520
}
1521
1522
/// Create a register that is definitely a GPR.
1523
/// This is typically only used for named registers such as $gp.
1524
static std::unique_ptr<MipsOperand>
1525
createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1526
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1527
return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1528
}
1529
1530
/// Create a register that is definitely a FGR.
1531
/// This is typically only used for named registers such as $f0.
1532
static std::unique_ptr<MipsOperand>
1533
createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1534
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1535
return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1536
}
1537
1538
/// Create a register that is definitely a HWReg.
1539
/// This is typically only used for named registers such as $hwr_cpunum.
1540
static std::unique_ptr<MipsOperand>
1541
createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1542
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1543
return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1544
}
1545
1546
/// Create a register that is definitely an FCC.
1547
/// This is typically only used for named registers such as $fcc0.
1548
static std::unique_ptr<MipsOperand>
1549
createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1550
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1551
return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1552
}
1553
1554
/// Create a register that is definitely an ACC.
1555
/// This is typically only used for named registers such as $ac0.
1556
static std::unique_ptr<MipsOperand>
1557
createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1558
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1559
return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1560
}
1561
1562
/// Create a register that is definitely an MSA128.
1563
/// This is typically only used for named registers such as $w0.
1564
static std::unique_ptr<MipsOperand>
1565
createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1566
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1567
return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1568
}
1569
1570
/// Create a register that is definitely an MSACtrl.
1571
/// This is typically only used for named registers such as $msaaccess.
1572
static std::unique_ptr<MipsOperand>
1573
createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1574
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1575
return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1576
}
1577
1578
static std::unique_ptr<MipsOperand>
1579
CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1580
auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1581
Op->Imm.Val = Val;
1582
Op->StartLoc = S;
1583
Op->EndLoc = E;
1584
return Op;
1585
}
1586
1587
static std::unique_ptr<MipsOperand>
1588
CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1589
SMLoc E, MipsAsmParser &Parser) {
1590
auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1591
Op->Mem.Base = Base.release();
1592
Op->Mem.Off = Off;
1593
Op->StartLoc = S;
1594
Op->EndLoc = E;
1595
return Op;
1596
}
1597
1598
static std::unique_ptr<MipsOperand>
1599
CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1600
MipsAsmParser &Parser) {
1601
assert(Regs.size() > 0 && "Empty list not allowed");
1602
1603
auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1604
Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1605
Op->StartLoc = StartLoc;
1606
Op->EndLoc = EndLoc;
1607
return Op;
1608
}
1609
1610
bool isGPRZeroAsmReg() const {
1611
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1612
}
1613
1614
bool isGPRNonZeroAsmReg() const {
1615
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1616
RegIdx.Index <= 31;
1617
}
1618
1619
bool isGPRAsmReg() const {
1620
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1621
}
1622
1623
bool isMM16AsmReg() const {
1624
if (!(isRegIdx() && RegIdx.Kind))
1625
return false;
1626
return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1627
|| RegIdx.Index == 16 || RegIdx.Index == 17);
1628
1629
}
1630
bool isMM16AsmRegZero() const {
1631
if (!(isRegIdx() && RegIdx.Kind))
1632
return false;
1633
return (RegIdx.Index == 0 ||
1634
(RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1635
RegIdx.Index == 17);
1636
}
1637
1638
bool isMM16AsmRegMoveP() const {
1639
if (!(isRegIdx() && RegIdx.Kind))
1640
return false;
1641
return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1642
(RegIdx.Index >= 16 && RegIdx.Index <= 20));
1643
}
1644
1645
bool isMM16AsmRegMovePPairFirst() const {
1646
if (!(isRegIdx() && RegIdx.Kind))
1647
return false;
1648
return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1649
}
1650
1651
bool isMM16AsmRegMovePPairSecond() const {
1652
if (!(isRegIdx() && RegIdx.Kind))
1653
return false;
1654
return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1655
(RegIdx.Index >= 5 && RegIdx.Index <= 7));
1656
}
1657
1658
bool isFGRAsmReg() const {
1659
// AFGR64 is $0-$15 but we handle this in getAFGR64()
1660
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1661
}
1662
1663
bool isStrictlyFGRAsmReg() const {
1664
// AFGR64 is $0-$15 but we handle this in getAFGR64()
1665
return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1666
}
1667
1668
bool isHWRegsAsmReg() const {
1669
return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1670
}
1671
1672
bool isCCRAsmReg() const {
1673
return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1674
}
1675
1676
bool isFCCAsmReg() const {
1677
if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1678
return false;
1679
return RegIdx.Index <= 7;
1680
}
1681
1682
bool isACCAsmReg() const {
1683
return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1684
}
1685
1686
bool isCOP0AsmReg() const {
1687
return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1688
}
1689
1690
bool isCOP2AsmReg() const {
1691
return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1692
}
1693
1694
bool isCOP3AsmReg() const {
1695
return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1696
}
1697
1698
bool isMSA128AsmReg() const {
1699
return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1700
}
1701
1702
bool isMSACtrlAsmReg() const {
1703
return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1704
}
1705
1706
/// getStartLoc - Get the location of the first token of this operand.
1707
SMLoc getStartLoc() const override { return StartLoc; }
1708
/// getEndLoc - Get the location of the last token of this operand.
1709
SMLoc getEndLoc() const override { return EndLoc; }
1710
1711
void print(raw_ostream &OS) const override {
1712
switch (Kind) {
1713
case k_Immediate:
1714
OS << "Imm<";
1715
OS << *Imm.Val;
1716
OS << ">";
1717
break;
1718
case k_Memory:
1719
OS << "Mem<";
1720
Mem.Base->print(OS);
1721
OS << ", ";
1722
OS << *Mem.Off;
1723
OS << ">";
1724
break;
1725
case k_RegisterIndex:
1726
OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1727
<< StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1728
break;
1729
case k_Token:
1730
OS << getToken();
1731
break;
1732
case k_RegList:
1733
OS << "RegList< ";
1734
for (auto Reg : (*RegList.List))
1735
OS << Reg << " ";
1736
OS << ">";
1737
break;
1738
}
1739
}
1740
1741
bool isValidForTie(const MipsOperand &Other) const {
1742
if (Kind != Other.Kind)
1743
return false;
1744
1745
switch (Kind) {
1746
default:
1747
llvm_unreachable("Unexpected kind");
1748
return false;
1749
case k_RegisterIndex: {
1750
StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1751
StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1752
return Token == OtherToken;
1753
}
1754
}
1755
}
1756
}; // class MipsOperand
1757
1758
} // end anonymous namespace
1759
1760
static bool hasShortDelaySlot(MCInst &Inst) {
1761
switch (Inst.getOpcode()) {
1762
case Mips::BEQ_MM:
1763
case Mips::BNE_MM:
1764
case Mips::BLTZ_MM:
1765
case Mips::BGEZ_MM:
1766
case Mips::BLEZ_MM:
1767
case Mips::BGTZ_MM:
1768
case Mips::JRC16_MM:
1769
case Mips::JALS_MM:
1770
case Mips::JALRS_MM:
1771
case Mips::JALRS16_MM:
1772
case Mips::BGEZALS_MM:
1773
case Mips::BLTZALS_MM:
1774
return true;
1775
case Mips::J_MM:
1776
return !Inst.getOperand(0).isReg();
1777
default:
1778
return false;
1779
}
1780
}
1781
1782
static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1783
if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1784
return &SRExpr->getSymbol();
1785
}
1786
1787
if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1788
const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1789
const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1790
1791
if (LHSSym)
1792
return LHSSym;
1793
1794
if (RHSSym)
1795
return RHSSym;
1796
1797
return nullptr;
1798
}
1799
1800
if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1801
return getSingleMCSymbol(UExpr->getSubExpr());
1802
1803
return nullptr;
1804
}
1805
1806
static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1807
if (isa<MCSymbolRefExpr>(Expr))
1808
return 1;
1809
1810
if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1811
return countMCSymbolRefExpr(BExpr->getLHS()) +
1812
countMCSymbolRefExpr(BExpr->getRHS());
1813
1814
if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1815
return countMCSymbolRefExpr(UExpr->getSubExpr());
1816
1817
return 0;
1818
}
1819
1820
static bool isEvaluated(const MCExpr *Expr) {
1821
switch (Expr->getKind()) {
1822
case MCExpr::Constant:
1823
return true;
1824
case MCExpr::SymbolRef:
1825
return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1826
case MCExpr::Binary: {
1827
const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1828
if (!isEvaluated(BE->getLHS()))
1829
return false;
1830
return isEvaluated(BE->getRHS());
1831
}
1832
case MCExpr::Unary:
1833
return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1834
case MCExpr::Target:
1835
return true;
1836
}
1837
return false;
1838
}
1839
1840
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID) {
1841
unsigned NumOp = MCID.getNumOperands();
1842
if (NumOp != 3 && NumOp != 4)
1843
return false;
1844
1845
const MCOperandInfo &OpInfo = MCID.operands()[NumOp - 1];
1846
if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
1847
OpInfo.OperandType != MCOI::OPERAND_UNKNOWN &&
1848
OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9)
1849
return false;
1850
1851
MCOperand &Op = Inst.getOperand(NumOp - 1);
1852
if (Op.isImm()) {
1853
if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9)
1854
return !isInt<9>(Op.getImm());
1855
// Offset can't exceed 16bit value.
1856
return !isInt<16>(Op.getImm());
1857
}
1858
1859
if (Op.isExpr()) {
1860
const MCExpr *Expr = Op.getExpr();
1861
if (Expr->getKind() != MCExpr::SymbolRef)
1862
return !isEvaluated(Expr);
1863
1864
// Expand symbol.
1865
const MCSymbolRefExpr *SR = static_cast<const MCSymbolRefExpr *>(Expr);
1866
return SR->getKind() == MCSymbolRefExpr::VK_None;
1867
}
1868
1869
return false;
1870
}
1871
1872
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1873
MCStreamer &Out,
1874
const MCSubtargetInfo *STI) {
1875
MipsTargetStreamer &TOut = getTargetStreamer();
1876
const unsigned Opcode = Inst.getOpcode();
1877
const MCInstrDesc &MCID = MII.get(Opcode);
1878
bool ExpandedJalSym = false;
1879
1880
Inst.setLoc(IDLoc);
1881
1882
if (MCID.isBranch() || MCID.isCall()) {
1883
MCOperand Offset;
1884
1885
switch (Opcode) {
1886
default:
1887
break;
1888
case Mips::BBIT0:
1889
case Mips::BBIT032:
1890
case Mips::BBIT1:
1891
case Mips::BBIT132:
1892
assert(hasCnMips() && "instruction only valid for octeon cpus");
1893
[[fallthrough]];
1894
1895
case Mips::BEQ:
1896
case Mips::BNE:
1897
case Mips::BEQ_MM:
1898
case Mips::BNE_MM:
1899
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1900
Offset = Inst.getOperand(2);
1901
if (!Offset.isImm())
1902
break; // We'll deal with this situation later on when applying fixups.
1903
if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1904
return Error(IDLoc, "branch target out of range");
1905
if (offsetToAlignment(Offset.getImm(),
1906
(inMicroMipsMode() ? Align(2) : Align(4))))
1907
return Error(IDLoc, "branch to misaligned address");
1908
break;
1909
case Mips::BGEZ:
1910
case Mips::BGTZ:
1911
case Mips::BLEZ:
1912
case Mips::BLTZ:
1913
case Mips::BGEZAL:
1914
case Mips::BLTZAL:
1915
case Mips::BC1F:
1916
case Mips::BC1T:
1917
case Mips::BGEZ_MM:
1918
case Mips::BGTZ_MM:
1919
case Mips::BLEZ_MM:
1920
case Mips::BLTZ_MM:
1921
case Mips::BGEZAL_MM:
1922
case Mips::BLTZAL_MM:
1923
case Mips::BC1F_MM:
1924
case Mips::BC1T_MM:
1925
case Mips::BC1EQZC_MMR6:
1926
case Mips::BC1NEZC_MMR6:
1927
case Mips::BC2EQZC_MMR6:
1928
case Mips::BC2NEZC_MMR6:
1929
assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1930
Offset = Inst.getOperand(1);
1931
if (!Offset.isImm())
1932
break; // We'll deal with this situation later on when applying fixups.
1933
if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1934
return Error(IDLoc, "branch target out of range");
1935
if (offsetToAlignment(Offset.getImm(),
1936
(inMicroMipsMode() ? Align(2) : Align(4))))
1937
return Error(IDLoc, "branch to misaligned address");
1938
break;
1939
case Mips::BGEC: case Mips::BGEC_MMR6:
1940
case Mips::BLTC: case Mips::BLTC_MMR6:
1941
case Mips::BGEUC: case Mips::BGEUC_MMR6:
1942
case Mips::BLTUC: case Mips::BLTUC_MMR6:
1943
case Mips::BEQC: case Mips::BEQC_MMR6:
1944
case Mips::BNEC: case Mips::BNEC_MMR6:
1945
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1946
Offset = Inst.getOperand(2);
1947
if (!Offset.isImm())
1948
break; // We'll deal with this situation later on when applying fixups.
1949
if (!isIntN(18, Offset.getImm()))
1950
return Error(IDLoc, "branch target out of range");
1951
if (offsetToAlignment(Offset.getImm(), Align(4)))
1952
return Error(IDLoc, "branch to misaligned address");
1953
break;
1954
case Mips::BLEZC: case Mips::BLEZC_MMR6:
1955
case Mips::BGEZC: case Mips::BGEZC_MMR6:
1956
case Mips::BGTZC: case Mips::BGTZC_MMR6:
1957
case Mips::BLTZC: case Mips::BLTZC_MMR6:
1958
assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1959
Offset = Inst.getOperand(1);
1960
if (!Offset.isImm())
1961
break; // We'll deal with this situation later on when applying fixups.
1962
if (!isIntN(18, Offset.getImm()))
1963
return Error(IDLoc, "branch target out of range");
1964
if (offsetToAlignment(Offset.getImm(), Align(4)))
1965
return Error(IDLoc, "branch to misaligned address");
1966
break;
1967
case Mips::BEQZC: case Mips::BEQZC_MMR6:
1968
case Mips::BNEZC: case Mips::BNEZC_MMR6:
1969
assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1970
Offset = Inst.getOperand(1);
1971
if (!Offset.isImm())
1972
break; // We'll deal with this situation later on when applying fixups.
1973
if (!isIntN(23, Offset.getImm()))
1974
return Error(IDLoc, "branch target out of range");
1975
if (offsetToAlignment(Offset.getImm(), Align(4)))
1976
return Error(IDLoc, "branch to misaligned address");
1977
break;
1978
case Mips::BEQZ16_MM:
1979
case Mips::BEQZC16_MMR6:
1980
case Mips::BNEZ16_MM:
1981
case Mips::BNEZC16_MMR6:
1982
assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1983
Offset = Inst.getOperand(1);
1984
if (!Offset.isImm())
1985
break; // We'll deal with this situation later on when applying fixups.
1986
if (!isInt<8>(Offset.getImm()))
1987
return Error(IDLoc, "branch target out of range");
1988
if (offsetToAlignment(Offset.getImm(), Align(2)))
1989
return Error(IDLoc, "branch to misaligned address");
1990
break;
1991
}
1992
}
1993
1994
// SSNOP is deprecated on MIPS32r6/MIPS64r6
1995
// We still accept it but it is a normal nop.
1996
if (hasMips32r6() && Opcode == Mips::SSNOP) {
1997
std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1998
Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1999
"nop instruction");
2000
}
2001
2002
if (hasCnMips()) {
2003
MCOperand Opnd;
2004
int Imm;
2005
2006
switch (Opcode) {
2007
default:
2008
break;
2009
2010
case Mips::BBIT0:
2011
case Mips::BBIT032:
2012
case Mips::BBIT1:
2013
case Mips::BBIT132:
2014
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2015
// The offset is handled above
2016
Opnd = Inst.getOperand(1);
2017
if (!Opnd.isImm())
2018
return Error(IDLoc, "expected immediate operand kind");
2019
Imm = Opnd.getImm();
2020
if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2021
Opcode == Mips::BBIT1 ? 63 : 31))
2022
return Error(IDLoc, "immediate operand value out of range");
2023
if (Imm > 31) {
2024
Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2025
: Mips::BBIT132);
2026
Inst.getOperand(1).setImm(Imm - 32);
2027
}
2028
break;
2029
2030
case Mips::SEQi:
2031
case Mips::SNEi:
2032
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2033
Opnd = Inst.getOperand(2);
2034
if (!Opnd.isImm())
2035
return Error(IDLoc, "expected immediate operand kind");
2036
Imm = Opnd.getImm();
2037
if (!isInt<10>(Imm))
2038
return Error(IDLoc, "immediate operand value out of range");
2039
break;
2040
}
2041
}
2042
2043
// Warn on division by zero. We're checking here as all instructions get
2044
// processed here, not just the macros that need expansion.
2045
//
2046
// The MIPS backend models most of the divison instructions and macros as
2047
// three operand instructions. The pre-R6 divide instructions however have
2048
// two operands and explicitly define HI/LO as part of the instruction,
2049
// not in the operands.
2050
unsigned FirstOp = 1;
2051
unsigned SecondOp = 2;
2052
switch (Opcode) {
2053
default:
2054
break;
2055
case Mips::SDivIMacro:
2056
case Mips::UDivIMacro:
2057
case Mips::DSDivIMacro:
2058
case Mips::DUDivIMacro:
2059
if (Inst.getOperand(2).getImm() == 0) {
2060
if (Inst.getOperand(1).getReg() == Mips::ZERO ||
2061
Inst.getOperand(1).getReg() == Mips::ZERO_64)
2062
Warning(IDLoc, "dividing zero by zero");
2063
else
2064
Warning(IDLoc, "division by zero");
2065
}
2066
break;
2067
case Mips::DSDIV:
2068
case Mips::SDIV:
2069
case Mips::UDIV:
2070
case Mips::DUDIV:
2071
case Mips::UDIV_MM:
2072
case Mips::SDIV_MM:
2073
FirstOp = 0;
2074
SecondOp = 1;
2075
[[fallthrough]];
2076
case Mips::SDivMacro:
2077
case Mips::DSDivMacro:
2078
case Mips::UDivMacro:
2079
case Mips::DUDivMacro:
2080
case Mips::DIV:
2081
case Mips::DIVU:
2082
case Mips::DDIV:
2083
case Mips::DDIVU:
2084
case Mips::DIVU_MMR6:
2085
case Mips::DIV_MMR6:
2086
if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2087
Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2088
if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2089
Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2090
Warning(IDLoc, "dividing zero by zero");
2091
else
2092
Warning(IDLoc, "division by zero");
2093
}
2094
break;
2095
}
2096
2097
// For PIC code convert unconditional jump to unconditional branch.
2098
if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2099
MCInst BInst;
2100
BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2101
BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2102
BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2103
BInst.addOperand(Inst.getOperand(0));
2104
Inst = BInst;
2105
}
2106
2107
// This expansion is not in a function called by tryExpandInstruction()
2108
// because the pseudo-instruction doesn't have a distinct opcode.
2109
if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2110
warnIfNoMacro(IDLoc);
2111
2112
const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2113
2114
// We can do this expansion if there's only 1 symbol in the argument
2115
// expression.
2116
if (countMCSymbolRefExpr(JalExpr) > 1)
2117
return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2118
2119
// FIXME: This is checking the expression can be handled by the later stages
2120
// of the assembler. We ought to leave it to those later stages.
2121
const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2122
2123
if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.getOperand(0),
2124
!isGP64bit(), IDLoc, Out, STI))
2125
return true;
2126
2127
MCInst JalrInst;
2128
if (inMicroMipsMode())
2129
JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2130
else
2131
JalrInst.setOpcode(Mips::JALR);
2132
JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2133
JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2134
2135
if (isJalrRelocAvailable(JalExpr)) {
2136
// As an optimization hint for the linker, before the JALR we add:
2137
// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2138
// tmplabel:
2139
MCSymbol *TmpLabel = getContext().createTempSymbol();
2140
const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2141
const MCExpr *RelocJalrExpr =
2142
MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2143
getContext(), IDLoc);
2144
2145
TOut.getStreamer().emitRelocDirective(
2146
*TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2147
RelocJalrExpr, IDLoc, *STI);
2148
TOut.getStreamer().emitLabel(TmpLabel);
2149
}
2150
2151
Inst = JalrInst;
2152
ExpandedJalSym = true;
2153
}
2154
2155
if (MCID.mayLoad() || MCID.mayStore()) {
2156
// Check the offset of memory operand, if it is a symbol
2157
// reference or immediate we may have to expand instructions.
2158
if (needsExpandMemInst(Inst, MCID)) {
2159
switch (MCID.operands()[MCID.getNumOperands() - 1].OperandType) {
2160
case MipsII::OPERAND_MEM_SIMM9:
2161
expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2162
break;
2163
default:
2164
expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2165
break;
2166
}
2167
return getParser().hasPendingError();
2168
}
2169
}
2170
2171
if (inMicroMipsMode()) {
2172
if (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
2173
// Try to create 16-bit GP relative load instruction.
2174
for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2175
const MCOperandInfo &OpInfo = MCID.operands()[i];
2176
if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2177
(OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2178
MCOperand &Op = Inst.getOperand(i);
2179
if (Op.isImm()) {
2180
int MemOffset = Op.getImm();
2181
MCOperand &DstReg = Inst.getOperand(0);
2182
MCOperand &BaseReg = Inst.getOperand(1);
2183
if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2184
getContext().getRegisterInfo()->getRegClass(
2185
Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2186
(BaseReg.getReg() == Mips::GP ||
2187
BaseReg.getReg() == Mips::GP_64)) {
2188
2189
TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2190
IDLoc, STI);
2191
return false;
2192
}
2193
}
2194
}
2195
} // for
2196
} // if load
2197
2198
// TODO: Handle this with the AsmOperandClass.PredicateMethod.
2199
2200
MCOperand Opnd;
2201
int Imm;
2202
2203
switch (Opcode) {
2204
default:
2205
break;
2206
case Mips::ADDIUSP_MM:
2207
Opnd = Inst.getOperand(0);
2208
if (!Opnd.isImm())
2209
return Error(IDLoc, "expected immediate operand kind");
2210
Imm = Opnd.getImm();
2211
if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2212
Imm % 4 != 0)
2213
return Error(IDLoc, "immediate operand value out of range");
2214
break;
2215
case Mips::SLL16_MM:
2216
case Mips::SRL16_MM:
2217
Opnd = Inst.getOperand(2);
2218
if (!Opnd.isImm())
2219
return Error(IDLoc, "expected immediate operand kind");
2220
Imm = Opnd.getImm();
2221
if (Imm < 1 || Imm > 8)
2222
return Error(IDLoc, "immediate operand value out of range");
2223
break;
2224
case Mips::LI16_MM:
2225
Opnd = Inst.getOperand(1);
2226
if (!Opnd.isImm())
2227
return Error(IDLoc, "expected immediate operand kind");
2228
Imm = Opnd.getImm();
2229
if (Imm < -1 || Imm > 126)
2230
return Error(IDLoc, "immediate operand value out of range");
2231
break;
2232
case Mips::ADDIUR2_MM:
2233
Opnd = Inst.getOperand(2);
2234
if (!Opnd.isImm())
2235
return Error(IDLoc, "expected immediate operand kind");
2236
Imm = Opnd.getImm();
2237
if (!(Imm == 1 || Imm == -1 ||
2238
((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2239
return Error(IDLoc, "immediate operand value out of range");
2240
break;
2241
case Mips::ANDI16_MM:
2242
Opnd = Inst.getOperand(2);
2243
if (!Opnd.isImm())
2244
return Error(IDLoc, "expected immediate operand kind");
2245
Imm = Opnd.getImm();
2246
if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2247
Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2248
Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2249
return Error(IDLoc, "immediate operand value out of range");
2250
break;
2251
case Mips::LBU16_MM:
2252
Opnd = Inst.getOperand(2);
2253
if (!Opnd.isImm())
2254
return Error(IDLoc, "expected immediate operand kind");
2255
Imm = Opnd.getImm();
2256
if (Imm < -1 || Imm > 14)
2257
return Error(IDLoc, "immediate operand value out of range");
2258
break;
2259
case Mips::SB16_MM:
2260
case Mips::SB16_MMR6:
2261
Opnd = Inst.getOperand(2);
2262
if (!Opnd.isImm())
2263
return Error(IDLoc, "expected immediate operand kind");
2264
Imm = Opnd.getImm();
2265
if (Imm < 0 || Imm > 15)
2266
return Error(IDLoc, "immediate operand value out of range");
2267
break;
2268
case Mips::LHU16_MM:
2269
case Mips::SH16_MM:
2270
case Mips::SH16_MMR6:
2271
Opnd = Inst.getOperand(2);
2272
if (!Opnd.isImm())
2273
return Error(IDLoc, "expected immediate operand kind");
2274
Imm = Opnd.getImm();
2275
if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2276
return Error(IDLoc, "immediate operand value out of range");
2277
break;
2278
case Mips::LW16_MM:
2279
case Mips::SW16_MM:
2280
case Mips::SW16_MMR6:
2281
Opnd = Inst.getOperand(2);
2282
if (!Opnd.isImm())
2283
return Error(IDLoc, "expected immediate operand kind");
2284
Imm = Opnd.getImm();
2285
if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2286
return Error(IDLoc, "immediate operand value out of range");
2287
break;
2288
case Mips::ADDIUPC_MM:
2289
Opnd = Inst.getOperand(1);
2290
if (!Opnd.isImm())
2291
return Error(IDLoc, "expected immediate operand kind");
2292
Imm = Opnd.getImm();
2293
if ((Imm % 4 != 0) || !isInt<25>(Imm))
2294
return Error(IDLoc, "immediate operand value out of range");
2295
break;
2296
case Mips::LWP_MM:
2297
case Mips::SWP_MM:
2298
if (Inst.getOperand(0).getReg() == Mips::RA)
2299
return Error(IDLoc, "invalid operand for instruction");
2300
break;
2301
case Mips::MOVEP_MM:
2302
case Mips::MOVEP_MMR6: {
2303
unsigned R0 = Inst.getOperand(0).getReg();
2304
unsigned R1 = Inst.getOperand(1).getReg();
2305
bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2306
(R0 == Mips::A1 && R1 == Mips::A3) ||
2307
(R0 == Mips::A2 && R1 == Mips::A3) ||
2308
(R0 == Mips::A0 && R1 == Mips::S5) ||
2309
(R0 == Mips::A0 && R1 == Mips::S6) ||
2310
(R0 == Mips::A0 && R1 == Mips::A1) ||
2311
(R0 == Mips::A0 && R1 == Mips::A2) ||
2312
(R0 == Mips::A0 && R1 == Mips::A3));
2313
if (!RegPair)
2314
return Error(IDLoc, "invalid operand for instruction");
2315
break;
2316
}
2317
}
2318
}
2319
2320
bool FillDelaySlot =
2321
MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2322
2323
// Get previous instruction`s forbidden slot attribute and
2324
// whether set reorder.
2325
bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2326
2327
// Flag represents we set reorder after nop.
2328
bool SetReorderAfterNop = false;
2329
2330
// If previous instruction has forbidden slot and .set reorder
2331
// is active and current instruction is CTI.
2332
// Then emit a NOP after it.
2333
if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2334
TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2335
// When 'FillDelaySlot' is true, the existing logic will add
2336
// noreorder before instruction and reorder after it. So there
2337
// need exclude this case avoiding two '.set reorder'.
2338
// The format of the first case is:
2339
// .set noreorder
2340
// bnezc
2341
// nop
2342
// .set reorder
2343
if (AssemblerOptions.back()->isReorder() && !FillDelaySlot) {
2344
SetReorderAfterNop = true;
2345
TOut.emitDirectiveSetReorder();
2346
}
2347
}
2348
2349
// Save current instruction`s forbidden slot and whether set reorder.
2350
// This is the judgment condition for whether to add nop.
2351
// We would add a couple of '.set noreorder' and '.set reorder' to
2352
// wrap the current instruction and the next instruction.
2353
CurForbiddenSlotAttr =
2354
hasForbiddenSlot(MCID) && AssemblerOptions.back()->isReorder();
2355
2356
if (FillDelaySlot || CurForbiddenSlotAttr)
2357
TOut.emitDirectiveSetNoReorder();
2358
2359
MacroExpanderResultTy ExpandResult =
2360
tryExpandInstruction(Inst, IDLoc, Out, STI);
2361
switch (ExpandResult) {
2362
case MER_NotAMacro:
2363
Out.emitInstruction(Inst, *STI);
2364
break;
2365
case MER_Success:
2366
break;
2367
case MER_Fail:
2368
return true;
2369
}
2370
2371
// When current instruction was not CTI, recover reorder state.
2372
// The format of the second case is:
2373
// .set noreoder
2374
// bnezc
2375
// add
2376
// .set reorder
2377
if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2378
AssemblerOptions.back()->isReorder()) {
2379
TOut.emitDirectiveSetReorder();
2380
}
2381
2382
// We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2383
// If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2384
if (inMicroMipsMode()) {
2385
TOut.setUsesMicroMips();
2386
TOut.updateABIInfo(*this);
2387
}
2388
2389
// If this instruction has a delay slot and .set reorder is active,
2390
// emit a NOP after it.
2391
// The format of the third case is:
2392
// .set noreorder
2393
// bnezc
2394
// nop
2395
// .set noreorder
2396
// j
2397
// nop
2398
// .set reorder
2399
if (FillDelaySlot) {
2400
TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2401
TOut.emitDirectiveSetReorder();
2402
}
2403
2404
if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2405
ExpandedJalSym) &&
2406
isPicAndNotNxxAbi()) {
2407
if (IsCpRestoreSet) {
2408
// We need a NOP between the JALR and the LW:
2409
// If .set reorder has been used, we've already emitted a NOP.
2410
// If .set noreorder has been used, we need to emit a NOP at this point.
2411
if (!AssemblerOptions.back()->isReorder())
2412
TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2413
STI);
2414
2415
// Load the $gp from the stack.
2416
TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2417
} else
2418
Warning(IDLoc, "no .cprestore used in PIC mode");
2419
}
2420
2421
return false;
2422
}
2423
2424
void MipsAsmParser::onEndOfFile() {
2425
MipsTargetStreamer &TOut = getTargetStreamer();
2426
SMLoc IDLoc = SMLoc();
2427
// If has pending forbidden slot, fill nop and recover reorder.
2428
if (CurForbiddenSlotAttr) {
2429
TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2430
if (AssemblerOptions.back()->isReorder())
2431
TOut.emitDirectiveSetReorder();
2432
}
2433
}
2434
2435
MipsAsmParser::MacroExpanderResultTy
2436
MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2437
const MCSubtargetInfo *STI) {
2438
switch (Inst.getOpcode()) {
2439
default:
2440
return MER_NotAMacro;
2441
case Mips::LoadImm32:
2442
return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2443
case Mips::LoadImm64:
2444
return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2445
case Mips::LoadAddrImm32:
2446
case Mips::LoadAddrImm64:
2447
assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2448
assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2449
"expected immediate operand kind");
2450
2451
return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2452
Inst.getOperand(1),
2453
Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2454
Out, STI)
2455
? MER_Fail
2456
: MER_Success;
2457
case Mips::LoadAddrReg32:
2458
case Mips::LoadAddrReg64:
2459
assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2460
assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2461
assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2462
"expected immediate operand kind");
2463
2464
return expandLoadAddress(Inst.getOperand(0).getReg(),
2465
Inst.getOperand(1).getReg(), Inst.getOperand(2),
2466
Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2467
Out, STI)
2468
? MER_Fail
2469
: MER_Success;
2470
case Mips::B_MM_Pseudo:
2471
case Mips::B_MMR6_Pseudo:
2472
return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2473
: MER_Success;
2474
case Mips::SWM_MM:
2475
case Mips::LWM_MM:
2476
return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2477
: MER_Success;
2478
case Mips::JalOneReg:
2479
case Mips::JalTwoReg:
2480
return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2481
case Mips::BneImm:
2482
case Mips::BeqImm:
2483
case Mips::BEQLImmMacro:
2484
case Mips::BNELImmMacro:
2485
return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2486
case Mips::BLT:
2487
case Mips::BLE:
2488
case Mips::BGE:
2489
case Mips::BGT:
2490
case Mips::BLTU:
2491
case Mips::BLEU:
2492
case Mips::BGEU:
2493
case Mips::BGTU:
2494
case Mips::BLTL:
2495
case Mips::BLEL:
2496
case Mips::BGEL:
2497
case Mips::BGTL:
2498
case Mips::BLTUL:
2499
case Mips::BLEUL:
2500
case Mips::BGEUL:
2501
case Mips::BGTUL:
2502
case Mips::BLTImmMacro:
2503
case Mips::BLEImmMacro:
2504
case Mips::BGEImmMacro:
2505
case Mips::BGTImmMacro:
2506
case Mips::BLTUImmMacro:
2507
case Mips::BLEUImmMacro:
2508
case Mips::BGEUImmMacro:
2509
case Mips::BGTUImmMacro:
2510
case Mips::BLTLImmMacro:
2511
case Mips::BLELImmMacro:
2512
case Mips::BGELImmMacro:
2513
case Mips::BGTLImmMacro:
2514
case Mips::BLTULImmMacro:
2515
case Mips::BLEULImmMacro:
2516
case Mips::BGEULImmMacro:
2517
case Mips::BGTULImmMacro:
2518
return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2519
case Mips::SDivMacro:
2520
case Mips::SDivIMacro:
2521
case Mips::SRemMacro:
2522
case Mips::SRemIMacro:
2523
return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2524
: MER_Success;
2525
case Mips::DSDivMacro:
2526
case Mips::DSDivIMacro:
2527
case Mips::DSRemMacro:
2528
case Mips::DSRemIMacro:
2529
return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2530
: MER_Success;
2531
case Mips::UDivMacro:
2532
case Mips::UDivIMacro:
2533
case Mips::URemMacro:
2534
case Mips::URemIMacro:
2535
return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2536
: MER_Success;
2537
case Mips::DUDivMacro:
2538
case Mips::DUDivIMacro:
2539
case Mips::DURemMacro:
2540
case Mips::DURemIMacro:
2541
return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2542
: MER_Success;
2543
case Mips::PseudoTRUNC_W_S:
2544
return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2545
: MER_Success;
2546
case Mips::PseudoTRUNC_W_D32:
2547
return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2548
: MER_Success;
2549
case Mips::PseudoTRUNC_W_D:
2550
return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2551
: MER_Success;
2552
2553
case Mips::LoadImmSingleGPR:
2554
return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2555
: MER_Success;
2556
case Mips::LoadImmSingleFGR:
2557
return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2558
: MER_Success;
2559
case Mips::LoadImmDoubleGPR:
2560
return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2561
: MER_Success;
2562
case Mips::LoadImmDoubleFGR:
2563
return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2564
: MER_Success;
2565
case Mips::LoadImmDoubleFGR_32:
2566
return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2567
: MER_Success;
2568
2569
case Mips::Ulh:
2570
return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2571
case Mips::Ulhu:
2572
return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2573
case Mips::Ush:
2574
return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2575
case Mips::Ulw:
2576
case Mips::Usw:
2577
return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2578
case Mips::NORImm:
2579
case Mips::NORImm64:
2580
return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2581
case Mips::SGE:
2582
case Mips::SGEU:
2583
return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2584
case Mips::SGEImm:
2585
case Mips::SGEUImm:
2586
case Mips::SGEImm64:
2587
case Mips::SGEUImm64:
2588
return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2589
case Mips::SGTImm:
2590
case Mips::SGTUImm:
2591
case Mips::SGTImm64:
2592
case Mips::SGTUImm64:
2593
return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2594
case Mips::SLE:
2595
case Mips::SLEU:
2596
return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2597
case Mips::SLEImm:
2598
case Mips::SLEUImm:
2599
case Mips::SLEImm64:
2600
case Mips::SLEUImm64:
2601
return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602
case Mips::SLTImm64:
2603
if (isInt<16>(Inst.getOperand(2).getImm())) {
2604
Inst.setOpcode(Mips::SLTi64);
2605
return MER_NotAMacro;
2606
}
2607
return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608
case Mips::SLTUImm64:
2609
if (isInt<16>(Inst.getOperand(2).getImm())) {
2610
Inst.setOpcode(Mips::SLTiu64);
2611
return MER_NotAMacro;
2612
}
2613
return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2614
case Mips::ADDi: case Mips::ADDi_MM:
2615
case Mips::ADDiu: case Mips::ADDiu_MM:
2616
case Mips::SLTi: case Mips::SLTi_MM:
2617
case Mips::SLTiu: case Mips::SLTiu_MM:
2618
if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2619
Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2620
int64_t ImmValue = Inst.getOperand(2).getImm();
2621
if (isInt<16>(ImmValue))
2622
return MER_NotAMacro;
2623
return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2624
: MER_Success;
2625
}
2626
return MER_NotAMacro;
2627
case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2628
case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2629
case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2630
if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2631
Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2632
int64_t ImmValue = Inst.getOperand(2).getImm();
2633
if (isUInt<16>(ImmValue))
2634
return MER_NotAMacro;
2635
return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2636
: MER_Success;
2637
}
2638
return MER_NotAMacro;
2639
case Mips::ROL:
2640
case Mips::ROR:
2641
return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2642
case Mips::ROLImm:
2643
case Mips::RORImm:
2644
return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2645
case Mips::DROL:
2646
case Mips::DROR:
2647
return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2648
case Mips::DROLImm:
2649
case Mips::DRORImm:
2650
return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651
case Mips::ABSMacro:
2652
return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2653
case Mips::MULImmMacro:
2654
case Mips::DMULImmMacro:
2655
return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656
case Mips::MULOMacro:
2657
case Mips::DMULOMacro:
2658
return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659
case Mips::MULOUMacro:
2660
case Mips::DMULOUMacro:
2661
return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662
case Mips::DMULMacro:
2663
return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2664
case Mips::LDMacro:
2665
case Mips::SDMacro:
2666
return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2667
Inst.getOpcode() == Mips::LDMacro)
2668
? MER_Fail
2669
: MER_Success;
2670
case Mips::SDC1_M1:
2671
return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2672
? MER_Fail
2673
: MER_Success;
2674
case Mips::SEQMacro:
2675
return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2676
case Mips::SEQIMacro:
2677
return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2678
case Mips::SNEMacro:
2679
return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2680
case Mips::SNEIMacro:
2681
return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2682
case Mips::MFTC0: case Mips::MTTC0:
2683
case Mips::MFTGPR: case Mips::MTTGPR:
2684
case Mips::MFTLO: case Mips::MTTLO:
2685
case Mips::MFTHI: case Mips::MTTHI:
2686
case Mips::MFTACX: case Mips::MTTACX:
2687
case Mips::MFTDSP: case Mips::MTTDSP:
2688
case Mips::MFTC1: case Mips::MTTC1:
2689
case Mips::MFTHC1: case Mips::MTTHC1:
2690
case Mips::CFTC1: case Mips::CTTC1:
2691
return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2692
case Mips::SaaAddr:
2693
case Mips::SaadAddr:
2694
return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2695
}
2696
}
2697
2698
bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2699
MCStreamer &Out,
2700
const MCSubtargetInfo *STI) {
2701
MipsTargetStreamer &TOut = getTargetStreamer();
2702
2703
// Create a JALR instruction which is going to replace the pseudo-JAL.
2704
MCInst JalrInst;
2705
JalrInst.setLoc(IDLoc);
2706
const MCOperand FirstRegOp = Inst.getOperand(0);
2707
const unsigned Opcode = Inst.getOpcode();
2708
2709
if (Opcode == Mips::JalOneReg) {
2710
// jal $rs => jalr $rs
2711
if (IsCpRestoreSet && inMicroMipsMode()) {
2712
JalrInst.setOpcode(Mips::JALRS16_MM);
2713
JalrInst.addOperand(FirstRegOp);
2714
} else if (inMicroMipsMode()) {
2715
JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2716
JalrInst.addOperand(FirstRegOp);
2717
} else {
2718
JalrInst.setOpcode(Mips::JALR);
2719
JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2720
JalrInst.addOperand(FirstRegOp);
2721
}
2722
} else if (Opcode == Mips::JalTwoReg) {
2723
// jal $rd, $rs => jalr $rd, $rs
2724
if (IsCpRestoreSet && inMicroMipsMode())
2725
JalrInst.setOpcode(Mips::JALRS_MM);
2726
else
2727
JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2728
JalrInst.addOperand(FirstRegOp);
2729
const MCOperand SecondRegOp = Inst.getOperand(1);
2730
JalrInst.addOperand(SecondRegOp);
2731
}
2732
Out.emitInstruction(JalrInst, *STI);
2733
2734
// If .set reorder is active and branch instruction has a delay slot,
2735
// emit a NOP after it.
2736
const MCInstrDesc &MCID = MII.get(JalrInst.getOpcode());
2737
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2738
TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2739
STI);
2740
2741
return false;
2742
}
2743
2744
/// Can the value be represented by a unsigned N-bit value and a shift left?
2745
template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2746
return x && isUInt<N>(x >> llvm::countr_zero(x));
2747
}
2748
2749
/// Load (or add) an immediate into a register.
2750
///
2751
/// @param ImmValue The immediate to load.
2752
/// @param DstReg The register that will hold the immediate.
2753
/// @param SrcReg A register to add to the immediate or Mips::NoRegister
2754
/// for a simple initialization.
2755
/// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2756
/// @param IsAddress True if the immediate represents an address. False if it
2757
/// is an integer.
2758
/// @param IDLoc Location of the immediate in the source file.
2759
bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2760
unsigned SrcReg, bool Is32BitImm,
2761
bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2762
const MCSubtargetInfo *STI) {
2763
MipsTargetStreamer &TOut = getTargetStreamer();
2764
2765
if (!Is32BitImm && !isGP64bit()) {
2766
Error(IDLoc, "instruction requires a 64-bit architecture");
2767
return true;
2768
}
2769
2770
if (Is32BitImm) {
2771
if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2772
// Sign extend up to 64-bit so that the predicates match the hardware
2773
// behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2774
// true.
2775
ImmValue = SignExtend64<32>(ImmValue);
2776
} else {
2777
Error(IDLoc, "instruction requires a 32-bit immediate");
2778
return true;
2779
}
2780
}
2781
2782
unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2783
unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2784
2785
bool UseSrcReg = false;
2786
if (SrcReg != Mips::NoRegister)
2787
UseSrcReg = true;
2788
2789
unsigned TmpReg = DstReg;
2790
if (UseSrcReg &&
2791
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2792
// At this point we need AT to perform the expansions and we exit if it is
2793
// not available.
2794
unsigned ATReg = getATReg(IDLoc);
2795
if (!ATReg)
2796
return true;
2797
TmpReg = ATReg;
2798
}
2799
2800
if (isInt<16>(ImmValue)) {
2801
if (!UseSrcReg)
2802
SrcReg = ZeroReg;
2803
2804
// This doesn't quite follow the usual ABI expectations for N32 but matches
2805
// traditional assembler behaviour. N32 would normally use addiu for both
2806
// integers and addresses.
2807
if (IsAddress && !Is32BitImm) {
2808
TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2809
return false;
2810
}
2811
2812
TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2813
return false;
2814
}
2815
2816
if (isUInt<16>(ImmValue)) {
2817
unsigned TmpReg = DstReg;
2818
if (SrcReg == DstReg) {
2819
TmpReg = getATReg(IDLoc);
2820
if (!TmpReg)
2821
return true;
2822
}
2823
2824
TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2825
if (UseSrcReg)
2826
TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2827
return false;
2828
}
2829
2830
if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2831
warnIfNoMacro(IDLoc);
2832
2833
uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2834
uint16_t Bits15To0 = ImmValue & 0xffff;
2835
if (!Is32BitImm && !isInt<32>(ImmValue)) {
2836
// Traditional behaviour seems to special case this particular value. It's
2837
// not clear why other masks are handled differently.
2838
if (ImmValue == 0xffffffff) {
2839
TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2840
TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2841
if (UseSrcReg)
2842
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2843
return false;
2844
}
2845
2846
// Expand to an ORi instead of a LUi to avoid sign-extending into the
2847
// upper 32 bits.
2848
TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2849
TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2850
if (Bits15To0)
2851
TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2852
if (UseSrcReg)
2853
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2854
return false;
2855
}
2856
2857
TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2858
if (Bits15To0)
2859
TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2860
if (UseSrcReg)
2861
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2862
return false;
2863
}
2864
2865
if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2866
if (Is32BitImm) {
2867
Error(IDLoc, "instruction requires a 32-bit immediate");
2868
return true;
2869
}
2870
2871
// We've processed ImmValue satisfying isUInt<16> above, so ImmValue must be
2872
// at least 17-bit wide here.
2873
unsigned BitWidth = llvm::bit_width((uint64_t)ImmValue);
2874
assert(BitWidth >= 17 && "ImmValue must be at least 17-bit wide");
2875
2876
// Traditionally, these immediates are shifted as little as possible and as
2877
// such we align the most significant bit to bit 15 of our temporary.
2878
unsigned ShiftAmount = BitWidth - 16;
2879
uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2880
TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2881
TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2882
2883
if (UseSrcReg)
2884
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2885
2886
return false;
2887
}
2888
2889
warnIfNoMacro(IDLoc);
2890
2891
// The remaining case is packed with a sequence of dsll and ori with zeros
2892
// being omitted and any neighbouring dsll's being coalesced.
2893
// The highest 32-bit's are equivalent to a 32-bit immediate load.
2894
2895
// Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2896
if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2897
IDLoc, Out, STI))
2898
return false;
2899
2900
// Shift and accumulate into the register. If a 16-bit chunk is zero, then
2901
// skip it and defer the shift to the next chunk.
2902
unsigned ShiftCarriedForwards = 16;
2903
for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2904
uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2905
2906
if (ImmChunk != 0) {
2907
TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2908
TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2909
ShiftCarriedForwards = 0;
2910
}
2911
2912
ShiftCarriedForwards += 16;
2913
}
2914
ShiftCarriedForwards -= 16;
2915
2916
// Finish any remaining shifts left by trailing zeros.
2917
if (ShiftCarriedForwards)
2918
TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2919
2920
if (UseSrcReg)
2921
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2922
2923
return false;
2924
}
2925
2926
bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2927
MCStreamer &Out, const MCSubtargetInfo *STI) {
2928
const MCOperand &ImmOp = Inst.getOperand(1);
2929
assert(ImmOp.isImm() && "expected immediate operand kind");
2930
const MCOperand &DstRegOp = Inst.getOperand(0);
2931
assert(DstRegOp.isReg() && "expected register operand kind");
2932
2933
if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2934
Is32BitImm, false, IDLoc, Out, STI))
2935
return true;
2936
2937
return false;
2938
}
2939
2940
bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2941
const MCOperand &Offset,
2942
bool Is32BitAddress, SMLoc IDLoc,
2943
MCStreamer &Out,
2944
const MCSubtargetInfo *STI) {
2945
// la can't produce a usable address when addresses are 64-bit.
2946
if (Is32BitAddress && ABI.ArePtrs64bit()) {
2947
Warning(IDLoc, "la used to load 64-bit address");
2948
// Continue as if we had 'dla' instead.
2949
Is32BitAddress = false;
2950
}
2951
2952
// dla requires 64-bit addresses.
2953
if (!Is32BitAddress && !hasMips3()) {
2954
Error(IDLoc, "instruction requires a 64-bit architecture");
2955
return true;
2956
}
2957
2958
if (!Offset.isImm())
2959
return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2960
Is32BitAddress, IDLoc, Out, STI);
2961
2962
if (!ABI.ArePtrs64bit()) {
2963
// Continue as if we had 'la' whether we had 'la' or 'dla'.
2964
Is32BitAddress = true;
2965
}
2966
2967
return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2968
IDLoc, Out, STI);
2969
}
2970
2971
bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2972
unsigned DstReg, unsigned SrcReg,
2973
bool Is32BitSym, SMLoc IDLoc,
2974
MCStreamer &Out,
2975
const MCSubtargetInfo *STI) {
2976
MipsTargetStreamer &TOut = getTargetStreamer();
2977
bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2978
SrcReg != Mips::ZERO_64;
2979
warnIfNoMacro(IDLoc);
2980
2981
if (inPicMode()) {
2982
MCValue Res;
2983
if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2984
Error(IDLoc, "expected relocatable expression");
2985
return true;
2986
}
2987
if (Res.getSymB() != nullptr) {
2988
Error(IDLoc, "expected relocatable expression with only one symbol");
2989
return true;
2990
}
2991
2992
bool IsPtr64 = ABI.ArePtrs64bit();
2993
bool IsLocalSym =
2994
Res.getSymA()->getSymbol().isInSection() ||
2995
Res.getSymA()->getSymbol().isTemporary() ||
2996
(Res.getSymA()->getSymbol().isELF() &&
2997
cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2998
ELF::STB_LOCAL);
2999
// For O32, "$"-prefixed symbols are recognized as temporary while
3000
// .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
3001
// manually.
3002
if (ABI.IsO32() && Res.getSymA()->getSymbol().getName().starts_with(".L"))
3003
IsLocalSym = true;
3004
bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3005
3006
// The case where the result register is $25 is somewhat special. If the
3007
// symbol in the final relocation is external and not modified with a
3008
// constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
3009
// or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
3010
if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3011
Res.getConstant() == 0 && !IsLocalSym) {
3012
if (UseXGOT) {
3013
const MCExpr *CallHiExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16,
3014
SymExpr, getContext());
3015
const MCExpr *CallLoExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16,
3016
SymExpr, getContext());
3017
TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3018
STI);
3019
TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3020
IDLoc, STI);
3021
TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3022
MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3023
} else {
3024
const MCExpr *CallExpr =
3025
MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
3026
TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3027
MCOperand::createExpr(CallExpr), IDLoc, STI);
3028
}
3029
return false;
3030
}
3031
3032
unsigned TmpReg = DstReg;
3033
if (UseSrcReg &&
3034
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3035
SrcReg)) {
3036
// If $rs is the same as $rd, we need to use AT.
3037
// If it is not available we exit.
3038
unsigned ATReg = getATReg(IDLoc);
3039
if (!ATReg)
3040
return true;
3041
TmpReg = ATReg;
3042
}
3043
3044
// FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
3045
// loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
3046
// FIXME: Implement XGOT for microMIPS.
3047
if (UseXGOT) {
3048
// Loading address from XGOT
3049
// External GOT: lui $tmp, %got_hi(symbol)($gp)
3050
// addu $tmp, $tmp, $gp
3051
// lw $tmp, %got_lo(symbol)($tmp)
3052
// >addiu $tmp, $tmp, offset
3053
// >addiu $rd, $tmp, $rs
3054
// The addiu's marked with a '>' may be omitted if they are redundant. If
3055
// this happens then the last instruction must use $rd as the result
3056
// register.
3057
const MCExpr *CallHiExpr =
3058
MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
3059
const MCExpr *CallLoExpr = MipsMCExpr::create(
3060
MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
3061
3062
TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3063
STI);
3064
TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3065
IDLoc, STI);
3066
TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3067
MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3068
3069
if (Res.getConstant() != 0)
3070
TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3071
MCOperand::createExpr(MCConstantExpr::create(
3072
Res.getConstant(), getContext())),
3073
IDLoc, STI);
3074
3075
if (UseSrcReg)
3076
TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3077
IDLoc, STI);
3078
return false;
3079
}
3080
3081
const MipsMCExpr *GotExpr = nullptr;
3082
const MCExpr *LoExpr = nullptr;
3083
if (ABI.IsN32() || ABI.IsN64()) {
3084
// The remaining cases are:
3085
// Small offset: ld $tmp, %got_disp(symbol)($gp)
3086
// >daddiu $tmp, $tmp, offset
3087
// >daddu $rd, $tmp, $rs
3088
// The daddiu's marked with a '>' may be omitted if they are redundant. If
3089
// this happens then the last instruction must use $rd as the result
3090
// register.
3091
GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, Res.getSymA(),
3092
getContext());
3093
if (Res.getConstant() != 0) {
3094
// Symbols fully resolve with just the %got_disp(symbol) but we
3095
// must still account for any offset to the symbol for
3096
// expressions like symbol+8.
3097
LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3098
3099
// FIXME: Offsets greater than 16 bits are not yet implemented.
3100
// FIXME: The correct range is a 32-bit sign-extended number.
3101
if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3102
Error(IDLoc, "macro instruction uses large offset, which is not "
3103
"currently supported");
3104
return true;
3105
}
3106
}
3107
} else {
3108
// The remaining cases are:
3109
// External GOT: lw $tmp, %got(symbol)($gp)
3110
// >addiu $tmp, $tmp, offset
3111
// >addiu $rd, $tmp, $rs
3112
// Local GOT: lw $tmp, %got(symbol+offset)($gp)
3113
// addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3114
// >addiu $rd, $tmp, $rs
3115
// The addiu's marked with a '>' may be omitted if they are redundant. If
3116
// this happens then the last instruction must use $rd as the result
3117
// register.
3118
if (IsLocalSym) {
3119
GotExpr =
3120
MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3121
LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3122
} else {
3123
// External symbols fully resolve the symbol with just the %got(symbol)
3124
// but we must still account for any offset to the symbol for
3125
// expressions like symbol+8.
3126
GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, Res.getSymA(),
3127
getContext());
3128
if (Res.getConstant() != 0)
3129
LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3130
}
3131
}
3132
3133
TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3134
MCOperand::createExpr(GotExpr), IDLoc, STI);
3135
3136
if (LoExpr)
3137
TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3138
MCOperand::createExpr(LoExpr), IDLoc, STI);
3139
3140
if (UseSrcReg)
3141
TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3142
IDLoc, STI);
3143
3144
return false;
3145
}
3146
3147
const MipsMCExpr *HiExpr =
3148
MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3149
const MipsMCExpr *LoExpr =
3150
MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3151
3152
// This is the 64-bit symbol address expansion.
3153
if (ABI.ArePtrs64bit() && isGP64bit()) {
3154
// We need AT for the 64-bit expansion in the cases where the optional
3155
// source register is the destination register and for the superscalar
3156
// scheduled form.
3157
//
3158
// If it is not available we exit if the destination is the same as the
3159
// source register.
3160
3161
const MipsMCExpr *HighestExpr =
3162
MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3163
const MipsMCExpr *HigherExpr =
3164
MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3165
3166
bool RdRegIsRsReg =
3167
UseSrcReg &&
3168
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3169
3170
if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3171
unsigned ATReg = getATReg(IDLoc);
3172
3173
// If $rs is the same as $rd:
3174
// (d)la $rd, sym($rd) => lui $at, %highest(sym)
3175
// daddiu $at, $at, %higher(sym)
3176
// dsll $at, $at, 16
3177
// daddiu $at, $at, %hi(sym)
3178
// dsll $at, $at, 16
3179
// daddiu $at, $at, %lo(sym)
3180
// daddu $rd, $at, $rd
3181
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3182
STI);
3183
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3184
MCOperand::createExpr(HigherExpr), IDLoc, STI);
3185
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3186
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3187
IDLoc, STI);
3188
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3189
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3190
IDLoc, STI);
3191
TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3192
3193
return false;
3194
} else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3195
unsigned ATReg = getATReg(IDLoc);
3196
3197
// If the $rs is different from $rd or if $rs isn't specified and we
3198
// have $at available:
3199
// (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3200
// lui $at, %hi(sym)
3201
// daddiu $rd, $rd, %higher(sym)
3202
// daddiu $at, $at, %lo(sym)
3203
// dsll32 $rd, $rd, 0
3204
// daddu $rd, $rd, $at
3205
// (daddu $rd, $rd, $rs)
3206
//
3207
// Which is preferred for superscalar issue.
3208
TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3209
STI);
3210
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3211
TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3212
MCOperand::createExpr(HigherExpr), IDLoc, STI);
3213
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3214
IDLoc, STI);
3215
TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3216
TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3217
if (UseSrcReg)
3218
TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3219
3220
return false;
3221
} else if ((!canUseATReg() && !RdRegIsRsReg) ||
3222
(canUseATReg() && DstReg == getATReg(IDLoc))) {
3223
// Otherwise, synthesize the address in the destination register
3224
// serially:
3225
// (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3226
// daddiu $rd, $rd, %higher(sym)
3227
// dsll $rd, $rd, 16
3228
// daddiu $rd, $rd, %hi(sym)
3229
// dsll $rd, $rd, 16
3230
// daddiu $rd, $rd, %lo(sym)
3231
TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3232
STI);
3233
TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3234
MCOperand::createExpr(HigherExpr), IDLoc, STI);
3235
TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3236
TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3237
MCOperand::createExpr(HiExpr), IDLoc, STI);
3238
TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3239
TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3240
MCOperand::createExpr(LoExpr), IDLoc, STI);
3241
if (UseSrcReg)
3242
TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3243
3244
return false;
3245
} else {
3246
// We have a case where SrcReg == DstReg and we don't have $at
3247
// available. We can't expand this case, so error out appropriately.
3248
assert(SrcReg == DstReg && !canUseATReg() &&
3249
"Could have expanded dla but didn't?");
3250
reportParseError(IDLoc,
3251
"pseudo-instruction requires $at, which is not available");
3252
return true;
3253
}
3254
}
3255
3256
// And now, the 32-bit symbol address expansion:
3257
// If $rs is the same as $rd:
3258
// (d)la $rd, sym($rd) => lui $at, %hi(sym)
3259
// ori $at, $at, %lo(sym)
3260
// addu $rd, $at, $rd
3261
// Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3262
// (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3263
// ori $rd, $rd, %lo(sym)
3264
// (addu $rd, $rd, $rs)
3265
unsigned TmpReg = DstReg;
3266
if (UseSrcReg &&
3267
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3268
// If $rs is the same as $rd, we need to use AT.
3269
// If it is not available we exit.
3270
unsigned ATReg = getATReg(IDLoc);
3271
if (!ATReg)
3272
return true;
3273
TmpReg = ATReg;
3274
}
3275
3276
TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3277
TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3278
IDLoc, STI);
3279
3280
if (UseSrcReg)
3281
TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3282
else
3283
assert(
3284
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3285
3286
return false;
3287
}
3288
3289
// Each double-precision register DO-D15 overlaps with two of the single
3290
// precision registers F0-F31. As an example, all of the following hold true:
3291
// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3292
static unsigned nextReg(unsigned Reg) {
3293
if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3294
return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3295
switch (Reg) {
3296
default: llvm_unreachable("Unknown register in assembly macro expansion!");
3297
case Mips::ZERO: return Mips::AT;
3298
case Mips::AT: return Mips::V0;
3299
case Mips::V0: return Mips::V1;
3300
case Mips::V1: return Mips::A0;
3301
case Mips::A0: return Mips::A1;
3302
case Mips::A1: return Mips::A2;
3303
case Mips::A2: return Mips::A3;
3304
case Mips::A3: return Mips::T0;
3305
case Mips::T0: return Mips::T1;
3306
case Mips::T1: return Mips::T2;
3307
case Mips::T2: return Mips::T3;
3308
case Mips::T3: return Mips::T4;
3309
case Mips::T4: return Mips::T5;
3310
case Mips::T5: return Mips::T6;
3311
case Mips::T6: return Mips::T7;
3312
case Mips::T7: return Mips::S0;
3313
case Mips::S0: return Mips::S1;
3314
case Mips::S1: return Mips::S2;
3315
case Mips::S2: return Mips::S3;
3316
case Mips::S3: return Mips::S4;
3317
case Mips::S4: return Mips::S5;
3318
case Mips::S5: return Mips::S6;
3319
case Mips::S6: return Mips::S7;
3320
case Mips::S7: return Mips::T8;
3321
case Mips::T8: return Mips::T9;
3322
case Mips::T9: return Mips::K0;
3323
case Mips::K0: return Mips::K1;
3324
case Mips::K1: return Mips::GP;
3325
case Mips::GP: return Mips::SP;
3326
case Mips::SP: return Mips::FP;
3327
case Mips::FP: return Mips::RA;
3328
case Mips::RA: return Mips::ZERO;
3329
case Mips::D0: return Mips::F1;
3330
case Mips::D1: return Mips::F3;
3331
case Mips::D2: return Mips::F5;
3332
case Mips::D3: return Mips::F7;
3333
case Mips::D4: return Mips::F9;
3334
case Mips::D5: return Mips::F11;
3335
case Mips::D6: return Mips::F13;
3336
case Mips::D7: return Mips::F15;
3337
case Mips::D8: return Mips::F17;
3338
case Mips::D9: return Mips::F19;
3339
case Mips::D10: return Mips::F21;
3340
case Mips::D11: return Mips::F23;
3341
case Mips::D12: return Mips::F25;
3342
case Mips::D13: return Mips::F27;
3343
case Mips::D14: return Mips::F29;
3344
case Mips::D15: return Mips::F31;
3345
}
3346
}
3347
3348
// FIXME: This method is too general. In principle we should compute the number
3349
// of instructions required to synthesize the immediate inline compared to
3350
// synthesizing the address inline and relying on non .text sections.
3351
// For static O32 and N32 this may yield a small benefit, for static N64 this is
3352
// likely to yield a much larger benefit as we have to synthesize a 64bit
3353
// address to load a 64 bit value.
3354
bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3355
MCSymbol *Sym) {
3356
unsigned ATReg = getATReg(IDLoc);
3357
if (!ATReg)
3358
return true;
3359
3360
if(IsPicEnabled) {
3361
const MCExpr *GotSym =
3362
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3363
const MipsMCExpr *GotExpr =
3364
MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3365
3366
if(isABI_O32() || isABI_N32()) {
3367
TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3368
IDLoc, STI);
3369
} else { //isABI_N64()
3370
TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3371
IDLoc, STI);
3372
}
3373
} else { //!IsPicEnabled
3374
const MCExpr *HiSym =
3375
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3376
const MipsMCExpr *HiExpr =
3377
MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3378
3379
// FIXME: This is technically correct but gives a different result to gas,
3380
// but gas is incomplete there (it has a fixme noting it doesn't work with
3381
// 64-bit addresses).
3382
// FIXME: With -msym32 option, the address expansion for N64 should probably
3383
// use the O32 / N32 case. It's safe to use the 64 address expansion as the
3384
// symbol's value is considered sign extended.
3385
if(isABI_O32() || isABI_N32()) {
3386
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3387
} else { //isABI_N64()
3388
const MCExpr *HighestSym =
3389
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3390
const MipsMCExpr *HighestExpr =
3391
MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3392
const MCExpr *HigherSym =
3393
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3394
const MipsMCExpr *HigherExpr =
3395
MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3396
3397
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3398
STI);
3399
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3400
MCOperand::createExpr(HigherExpr), IDLoc, STI);
3401
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3402
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3403
IDLoc, STI);
3404
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3405
}
3406
}
3407
return false;
3408
}
3409
3410
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) {
3411
// If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3412
// exponent field), convert it to double (e.g. 1 to 1.0)
3413
if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3414
APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3415
ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3416
}
3417
return ImmOp64;
3418
}
3419
3420
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) {
3421
// Conversion of a double in an uint64_t to a float in a uint32_t,
3422
// retaining the bit pattern of a float.
3423
double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3424
float TmpFloat = static_cast<float>(DoubleImm);
3425
return llvm::bit_cast<uint32_t>(TmpFloat);
3426
}
3427
3428
bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3429
MCStreamer &Out,
3430
const MCSubtargetInfo *STI) {
3431
assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3432
assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3433
"Invalid instruction operand.");
3434
3435
unsigned FirstReg = Inst.getOperand(0).getReg();
3436
uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3437
3438
uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3439
3440
return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3441
Out, STI);
3442
}
3443
3444
bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3445
MCStreamer &Out,
3446
const MCSubtargetInfo *STI) {
3447
MipsTargetStreamer &TOut = getTargetStreamer();
3448
assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3449
assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3450
"Invalid instruction operand.");
3451
3452
unsigned FirstReg = Inst.getOperand(0).getReg();
3453
uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3454
3455
ImmOp64 = convertIntToDoubleImm(ImmOp64);
3456
3457
uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3458
3459
unsigned TmpReg = Mips::ZERO;
3460
if (ImmOp32 != 0) {
3461
TmpReg = getATReg(IDLoc);
3462
if (!TmpReg)
3463
return true;
3464
}
3465
3466
if (Lo_32(ImmOp64) == 0) {
3467
if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3468
true, false, IDLoc, Out, STI))
3469
return true;
3470
TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3471
return false;
3472
}
3473
3474
MCSection *CS = getStreamer().getCurrentSectionOnly();
3475
// FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3476
// where appropriate.
3477
MCSection *ReadOnlySection =
3478
getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3479
3480
MCSymbol *Sym = getContext().createTempSymbol();
3481
const MCExpr *LoSym =
3482
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3483
const MipsMCExpr *LoExpr =
3484
MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3485
3486
getStreamer().switchSection(ReadOnlySection);
3487
getStreamer().emitLabel(Sym, IDLoc);
3488
getStreamer().emitInt32(ImmOp32);
3489
getStreamer().switchSection(CS);
3490
3491
if (emitPartialAddress(TOut, IDLoc, Sym))
3492
return true;
3493
TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3494
IDLoc, STI);
3495
return false;
3496
}
3497
3498
bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3499
MCStreamer &Out,
3500
const MCSubtargetInfo *STI) {
3501
MipsTargetStreamer &TOut = getTargetStreamer();
3502
assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3503
assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3504
"Invalid instruction operand.");
3505
3506
unsigned FirstReg = Inst.getOperand(0).getReg();
3507
uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3508
3509
ImmOp64 = convertIntToDoubleImm(ImmOp64);
3510
3511
if (Lo_32(ImmOp64) == 0) {
3512
if (isGP64bit()) {
3513
if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3514
IDLoc, Out, STI))
3515
return true;
3516
} else {
3517
if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3518
IDLoc, Out, STI))
3519
return true;
3520
3521
if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3522
IDLoc, Out, STI))
3523
return true;
3524
}
3525
return false;
3526
}
3527
3528
MCSection *CS = getStreamer().getCurrentSectionOnly();
3529
MCSection *ReadOnlySection =
3530
getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3531
3532
MCSymbol *Sym = getContext().createTempSymbol();
3533
const MCExpr *LoSym =
3534
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3535
const MipsMCExpr *LoExpr =
3536
MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3537
3538
getStreamer().switchSection(ReadOnlySection);
3539
getStreamer().emitLabel(Sym, IDLoc);
3540
getStreamer().emitValueToAlignment(Align(8));
3541
getStreamer().emitIntValue(ImmOp64, 8);
3542
getStreamer().switchSection(CS);
3543
3544
unsigned TmpReg = getATReg(IDLoc);
3545
if (!TmpReg)
3546
return true;
3547
3548
if (emitPartialAddress(TOut, IDLoc, Sym))
3549
return true;
3550
3551
TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3552
MCOperand::createExpr(LoExpr), IDLoc, STI);
3553
3554
if (isGP64bit())
3555
TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3556
else {
3557
TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3558
TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3559
}
3560
return false;
3561
}
3562
3563
bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3564
SMLoc IDLoc, MCStreamer &Out,
3565
const MCSubtargetInfo *STI) {
3566
MipsTargetStreamer &TOut = getTargetStreamer();
3567
assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3568
assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3569
"Invalid instruction operand.");
3570
3571
unsigned FirstReg = Inst.getOperand(0).getReg();
3572
uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3573
3574
ImmOp64 = convertIntToDoubleImm(ImmOp64);
3575
3576
unsigned TmpReg = Mips::ZERO;
3577
if (ImmOp64 != 0) {
3578
TmpReg = getATReg(IDLoc);
3579
if (!TmpReg)
3580
return true;
3581
}
3582
3583
if ((Lo_32(ImmOp64) == 0) &&
3584
!((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3585
if (isGP64bit()) {
3586
if (TmpReg != Mips::ZERO &&
3587
loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3588
Out, STI))
3589
return true;
3590
TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3591
return false;
3592
}
3593
3594
if (TmpReg != Mips::ZERO &&
3595
loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3596
IDLoc, Out, STI))
3597
return true;
3598
3599
if (hasMips32r2()) {
3600
TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3601
TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3602
} else {
3603
TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3604
TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3605
}
3606
return false;
3607
}
3608
3609
MCSection *CS = getStreamer().getCurrentSectionOnly();
3610
// FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3611
// where appropriate.
3612
MCSection *ReadOnlySection =
3613
getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3614
3615
MCSymbol *Sym = getContext().createTempSymbol();
3616
const MCExpr *LoSym =
3617
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3618
const MipsMCExpr *LoExpr =
3619
MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3620
3621
getStreamer().switchSection(ReadOnlySection);
3622
getStreamer().emitLabel(Sym, IDLoc);
3623
getStreamer().emitValueToAlignment(Align(8));
3624
getStreamer().emitIntValue(ImmOp64, 8);
3625
getStreamer().switchSection(CS);
3626
3627
if (emitPartialAddress(TOut, IDLoc, Sym))
3628
return true;
3629
3630
TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3631
MCOperand::createExpr(LoExpr), IDLoc, STI);
3632
3633
return false;
3634
}
3635
3636
bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3637
MCStreamer &Out,
3638
const MCSubtargetInfo *STI) {
3639
MipsTargetStreamer &TOut = getTargetStreamer();
3640
3641
assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 &&
3642
"unexpected number of operands");
3643
3644
MCOperand Offset = Inst.getOperand(0);
3645
if (Offset.isExpr()) {
3646
Inst.clear();
3647
Inst.setOpcode(Mips::BEQ_MM);
3648
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3649
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3650
Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3651
} else {
3652
assert(Offset.isImm() && "expected immediate operand kind");
3653
if (isInt<11>(Offset.getImm())) {
3654
// If offset fits into 11 bits then this instruction becomes microMIPS
3655
// 16-bit unconditional branch instruction.
3656
if (inMicroMipsMode())
3657
Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3658
} else {
3659
if (!isInt<17>(Offset.getImm()))
3660
return Error(IDLoc, "branch target out of range");
3661
if (offsetToAlignment(Offset.getImm(), Align(2)))
3662
return Error(IDLoc, "branch to misaligned address");
3663
Inst.clear();
3664
Inst.setOpcode(Mips::BEQ_MM);
3665
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3666
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3667
Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3668
}
3669
}
3670
Out.emitInstruction(Inst, *STI);
3671
3672
// If .set reorder is active and branch instruction has a delay slot,
3673
// emit a NOP after it.
3674
const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3675
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3676
TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3677
3678
return false;
3679
}
3680
3681
bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3682
const MCSubtargetInfo *STI) {
3683
MipsTargetStreamer &TOut = getTargetStreamer();
3684
const MCOperand &DstRegOp = Inst.getOperand(0);
3685
assert(DstRegOp.isReg() && "expected register operand kind");
3686
3687
const MCOperand &ImmOp = Inst.getOperand(1);
3688
assert(ImmOp.isImm() && "expected immediate operand kind");
3689
3690
const MCOperand &MemOffsetOp = Inst.getOperand(2);
3691
assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3692
"expected immediate or expression operand");
3693
3694
bool IsLikely = false;
3695
3696
unsigned OpCode = 0;
3697
switch(Inst.getOpcode()) {
3698
case Mips::BneImm:
3699
OpCode = Mips::BNE;
3700
break;
3701
case Mips::BeqImm:
3702
OpCode = Mips::BEQ;
3703
break;
3704
case Mips::BEQLImmMacro:
3705
OpCode = Mips::BEQL;
3706
IsLikely = true;
3707
break;
3708
case Mips::BNELImmMacro:
3709
OpCode = Mips::BNEL;
3710
IsLikely = true;
3711
break;
3712
default:
3713
llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3714
break;
3715
}
3716
3717
int64_t ImmValue = ImmOp.getImm();
3718
if (ImmValue == 0) {
3719
if (IsLikely) {
3720
TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3721
MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3722
TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3723
} else
3724
TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3725
STI);
3726
} else {
3727
warnIfNoMacro(IDLoc);
3728
3729
unsigned ATReg = getATReg(IDLoc);
3730
if (!ATReg)
3731
return true;
3732
3733
if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3734
IDLoc, Out, STI))
3735
return true;
3736
3737
if (IsLikely) {
3738
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3739
MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3740
TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3741
} else
3742
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3743
}
3744
return false;
3745
}
3746
3747
void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3748
const MCSubtargetInfo *STI, bool IsLoad) {
3749
unsigned NumOp = Inst.getNumOperands();
3750
assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3751
unsigned StartOp = NumOp == 3 ? 0 : 1;
3752
3753
const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3754
assert(DstRegOp.isReg() && "expected register operand kind");
3755
const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3756
assert(BaseRegOp.isReg() && "expected register operand kind");
3757
const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3758
3759
MipsTargetStreamer &TOut = getTargetStreamer();
3760
unsigned OpCode = Inst.getOpcode();
3761
unsigned DstReg = DstRegOp.getReg();
3762
unsigned BaseReg = BaseRegOp.getReg();
3763
unsigned TmpReg = DstReg;
3764
3765
const MCInstrDesc &Desc = MII.get(OpCode);
3766
int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3767
unsigned DstRegClassID =
3768
getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3769
bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3770
(DstRegClassID == Mips::GPR64RegClassID);
3771
3772
if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3773
// At this point we need AT to perform the expansions
3774
// and we exit if it is not available.
3775
TmpReg = getATReg(IDLoc);
3776
if (!TmpReg)
3777
return;
3778
}
3779
3780
auto emitInstWithOffset = [&](const MCOperand &Off) {
3781
if (NumOp == 3)
3782
TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3783
else
3784
TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3785
};
3786
3787
if (OffsetOp.isImm()) {
3788
int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3789
int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3790
3791
// If msb of LoOffset is 1(negative number) we must increment
3792
// HiOffset to account for the sign-extension of the low part.
3793
if (LoOffset & 0x8000)
3794
HiOffset += 0x10000;
3795
3796
bool IsLargeOffset = HiOffset != 0;
3797
3798
if (IsLargeOffset) {
3799
bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3800
if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3801
IDLoc, Out, STI))
3802
return;
3803
}
3804
3805
if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3806
TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3807
TmpReg, BaseReg, IDLoc, STI);
3808
emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3809
return;
3810
}
3811
3812
if (OffsetOp.isExpr()) {
3813
if (inPicMode()) {
3814
// FIXME:
3815
// c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3816
// do not exceed 16-bit.
3817
// d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3818
// of R_MIPS_GOT_DISP in appropriate cases to reduce number
3819
// of GOT entries.
3820
MCValue Res;
3821
if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3822
Error(IDLoc, "expected relocatable expression");
3823
return;
3824
}
3825
if (Res.getSymB() != nullptr) {
3826
Error(IDLoc, "expected relocatable expression with only one symbol");
3827
return;
3828
}
3829
3830
loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3831
!ABI.ArePtrs64bit(), IDLoc, Out, STI);
3832
emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3833
} else {
3834
// FIXME: Implement 64-bit case.
3835
// 1) lw $8, sym => lui $8, %hi(sym)
3836
// lw $8, %lo(sym)($8)
3837
// 2) sw $8, sym => lui $at, %hi(sym)
3838
// sw $8, %lo(sym)($at)
3839
const MCExpr *OffExpr = OffsetOp.getExpr();
3840
MCOperand LoOperand = MCOperand::createExpr(
3841
MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
3842
MCOperand HiOperand = MCOperand::createExpr(
3843
MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
3844
3845
if (ABI.IsN64()) {
3846
MCOperand HighestOperand = MCOperand::createExpr(
3847
MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
3848
MCOperand HigherOperand = MCOperand::createExpr(
3849
MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
3850
3851
TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3852
TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3853
TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3854
TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3855
TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3856
if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3857
TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3858
emitInstWithOffset(LoOperand);
3859
} else {
3860
// Generate the base address in TmpReg.
3861
TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3862
if (BaseReg != Mips::ZERO)
3863
TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3864
// Emit the load or store with the adjusted base and offset.
3865
emitInstWithOffset(LoOperand);
3866
}
3867
}
3868
return;
3869
}
3870
3871
llvm_unreachable("unexpected operand type");
3872
}
3873
3874
void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3875
const MCSubtargetInfo *STI, bool IsLoad) {
3876
unsigned NumOp = Inst.getNumOperands();
3877
assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3878
unsigned StartOp = NumOp == 3 ? 0 : 1;
3879
3880
const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3881
assert(DstRegOp.isReg() && "expected register operand kind");
3882
const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3883
assert(BaseRegOp.isReg() && "expected register operand kind");
3884
const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3885
3886
MipsTargetStreamer &TOut = getTargetStreamer();
3887
unsigned OpCode = Inst.getOpcode();
3888
unsigned DstReg = DstRegOp.getReg();
3889
unsigned BaseReg = BaseRegOp.getReg();
3890
unsigned TmpReg = DstReg;
3891
3892
const MCInstrDesc &Desc = MII.get(OpCode);
3893
int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3894
unsigned DstRegClassID =
3895
getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3896
bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3897
(DstRegClassID == Mips::GPR64RegClassID);
3898
3899
if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3900
// At this point we need AT to perform the expansions
3901
// and we exit if it is not available.
3902
TmpReg = getATReg(IDLoc);
3903
if (!TmpReg)
3904
return;
3905
}
3906
3907
auto emitInst = [&]() {
3908
if (NumOp == 3)
3909
TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3910
else
3911
TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3912
IDLoc, STI);
3913
};
3914
3915
if (OffsetOp.isImm()) {
3916
loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3917
IDLoc, Out, STI);
3918
emitInst();
3919
return;
3920
}
3921
3922
if (OffsetOp.isExpr()) {
3923
loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3924
!ABI.ArePtrs64bit(), IDLoc, Out, STI);
3925
emitInst();
3926
return;
3927
}
3928
3929
llvm_unreachable("unexpected operand type");
3930
}
3931
3932
bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3933
MCStreamer &Out,
3934
const MCSubtargetInfo *STI) {
3935
unsigned OpNum = Inst.getNumOperands();
3936
unsigned Opcode = Inst.getOpcode();
3937
unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3938
3939
assert(Inst.getOperand(OpNum - 1).isImm() &&
3940
Inst.getOperand(OpNum - 2).isReg() &&
3941
Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3942
3943
if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3944
Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3945
(Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3946
Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3947
(Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3948
Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3949
// It can be implemented as SWM16 or LWM16 instruction.
3950
if (inMicroMipsMode() && hasMips32r6())
3951
NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3952
else
3953
NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3954
}
3955
3956
Inst.setOpcode(NewOpcode);
3957
Out.emitInstruction(Inst, *STI);
3958
return false;
3959
}
3960
3961
bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3962
MCStreamer &Out,
3963
const MCSubtargetInfo *STI) {
3964
MipsTargetStreamer &TOut = getTargetStreamer();
3965
bool EmittedNoMacroWarning = false;
3966
unsigned PseudoOpcode = Inst.getOpcode();
3967
unsigned SrcReg = Inst.getOperand(0).getReg();
3968
const MCOperand &TrgOp = Inst.getOperand(1);
3969
const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3970
3971
unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3972
bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3973
3974
unsigned TrgReg;
3975
if (TrgOp.isReg())
3976
TrgReg = TrgOp.getReg();
3977
else if (TrgOp.isImm()) {
3978
warnIfNoMacro(IDLoc);
3979
EmittedNoMacroWarning = true;
3980
3981
TrgReg = getATReg(IDLoc);
3982
if (!TrgReg)
3983
return true;
3984
3985
switch(PseudoOpcode) {
3986
default:
3987
llvm_unreachable("unknown opcode for branch pseudo-instruction");
3988
case Mips::BLTImmMacro:
3989
PseudoOpcode = Mips::BLT;
3990
break;
3991
case Mips::BLEImmMacro:
3992
PseudoOpcode = Mips::BLE;
3993
break;
3994
case Mips::BGEImmMacro:
3995
PseudoOpcode = Mips::BGE;
3996
break;
3997
case Mips::BGTImmMacro:
3998
PseudoOpcode = Mips::BGT;
3999
break;
4000
case Mips::BLTUImmMacro:
4001
PseudoOpcode = Mips::BLTU;
4002
break;
4003
case Mips::BLEUImmMacro:
4004
PseudoOpcode = Mips::BLEU;
4005
break;
4006
case Mips::BGEUImmMacro:
4007
PseudoOpcode = Mips::BGEU;
4008
break;
4009
case Mips::BGTUImmMacro:
4010
PseudoOpcode = Mips::BGTU;
4011
break;
4012
case Mips::BLTLImmMacro:
4013
PseudoOpcode = Mips::BLTL;
4014
break;
4015
case Mips::BLELImmMacro:
4016
PseudoOpcode = Mips::BLEL;
4017
break;
4018
case Mips::BGELImmMacro:
4019
PseudoOpcode = Mips::BGEL;
4020
break;
4021
case Mips::BGTLImmMacro:
4022
PseudoOpcode = Mips::BGTL;
4023
break;
4024
case Mips::BLTULImmMacro:
4025
PseudoOpcode = Mips::BLTUL;
4026
break;
4027
case Mips::BLEULImmMacro:
4028
PseudoOpcode = Mips::BLEUL;
4029
break;
4030
case Mips::BGEULImmMacro:
4031
PseudoOpcode = Mips::BGEUL;
4032
break;
4033
case Mips::BGTULImmMacro:
4034
PseudoOpcode = Mips::BGTUL;
4035
break;
4036
}
4037
4038
if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4039
false, IDLoc, Out, STI))
4040
return true;
4041
}
4042
4043
switch (PseudoOpcode) {
4044
case Mips::BLT:
4045
case Mips::BLTU:
4046
case Mips::BLTL:
4047
case Mips::BLTUL:
4048
AcceptsEquality = false;
4049
ReverseOrderSLT = false;
4050
IsUnsigned =
4051
((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4052
IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4053
ZeroSrcOpcode = Mips::BGTZ;
4054
ZeroTrgOpcode = Mips::BLTZ;
4055
break;
4056
case Mips::BLE:
4057
case Mips::BLEU:
4058
case Mips::BLEL:
4059
case Mips::BLEUL:
4060
AcceptsEquality = true;
4061
ReverseOrderSLT = true;
4062
IsUnsigned =
4063
((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4064
IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4065
ZeroSrcOpcode = Mips::BGEZ;
4066
ZeroTrgOpcode = Mips::BLEZ;
4067
break;
4068
case Mips::BGE:
4069
case Mips::BGEU:
4070
case Mips::BGEL:
4071
case Mips::BGEUL:
4072
AcceptsEquality = true;
4073
ReverseOrderSLT = false;
4074
IsUnsigned =
4075
((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4076
IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4077
ZeroSrcOpcode = Mips::BLEZ;
4078
ZeroTrgOpcode = Mips::BGEZ;
4079
break;
4080
case Mips::BGT:
4081
case Mips::BGTU:
4082
case Mips::BGTL:
4083
case Mips::BGTUL:
4084
AcceptsEquality = false;
4085
ReverseOrderSLT = true;
4086
IsUnsigned =
4087
((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4088
IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4089
ZeroSrcOpcode = Mips::BLTZ;
4090
ZeroTrgOpcode = Mips::BGTZ;
4091
break;
4092
default:
4093
llvm_unreachable("unknown opcode for branch pseudo-instruction");
4094
}
4095
4096
bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4097
bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4098
if (IsSrcRegZero && IsTrgRegZero) {
4099
// FIXME: All of these Opcode-specific if's are needed for compatibility
4100
// with GAS' behaviour. However, they may not generate the most efficient
4101
// code in some circumstances.
4102
if (PseudoOpcode == Mips::BLT) {
4103
TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4104
IDLoc, STI);
4105
return false;
4106
}
4107
if (PseudoOpcode == Mips::BLE) {
4108
TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4109
IDLoc, STI);
4110
Warning(IDLoc, "branch is always taken");
4111
return false;
4112
}
4113
if (PseudoOpcode == Mips::BGE) {
4114
TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4115
IDLoc, STI);
4116
Warning(IDLoc, "branch is always taken");
4117
return false;
4118
}
4119
if (PseudoOpcode == Mips::BGT) {
4120
TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4121
IDLoc, STI);
4122
return false;
4123
}
4124
if (PseudoOpcode == Mips::BGTU) {
4125
TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4126
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4127
return false;
4128
}
4129
if (AcceptsEquality) {
4130
// If both registers are $0 and the pseudo-branch accepts equality, it
4131
// will always be taken, so we emit an unconditional branch.
4132
TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4133
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4134
Warning(IDLoc, "branch is always taken");
4135
return false;
4136
}
4137
// If both registers are $0 and the pseudo-branch does not accept
4138
// equality, it will never be taken, so we don't have to emit anything.
4139
return false;
4140
}
4141
if (IsSrcRegZero || IsTrgRegZero) {
4142
if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4143
(IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4144
// If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4145
// if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4146
// the pseudo-branch will never be taken, so we don't emit anything.
4147
// This only applies to unsigned pseudo-branches.
4148
return false;
4149
}
4150
if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4151
(IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4152
// If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4153
// if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4154
// the pseudo-branch will always be taken, so we emit an unconditional
4155
// branch.
4156
// This only applies to unsigned pseudo-branches.
4157
TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4158
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4159
Warning(IDLoc, "branch is always taken");
4160
return false;
4161
}
4162
if (IsUnsigned) {
4163
// If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4164
// if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4165
// the pseudo-branch will be taken only when the non-zero register is
4166
// different from 0, so we emit a BNEZ.
4167
//
4168
// If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4169
// if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4170
// the pseudo-branch will be taken only when the non-zero register is
4171
// equal to 0, so we emit a BEQZ.
4172
//
4173
// Because only BLEU and BGEU branch on equality, we can use the
4174
// AcceptsEquality variable to decide when to emit the BEQZ.
4175
TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4176
IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4177
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4178
return false;
4179
}
4180
// If we have a signed pseudo-branch and one of the registers is $0,
4181
// we can use an appropriate compare-to-zero branch. We select which one
4182
// to use in the switch statement above.
4183
TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4184
IsSrcRegZero ? TrgReg : SrcReg,
4185
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4186
return false;
4187
}
4188
4189
// If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4190
// expansions. If it is not available, we return.
4191
unsigned ATRegNum = getATReg(IDLoc);
4192
if (!ATRegNum)
4193
return true;
4194
4195
if (!EmittedNoMacroWarning)
4196
warnIfNoMacro(IDLoc);
4197
4198
// SLT fits well with 2 of our 4 pseudo-branches:
4199
// BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4200
// BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4201
// If the result of the SLT is 1, we branch, and if it's 0, we don't.
4202
// This is accomplished by using a BNEZ with the result of the SLT.
4203
//
4204
// The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4205
// and BLE with BGT), so we change the BNEZ into a BEQZ.
4206
// Because only BGE and BLE branch on equality, we can use the
4207
// AcceptsEquality variable to decide when to emit the BEQZ.
4208
// Note that the order of the SLT arguments doesn't change between
4209
// opposites.
4210
//
4211
// The same applies to the unsigned variants, except that SLTu is used
4212
// instead of SLT.
4213
TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4214
ReverseOrderSLT ? TrgReg : SrcReg,
4215
ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4216
4217
TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4218
: (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4219
ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4220
STI);
4221
return false;
4222
}
4223
4224
// Expand a integer division macro.
4225
//
4226
// Notably we don't have to emit a warning when encountering $rt as the $zero
4227
// register, or 0 as an immediate. processInstruction() has already done that.
4228
//
4229
// The destination register can only be $zero when expanding (S)DivIMacro or
4230
// D(S)DivMacro.
4231
4232
bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4233
const MCSubtargetInfo *STI,
4234
const bool IsMips64, const bool Signed) {
4235
MipsTargetStreamer &TOut = getTargetStreamer();
4236
4237
warnIfNoMacro(IDLoc);
4238
4239
const MCOperand &RdRegOp = Inst.getOperand(0);
4240
assert(RdRegOp.isReg() && "expected register operand kind");
4241
unsigned RdReg = RdRegOp.getReg();
4242
4243
const MCOperand &RsRegOp = Inst.getOperand(1);
4244
assert(RsRegOp.isReg() && "expected register operand kind");
4245
unsigned RsReg = RsRegOp.getReg();
4246
4247
unsigned RtReg;
4248
int64_t ImmValue;
4249
4250
const MCOperand &RtOp = Inst.getOperand(2);
4251
assert((RtOp.isReg() || RtOp.isImm()) &&
4252
"expected register or immediate operand kind");
4253
if (RtOp.isReg())
4254
RtReg = RtOp.getReg();
4255
else
4256
ImmValue = RtOp.getImm();
4257
4258
unsigned DivOp;
4259
unsigned ZeroReg;
4260
unsigned SubOp;
4261
4262
if (IsMips64) {
4263
DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4264
ZeroReg = Mips::ZERO_64;
4265
SubOp = Mips::DSUB;
4266
} else {
4267
DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4268
ZeroReg = Mips::ZERO;
4269
SubOp = Mips::SUB;
4270
}
4271
4272
bool UseTraps = useTraps();
4273
4274
unsigned Opcode = Inst.getOpcode();
4275
bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4276
Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4277
Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4278
Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4279
4280
bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4281
Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4282
Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4283
Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4284
4285
if (RtOp.isImm()) {
4286
unsigned ATReg = getATReg(IDLoc);
4287
if (!ATReg)
4288
return true;
4289
4290
if (ImmValue == 0) {
4291
if (UseTraps)
4292
TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4293
else
4294
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4295
return false;
4296
}
4297
4298
if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4299
TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4300
return false;
4301
} else if (isDiv && ImmValue == 1) {
4302
TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4303
return false;
4304
} else if (isDiv && Signed && ImmValue == -1) {
4305
TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4306
return false;
4307
} else {
4308
if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4309
false, Inst.getLoc(), Out, STI))
4310
return true;
4311
TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4312
TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4313
return false;
4314
}
4315
return true;
4316
}
4317
4318
// If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4319
// break, insert the trap/break and exit. This gives a different result to
4320
// GAS. GAS has an inconsistency/missed optimization in that not all cases
4321
// are handled equivalently. As the observed behaviour is the same, we're ok.
4322
if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4323
if (UseTraps) {
4324
TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4325
return false;
4326
}
4327
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4328
return false;
4329
}
4330
4331
// (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4332
// not expand to macro sequence.
4333
if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4334
TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4335
return false;
4336
}
4337
4338
// Temporary label for first branch traget
4339
MCContext &Context = TOut.getStreamer().getContext();
4340
MCSymbol *BrTarget;
4341
MCOperand LabelOp;
4342
4343
if (UseTraps) {
4344
TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4345
} else {
4346
// Branch to the li instruction.
4347
BrTarget = Context.createTempSymbol();
4348
LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4349
TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4350
}
4351
4352
TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4353
4354
if (!UseTraps)
4355
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4356
4357
if (!Signed) {
4358
if (!UseTraps)
4359
TOut.getStreamer().emitLabel(BrTarget);
4360
4361
TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4362
return false;
4363
}
4364
4365
unsigned ATReg = getATReg(IDLoc);
4366
if (!ATReg)
4367
return true;
4368
4369
if (!UseTraps)
4370
TOut.getStreamer().emitLabel(BrTarget);
4371
4372
TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4373
4374
// Temporary label for the second branch target.
4375
MCSymbol *BrTargetEnd = Context.createTempSymbol();
4376
MCOperand LabelOpEnd =
4377
MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4378
4379
// Branch to the mflo instruction.
4380
TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4381
4382
if (IsMips64) {
4383
TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4384
TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4385
} else {
4386
TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4387
}
4388
4389
if (UseTraps)
4390
TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4391
else {
4392
// Branch to the mflo instruction.
4393
TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4394
TOut.emitNop(IDLoc, STI);
4395
TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4396
}
4397
4398
TOut.getStreamer().emitLabel(BrTargetEnd);
4399
TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4400
return false;
4401
}
4402
4403
bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4404
SMLoc IDLoc, MCStreamer &Out,
4405
const MCSubtargetInfo *STI) {
4406
MipsTargetStreamer &TOut = getTargetStreamer();
4407
4408
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4409
assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4410
Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4411
4412
unsigned FirstReg = Inst.getOperand(0).getReg();
4413
unsigned SecondReg = Inst.getOperand(1).getReg();
4414
unsigned ThirdReg = Inst.getOperand(2).getReg();
4415
4416
if (hasMips1() && !hasMips2()) {
4417
unsigned ATReg = getATReg(IDLoc);
4418
if (!ATReg)
4419
return true;
4420
TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4421
TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4422
TOut.emitNop(IDLoc, STI);
4423
TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4424
TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4425
TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4426
TOut.emitNop(IDLoc, STI);
4427
TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4428
: Mips::CVT_W_S,
4429
FirstReg, SecondReg, IDLoc, STI);
4430
TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4431
TOut.emitNop(IDLoc, STI);
4432
return false;
4433
}
4434
4435
TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4436
: Mips::TRUNC_W_S,
4437
FirstReg, SecondReg, IDLoc, STI);
4438
4439
return false;
4440
}
4441
4442
bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4443
MCStreamer &Out, const MCSubtargetInfo *STI) {
4444
if (hasMips32r6() || hasMips64r6()) {
4445
return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4446
}
4447
4448
const MCOperand &DstRegOp = Inst.getOperand(0);
4449
assert(DstRegOp.isReg() && "expected register operand kind");
4450
const MCOperand &SrcRegOp = Inst.getOperand(1);
4451
assert(SrcRegOp.isReg() && "expected register operand kind");
4452
const MCOperand &OffsetImmOp = Inst.getOperand(2);
4453
assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4454
4455
MipsTargetStreamer &TOut = getTargetStreamer();
4456
unsigned DstReg = DstRegOp.getReg();
4457
unsigned SrcReg = SrcRegOp.getReg();
4458
int64_t OffsetValue = OffsetImmOp.getImm();
4459
4460
// NOTE: We always need AT for ULHU, as it is always used as the source
4461
// register for one of the LBu's.
4462
warnIfNoMacro(IDLoc);
4463
unsigned ATReg = getATReg(IDLoc);
4464
if (!ATReg)
4465
return true;
4466
4467
bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4468
if (IsLargeOffset) {
4469
if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4470
IDLoc, Out, STI))
4471
return true;
4472
}
4473
4474
int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4475
int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4476
if (isLittle())
4477
std::swap(FirstOffset, SecondOffset);
4478
4479
unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4480
unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4481
4482
unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4483
unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4484
4485
TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4486
FirstOffset, IDLoc, STI);
4487
TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4488
TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4489
TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4490
4491
return false;
4492
}
4493
4494
bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4495
const MCSubtargetInfo *STI) {
4496
if (hasMips32r6() || hasMips64r6()) {
4497
return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4498
}
4499
4500
const MCOperand &DstRegOp = Inst.getOperand(0);
4501
assert(DstRegOp.isReg() && "expected register operand kind");
4502
const MCOperand &SrcRegOp = Inst.getOperand(1);
4503
assert(SrcRegOp.isReg() && "expected register operand kind");
4504
const MCOperand &OffsetImmOp = Inst.getOperand(2);
4505
assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4506
4507
MipsTargetStreamer &TOut = getTargetStreamer();
4508
unsigned DstReg = DstRegOp.getReg();
4509
unsigned SrcReg = SrcRegOp.getReg();
4510
int64_t OffsetValue = OffsetImmOp.getImm();
4511
4512
warnIfNoMacro(IDLoc);
4513
unsigned ATReg = getATReg(IDLoc);
4514
if (!ATReg)
4515
return true;
4516
4517
bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4518
if (IsLargeOffset) {
4519
if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4520
IDLoc, Out, STI))
4521
return true;
4522
}
4523
4524
int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4525
int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4526
if (isLittle())
4527
std::swap(FirstOffset, SecondOffset);
4528
4529
if (IsLargeOffset) {
4530
TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4531
TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4532
TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4533
TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4534
TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4535
TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4536
} else {
4537
TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4538
TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4539
TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4540
}
4541
4542
return false;
4543
}
4544
4545
bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4546
const MCSubtargetInfo *STI) {
4547
if (hasMips32r6() || hasMips64r6()) {
4548
return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4549
}
4550
4551
const MCOperand &DstRegOp = Inst.getOperand(0);
4552
assert(DstRegOp.isReg() && "expected register operand kind");
4553
const MCOperand &SrcRegOp = Inst.getOperand(1);
4554
assert(SrcRegOp.isReg() && "expected register operand kind");
4555
const MCOperand &OffsetImmOp = Inst.getOperand(2);
4556
assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4557
4558
MipsTargetStreamer &TOut = getTargetStreamer();
4559
unsigned DstReg = DstRegOp.getReg();
4560
unsigned SrcReg = SrcRegOp.getReg();
4561
int64_t OffsetValue = OffsetImmOp.getImm();
4562
4563
// Compute left/right load/store offsets.
4564
bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4565
int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4566
int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4567
if (isLittle())
4568
std::swap(LxlOffset, LxrOffset);
4569
4570
bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4571
bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4572
unsigned TmpReg = SrcReg;
4573
if (IsLargeOffset || DoMove) {
4574
warnIfNoMacro(IDLoc);
4575
TmpReg = getATReg(IDLoc);
4576
if (!TmpReg)
4577
return true;
4578
}
4579
4580
if (IsLargeOffset) {
4581
if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4582
IDLoc, Out, STI))
4583
return true;
4584
}
4585
4586
if (DoMove)
4587
std::swap(DstReg, TmpReg);
4588
4589
unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4590
unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4591
TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4592
TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4593
4594
if (DoMove)
4595
TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4596
4597
return false;
4598
}
4599
4600
bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4601
const MCSubtargetInfo *STI) {
4602
MipsTargetStreamer &TOut = getTargetStreamer();
4603
4604
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4605
assert(Inst.getOperand(0).isReg() &&
4606
Inst.getOperand(1).isReg() &&
4607
Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4608
4609
unsigned DstReg = Inst.getOperand(0).getReg();
4610
unsigned SrcReg = Inst.getOperand(1).getReg();
4611
unsigned OpReg = Inst.getOperand(2).getReg();
4612
unsigned OpCode;
4613
4614
warnIfNoMacro(IDLoc);
4615
4616
switch (Inst.getOpcode()) {
4617
case Mips::SGE:
4618
OpCode = Mips::SLT;
4619
break;
4620
case Mips::SGEU:
4621
OpCode = Mips::SLTu;
4622
break;
4623
default:
4624
llvm_unreachable("unexpected 'sge' opcode");
4625
}
4626
4627
// $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4628
TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4629
TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4630
4631
return false;
4632
}
4633
4634
bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4635
const MCSubtargetInfo *STI) {
4636
MipsTargetStreamer &TOut = getTargetStreamer();
4637
4638
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4639
assert(Inst.getOperand(0).isReg() &&
4640
Inst.getOperand(1).isReg() &&
4641
Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4642
4643
unsigned DstReg = Inst.getOperand(0).getReg();
4644
unsigned SrcReg = Inst.getOperand(1).getReg();
4645
int64_t ImmValue = Inst.getOperand(2).getImm();
4646
unsigned OpRegCode, OpImmCode;
4647
4648
warnIfNoMacro(IDLoc);
4649
4650
switch (Inst.getOpcode()) {
4651
case Mips::SGEImm:
4652
case Mips::SGEImm64:
4653
OpRegCode = Mips::SLT;
4654
OpImmCode = Mips::SLTi;
4655
break;
4656
case Mips::SGEUImm:
4657
case Mips::SGEUImm64:
4658
OpRegCode = Mips::SLTu;
4659
OpImmCode = Mips::SLTiu;
4660
break;
4661
default:
4662
llvm_unreachable("unexpected 'sge' opcode with immediate");
4663
}
4664
4665
// $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4666
if (isInt<16>(ImmValue)) {
4667
// Use immediate version of STL.
4668
TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4669
TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4670
} else {
4671
unsigned ImmReg = DstReg;
4672
if (DstReg == SrcReg) {
4673
unsigned ATReg = getATReg(Inst.getLoc());
4674
if (!ATReg)
4675
return true;
4676
ImmReg = ATReg;
4677
}
4678
4679
if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4680
false, IDLoc, Out, STI))
4681
return true;
4682
4683
TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4684
TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4685
}
4686
4687
return false;
4688
}
4689
4690
bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4691
const MCSubtargetInfo *STI) {
4692
MipsTargetStreamer &TOut = getTargetStreamer();
4693
4694
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4695
assert(Inst.getOperand(0).isReg() &&
4696
Inst.getOperand(1).isReg() &&
4697
Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4698
4699
unsigned DstReg = Inst.getOperand(0).getReg();
4700
unsigned SrcReg = Inst.getOperand(1).getReg();
4701
unsigned ImmReg = DstReg;
4702
int64_t ImmValue = Inst.getOperand(2).getImm();
4703
unsigned OpCode;
4704
4705
warnIfNoMacro(IDLoc);
4706
4707
switch (Inst.getOpcode()) {
4708
case Mips::SGTImm:
4709
case Mips::SGTImm64:
4710
OpCode = Mips::SLT;
4711
break;
4712
case Mips::SGTUImm:
4713
case Mips::SGTUImm64:
4714
OpCode = Mips::SLTu;
4715
break;
4716
default:
4717
llvm_unreachable("unexpected 'sgt' opcode with immediate");
4718
}
4719
4720
if (DstReg == SrcReg) {
4721
unsigned ATReg = getATReg(Inst.getLoc());
4722
if (!ATReg)
4723
return true;
4724
ImmReg = ATReg;
4725
}
4726
4727
if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4728
false, IDLoc, Out, STI))
4729
return true;
4730
4731
// $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4732
TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4733
4734
return false;
4735
}
4736
4737
bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4738
const MCSubtargetInfo *STI) {
4739
MipsTargetStreamer &TOut = getTargetStreamer();
4740
4741
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4742
assert(Inst.getOperand(0).isReg() &&
4743
Inst.getOperand(1).isReg() &&
4744
Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4745
4746
unsigned DstReg = Inst.getOperand(0).getReg();
4747
unsigned SrcReg = Inst.getOperand(1).getReg();
4748
unsigned OpReg = Inst.getOperand(2).getReg();
4749
unsigned OpCode;
4750
4751
warnIfNoMacro(IDLoc);
4752
4753
switch (Inst.getOpcode()) {
4754
case Mips::SLE:
4755
OpCode = Mips::SLT;
4756
break;
4757
case Mips::SLEU:
4758
OpCode = Mips::SLTu;
4759
break;
4760
default:
4761
llvm_unreachable("unexpected 'sge' opcode");
4762
}
4763
4764
// $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4765
TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4766
TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4767
4768
return false;
4769
}
4770
4771
bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4772
const MCSubtargetInfo *STI) {
4773
MipsTargetStreamer &TOut = getTargetStreamer();
4774
4775
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4776
assert(Inst.getOperand(0).isReg() &&
4777
Inst.getOperand(1).isReg() &&
4778
Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4779
4780
unsigned DstReg = Inst.getOperand(0).getReg();
4781
unsigned SrcReg = Inst.getOperand(1).getReg();
4782
int64_t ImmValue = Inst.getOperand(2).getImm();
4783
unsigned OpRegCode;
4784
4785
warnIfNoMacro(IDLoc);
4786
4787
switch (Inst.getOpcode()) {
4788
case Mips::SLEImm:
4789
case Mips::SLEImm64:
4790
OpRegCode = Mips::SLT;
4791
break;
4792
case Mips::SLEUImm:
4793
case Mips::SLEUImm64:
4794
OpRegCode = Mips::SLTu;
4795
break;
4796
default:
4797
llvm_unreachable("unexpected 'sge' opcode with immediate");
4798
}
4799
4800
// $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4801
unsigned ImmReg = DstReg;
4802
if (DstReg == SrcReg) {
4803
unsigned ATReg = getATReg(Inst.getLoc());
4804
if (!ATReg)
4805
return true;
4806
ImmReg = ATReg;
4807
}
4808
4809
if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4810
false, IDLoc, Out, STI))
4811
return true;
4812
4813
TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4814
TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4815
4816
return false;
4817
}
4818
4819
bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4820
MCStreamer &Out,
4821
const MCSubtargetInfo *STI) {
4822
MipsTargetStreamer &TOut = getTargetStreamer();
4823
4824
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4825
assert(Inst.getOperand(0).isReg() &&
4826
Inst.getOperand(1).isReg() &&
4827
Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4828
4829
unsigned ATReg = Mips::NoRegister;
4830
unsigned FinalDstReg = Mips::NoRegister;
4831
unsigned DstReg = Inst.getOperand(0).getReg();
4832
unsigned SrcReg = Inst.getOperand(1).getReg();
4833
int64_t ImmValue = Inst.getOperand(2).getImm();
4834
4835
bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4836
4837
unsigned FinalOpcode = Inst.getOpcode();
4838
4839
if (DstReg == SrcReg) {
4840
ATReg = getATReg(Inst.getLoc());
4841
if (!ATReg)
4842
return true;
4843
FinalDstReg = DstReg;
4844
DstReg = ATReg;
4845
}
4846
4847
if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4848
Inst.getLoc(), Out, STI)) {
4849
switch (FinalOpcode) {
4850
default:
4851
llvm_unreachable("unimplemented expansion");
4852
case Mips::ADDi:
4853
FinalOpcode = Mips::ADD;
4854
break;
4855
case Mips::ADDiu:
4856
FinalOpcode = Mips::ADDu;
4857
break;
4858
case Mips::ANDi:
4859
FinalOpcode = Mips::AND;
4860
break;
4861
case Mips::NORImm:
4862
FinalOpcode = Mips::NOR;
4863
break;
4864
case Mips::ORi:
4865
FinalOpcode = Mips::OR;
4866
break;
4867
case Mips::SLTi:
4868
FinalOpcode = Mips::SLT;
4869
break;
4870
case Mips::SLTiu:
4871
FinalOpcode = Mips::SLTu;
4872
break;
4873
case Mips::XORi:
4874
FinalOpcode = Mips::XOR;
4875
break;
4876
case Mips::ADDi_MM:
4877
FinalOpcode = Mips::ADD_MM;
4878
break;
4879
case Mips::ADDiu_MM:
4880
FinalOpcode = Mips::ADDu_MM;
4881
break;
4882
case Mips::ANDi_MM:
4883
FinalOpcode = Mips::AND_MM;
4884
break;
4885
case Mips::ORi_MM:
4886
FinalOpcode = Mips::OR_MM;
4887
break;
4888
case Mips::SLTi_MM:
4889
FinalOpcode = Mips::SLT_MM;
4890
break;
4891
case Mips::SLTiu_MM:
4892
FinalOpcode = Mips::SLTu_MM;
4893
break;
4894
case Mips::XORi_MM:
4895
FinalOpcode = Mips::XOR_MM;
4896
break;
4897
case Mips::ANDi64:
4898
FinalOpcode = Mips::AND64;
4899
break;
4900
case Mips::NORImm64:
4901
FinalOpcode = Mips::NOR64;
4902
break;
4903
case Mips::ORi64:
4904
FinalOpcode = Mips::OR64;
4905
break;
4906
case Mips::SLTImm64:
4907
FinalOpcode = Mips::SLT64;
4908
break;
4909
case Mips::SLTUImm64:
4910
FinalOpcode = Mips::SLTu64;
4911
break;
4912
case Mips::XORi64:
4913
FinalOpcode = Mips::XOR64;
4914
break;
4915
}
4916
4917
if (FinalDstReg == Mips::NoRegister)
4918
TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4919
else
4920
TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4921
return false;
4922
}
4923
return true;
4924
}
4925
4926
bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4927
const MCSubtargetInfo *STI) {
4928
MipsTargetStreamer &TOut = getTargetStreamer();
4929
unsigned ATReg = Mips::NoRegister;
4930
unsigned DReg = Inst.getOperand(0).getReg();
4931
unsigned SReg = Inst.getOperand(1).getReg();
4932
unsigned TReg = Inst.getOperand(2).getReg();
4933
unsigned TmpReg = DReg;
4934
4935
unsigned FirstShift = Mips::NOP;
4936
unsigned SecondShift = Mips::NOP;
4937
4938
if (hasMips32r2()) {
4939
if (DReg == SReg) {
4940
TmpReg = getATReg(Inst.getLoc());
4941
if (!TmpReg)
4942
return true;
4943
}
4944
4945
if (Inst.getOpcode() == Mips::ROL) {
4946
TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4947
TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4948
return false;
4949
}
4950
4951
if (Inst.getOpcode() == Mips::ROR) {
4952
TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4953
return false;
4954
}
4955
4956
return true;
4957
}
4958
4959
if (hasMips32()) {
4960
switch (Inst.getOpcode()) {
4961
default:
4962
llvm_unreachable("unexpected instruction opcode");
4963
case Mips::ROL:
4964
FirstShift = Mips::SRLV;
4965
SecondShift = Mips::SLLV;
4966
break;
4967
case Mips::ROR:
4968
FirstShift = Mips::SLLV;
4969
SecondShift = Mips::SRLV;
4970
break;
4971
}
4972
4973
ATReg = getATReg(Inst.getLoc());
4974
if (!ATReg)
4975
return true;
4976
4977
TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4978
TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4979
TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4980
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4981
4982
return false;
4983
}
4984
4985
return true;
4986
}
4987
4988
bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4989
MCStreamer &Out,
4990
const MCSubtargetInfo *STI) {
4991
MipsTargetStreamer &TOut = getTargetStreamer();
4992
unsigned ATReg = Mips::NoRegister;
4993
unsigned DReg = Inst.getOperand(0).getReg();
4994
unsigned SReg = Inst.getOperand(1).getReg();
4995
int64_t ImmValue = Inst.getOperand(2).getImm();
4996
4997
unsigned FirstShift = Mips::NOP;
4998
unsigned SecondShift = Mips::NOP;
4999
5000
if (hasMips32r2()) {
5001
if (Inst.getOpcode() == Mips::ROLImm) {
5002
uint64_t MaxShift = 32;
5003
uint64_t ShiftValue = ImmValue;
5004
if (ImmValue != 0)
5005
ShiftValue = MaxShift - ImmValue;
5006
TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5007
return false;
5008
}
5009
5010
if (Inst.getOpcode() == Mips::RORImm) {
5011
TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
5012
return false;
5013
}
5014
5015
return true;
5016
}
5017
5018
if (hasMips32()) {
5019
if (ImmValue == 0) {
5020
TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
5021
return false;
5022
}
5023
5024
switch (Inst.getOpcode()) {
5025
default:
5026
llvm_unreachable("unexpected instruction opcode");
5027
case Mips::ROLImm:
5028
FirstShift = Mips::SLL;
5029
SecondShift = Mips::SRL;
5030
break;
5031
case Mips::RORImm:
5032
FirstShift = Mips::SRL;
5033
SecondShift = Mips::SLL;
5034
break;
5035
}
5036
5037
ATReg = getATReg(Inst.getLoc());
5038
if (!ATReg)
5039
return true;
5040
5041
TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
5042
TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
5043
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5044
5045
return false;
5046
}
5047
5048
return true;
5049
}
5050
5051
bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5052
const MCSubtargetInfo *STI) {
5053
MipsTargetStreamer &TOut = getTargetStreamer();
5054
unsigned ATReg = Mips::NoRegister;
5055
unsigned DReg = Inst.getOperand(0).getReg();
5056
unsigned SReg = Inst.getOperand(1).getReg();
5057
unsigned TReg = Inst.getOperand(2).getReg();
5058
unsigned TmpReg = DReg;
5059
5060
unsigned FirstShift = Mips::NOP;
5061
unsigned SecondShift = Mips::NOP;
5062
5063
if (hasMips64r2()) {
5064
if (TmpReg == SReg) {
5065
TmpReg = getATReg(Inst.getLoc());
5066
if (!TmpReg)
5067
return true;
5068
}
5069
5070
if (Inst.getOpcode() == Mips::DROL) {
5071
TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5072
TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
5073
return false;
5074
}
5075
5076
if (Inst.getOpcode() == Mips::DROR) {
5077
TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
5078
return false;
5079
}
5080
5081
return true;
5082
}
5083
5084
if (hasMips64()) {
5085
switch (Inst.getOpcode()) {
5086
default:
5087
llvm_unreachable("unexpected instruction opcode");
5088
case Mips::DROL:
5089
FirstShift = Mips::DSRLV;
5090
SecondShift = Mips::DSLLV;
5091
break;
5092
case Mips::DROR:
5093
FirstShift = Mips::DSLLV;
5094
SecondShift = Mips::DSRLV;
5095
break;
5096
}
5097
5098
ATReg = getATReg(Inst.getLoc());
5099
if (!ATReg)
5100
return true;
5101
5102
TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5103
TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5104
TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5105
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5106
5107
return false;
5108
}
5109
5110
return true;
5111
}
5112
5113
bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5114
MCStreamer &Out,
5115
const MCSubtargetInfo *STI) {
5116
MipsTargetStreamer &TOut = getTargetStreamer();
5117
unsigned ATReg = Mips::NoRegister;
5118
unsigned DReg = Inst.getOperand(0).getReg();
5119
unsigned SReg = Inst.getOperand(1).getReg();
5120
int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5121
5122
unsigned FirstShift = Mips::NOP;
5123
unsigned SecondShift = Mips::NOP;
5124
5125
MCInst TmpInst;
5126
5127
if (hasMips64r2()) {
5128
unsigned FinalOpcode = Mips::NOP;
5129
if (ImmValue == 0)
5130
FinalOpcode = Mips::DROTR;
5131
else if (ImmValue % 32 == 0)
5132
FinalOpcode = Mips::DROTR32;
5133
else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5134
if (Inst.getOpcode() == Mips::DROLImm)
5135
FinalOpcode = Mips::DROTR32;
5136
else
5137
FinalOpcode = Mips::DROTR;
5138
} else if (ImmValue >= 33) {
5139
if (Inst.getOpcode() == Mips::DROLImm)
5140
FinalOpcode = Mips::DROTR;
5141
else
5142
FinalOpcode = Mips::DROTR32;
5143
}
5144
5145
uint64_t ShiftValue = ImmValue % 32;
5146
if (Inst.getOpcode() == Mips::DROLImm)
5147
ShiftValue = (32 - ImmValue % 32) % 32;
5148
5149
TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5150
5151
return false;
5152
}
5153
5154
if (hasMips64()) {
5155
if (ImmValue == 0) {
5156
TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5157
return false;
5158
}
5159
5160
switch (Inst.getOpcode()) {
5161
default:
5162
llvm_unreachable("unexpected instruction opcode");
5163
case Mips::DROLImm:
5164
if ((ImmValue >= 1) && (ImmValue <= 31)) {
5165
FirstShift = Mips::DSLL;
5166
SecondShift = Mips::DSRL32;
5167
}
5168
if (ImmValue == 32) {
5169
FirstShift = Mips::DSLL32;
5170
SecondShift = Mips::DSRL32;
5171
}
5172
if ((ImmValue >= 33) && (ImmValue <= 63)) {
5173
FirstShift = Mips::DSLL32;
5174
SecondShift = Mips::DSRL;
5175
}
5176
break;
5177
case Mips::DRORImm:
5178
if ((ImmValue >= 1) && (ImmValue <= 31)) {
5179
FirstShift = Mips::DSRL;
5180
SecondShift = Mips::DSLL32;
5181
}
5182
if (ImmValue == 32) {
5183
FirstShift = Mips::DSRL32;
5184
SecondShift = Mips::DSLL32;
5185
}
5186
if ((ImmValue >= 33) && (ImmValue <= 63)) {
5187
FirstShift = Mips::DSRL32;
5188
SecondShift = Mips::DSLL;
5189
}
5190
break;
5191
}
5192
5193
ATReg = getATReg(Inst.getLoc());
5194
if (!ATReg)
5195
return true;
5196
5197
TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5198
TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5199
Inst.getLoc(), STI);
5200
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5201
5202
return false;
5203
}
5204
5205
return true;
5206
}
5207
5208
bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5209
const MCSubtargetInfo *STI) {
5210
MipsTargetStreamer &TOut = getTargetStreamer();
5211
unsigned FirstRegOp = Inst.getOperand(0).getReg();
5212
unsigned SecondRegOp = Inst.getOperand(1).getReg();
5213
5214
TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5215
if (FirstRegOp != SecondRegOp)
5216
TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5217
else
5218
TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5219
TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5220
5221
return false;
5222
}
5223
5224
bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5225
const MCSubtargetInfo *STI) {
5226
MipsTargetStreamer &TOut = getTargetStreamer();
5227
unsigned ATReg = Mips::NoRegister;
5228
unsigned DstReg = Inst.getOperand(0).getReg();
5229
unsigned SrcReg = Inst.getOperand(1).getReg();
5230
int32_t ImmValue = Inst.getOperand(2).getImm();
5231
5232
ATReg = getATReg(IDLoc);
5233
if (!ATReg)
5234
return true;
5235
5236
loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
5237
STI);
5238
5239
TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5240
SrcReg, ATReg, IDLoc, STI);
5241
5242
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5243
5244
return false;
5245
}
5246
5247
bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5248
const MCSubtargetInfo *STI) {
5249
MipsTargetStreamer &TOut = getTargetStreamer();
5250
unsigned ATReg = Mips::NoRegister;
5251
unsigned DstReg = Inst.getOperand(0).getReg();
5252
unsigned SrcReg = Inst.getOperand(1).getReg();
5253
unsigned TmpReg = Inst.getOperand(2).getReg();
5254
5255
ATReg = getATReg(Inst.getLoc());
5256
if (!ATReg)
5257
return true;
5258
5259
TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5260
SrcReg, TmpReg, IDLoc, STI);
5261
5262
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5263
5264
TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5265
DstReg, DstReg, 0x1F, IDLoc, STI);
5266
5267
TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5268
5269
if (useTraps()) {
5270
TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5271
} else {
5272
MCContext & Context = TOut.getStreamer().getContext();
5273
MCSymbol * BrTarget = Context.createTempSymbol();
5274
MCOperand LabelOp =
5275
MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5276
5277
TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5278
if (AssemblerOptions.back()->isReorder())
5279
TOut.emitNop(IDLoc, STI);
5280
TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5281
5282
TOut.getStreamer().emitLabel(BrTarget);
5283
}
5284
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5285
5286
return false;
5287
}
5288
5289
bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5290
const MCSubtargetInfo *STI) {
5291
MipsTargetStreamer &TOut = getTargetStreamer();
5292
unsigned ATReg = Mips::NoRegister;
5293
unsigned DstReg = Inst.getOperand(0).getReg();
5294
unsigned SrcReg = Inst.getOperand(1).getReg();
5295
unsigned TmpReg = Inst.getOperand(2).getReg();
5296
5297
ATReg = getATReg(IDLoc);
5298
if (!ATReg)
5299
return true;
5300
5301
TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5302
SrcReg, TmpReg, IDLoc, STI);
5303
5304
TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5305
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5306
if (useTraps()) {
5307
TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5308
} else {
5309
MCContext & Context = TOut.getStreamer().getContext();
5310
MCSymbol * BrTarget = Context.createTempSymbol();
5311
MCOperand LabelOp =
5312
MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5313
5314
TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5315
if (AssemblerOptions.back()->isReorder())
5316
TOut.emitNop(IDLoc, STI);
5317
TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5318
5319
TOut.getStreamer().emitLabel(BrTarget);
5320
}
5321
5322
return false;
5323
}
5324
5325
bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5326
const MCSubtargetInfo *STI) {
5327
MipsTargetStreamer &TOut = getTargetStreamer();
5328
unsigned DstReg = Inst.getOperand(0).getReg();
5329
unsigned SrcReg = Inst.getOperand(1).getReg();
5330
unsigned TmpReg = Inst.getOperand(2).getReg();
5331
5332
TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5333
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5334
5335
return false;
5336
}
5337
5338
// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5339
// lw $<reg+1>>, offset+4($reg2)'
5340
// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5341
// sw $<reg+1>>, offset+4($reg2)'
5342
// for O32.
5343
bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5344
MCStreamer &Out,
5345
const MCSubtargetInfo *STI,
5346
bool IsLoad) {
5347
if (!isABI_O32())
5348
return true;
5349
5350
warnIfNoMacro(IDLoc);
5351
5352
MipsTargetStreamer &TOut = getTargetStreamer();
5353
unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5354
unsigned FirstReg = Inst.getOperand(0).getReg();
5355
unsigned SecondReg = nextReg(FirstReg);
5356
unsigned BaseReg = Inst.getOperand(1).getReg();
5357
if (!SecondReg)
5358
return true;
5359
5360
warnIfRegIndexIsAT(FirstReg, IDLoc);
5361
5362
assert(Inst.getOperand(2).isImm() &&
5363
"Offset for load macro is not immediate!");
5364
5365
MCOperand &FirstOffset = Inst.getOperand(2);
5366
signed NextOffset = FirstOffset.getImm() + 4;
5367
MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5368
5369
if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5370
return true;
5371
5372
// For loads, clobber the base register with the second load instead of the
5373
// first if the BaseReg == FirstReg.
5374
if (FirstReg != BaseReg || !IsLoad) {
5375
TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5376
TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5377
} else {
5378
TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5379
TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5380
}
5381
5382
return false;
5383
}
5384
5385
5386
// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5387
// swc1 $<reg>, offset+4($reg2)'
5388
// or if little endian to 'swc1 $<reg>, offset($reg2);
5389
// swc1 $<reg+1>, offset+4($reg2)'
5390
// for Mips1.
5391
bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5392
MCStreamer &Out,
5393
const MCSubtargetInfo *STI) {
5394
if (!isABI_O32())
5395
return true;
5396
5397
warnIfNoMacro(IDLoc);
5398
5399
MipsTargetStreamer &TOut = getTargetStreamer();
5400
unsigned Opcode = Mips::SWC1;
5401
unsigned FirstReg = Inst.getOperand(0).getReg();
5402
unsigned SecondReg = nextReg(FirstReg);
5403
unsigned BaseReg = Inst.getOperand(1).getReg();
5404
if (!SecondReg)
5405
return true;
5406
5407
warnIfRegIndexIsAT(FirstReg, IDLoc);
5408
5409
assert(Inst.getOperand(2).isImm() &&
5410
"Offset for macro is not immediate!");
5411
5412
MCOperand &FirstOffset = Inst.getOperand(2);
5413
signed NextOffset = FirstOffset.getImm() + 4;
5414
MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5415
5416
if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5417
return true;
5418
5419
if (!IsLittleEndian)
5420
std::swap(FirstReg, SecondReg);
5421
5422
TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5423
TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5424
5425
return false;
5426
}
5427
5428
bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5429
const MCSubtargetInfo *STI) {
5430
MipsTargetStreamer &TOut = getTargetStreamer();
5431
5432
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5433
assert(Inst.getOperand(0).isReg() &&
5434
Inst.getOperand(1).isReg() &&
5435
Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5436
5437
unsigned DstReg = Inst.getOperand(0).getReg();
5438
unsigned SrcReg = Inst.getOperand(1).getReg();
5439
unsigned OpReg = Inst.getOperand(2).getReg();
5440
5441
warnIfNoMacro(IDLoc);
5442
5443
if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5444
TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5445
TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5446
return false;
5447
}
5448
5449
unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5450
TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5451
return false;
5452
}
5453
5454
bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5455
const MCSubtargetInfo *STI) {
5456
MipsTargetStreamer &TOut = getTargetStreamer();
5457
5458
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5459
assert(Inst.getOperand(0).isReg() &&
5460
Inst.getOperand(1).isReg() &&
5461
Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5462
5463
unsigned DstReg = Inst.getOperand(0).getReg();
5464
unsigned SrcReg = Inst.getOperand(1).getReg();
5465
int64_t Imm = Inst.getOperand(2).getImm();
5466
5467
warnIfNoMacro(IDLoc);
5468
5469
if (Imm == 0) {
5470
TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5471
return false;
5472
}
5473
5474
if (SrcReg == Mips::ZERO) {
5475
Warning(IDLoc, "comparison is always false");
5476
TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5477
DstReg, SrcReg, SrcReg, IDLoc, STI);
5478
return false;
5479
}
5480
5481
unsigned Opc;
5482
if (Imm > -0x8000 && Imm < 0) {
5483
Imm = -Imm;
5484
Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5485
} else {
5486
Opc = Mips::XORi;
5487
}
5488
5489
if (!isUInt<16>(Imm)) {
5490
unsigned ATReg = getATReg(IDLoc);
5491
if (!ATReg)
5492
return true;
5493
5494
if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5495
Out, STI))
5496
return true;
5497
5498
TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5499
TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5500
return false;
5501
}
5502
5503
TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5504
TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5505
return false;
5506
}
5507
5508
bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5509
const MCSubtargetInfo *STI) {
5510
5511
MipsTargetStreamer &TOut = getTargetStreamer();
5512
5513
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5514
assert(Inst.getOperand(0).isReg() &&
5515
Inst.getOperand(1).isReg() &&
5516
Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5517
5518
unsigned DstReg = Inst.getOperand(0).getReg();
5519
unsigned SrcReg = Inst.getOperand(1).getReg();
5520
unsigned OpReg = Inst.getOperand(2).getReg();
5521
5522
warnIfNoMacro(IDLoc);
5523
5524
if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5525
TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5526
TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5527
return false;
5528
}
5529
5530
unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5531
TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5532
return false;
5533
}
5534
5535
bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5536
const MCSubtargetInfo *STI) {
5537
MipsTargetStreamer &TOut = getTargetStreamer();
5538
5539
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5540
assert(Inst.getOperand(0).isReg() &&
5541
Inst.getOperand(1).isReg() &&
5542
Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5543
5544
unsigned DstReg = Inst.getOperand(0).getReg();
5545
unsigned SrcReg = Inst.getOperand(1).getReg();
5546
int64_t ImmValue = Inst.getOperand(2).getImm();
5547
5548
warnIfNoMacro(IDLoc);
5549
5550
if (ImmValue == 0) {
5551
TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5552
return false;
5553
}
5554
5555
if (SrcReg == Mips::ZERO) {
5556
Warning(IDLoc, "comparison is always true");
5557
if (loadImmediate(1, DstReg, Mips::NoRegister, true, false, IDLoc, Out,
5558
STI))
5559
return true;
5560
return false;
5561
}
5562
5563
unsigned Opc;
5564
if (ImmValue > -0x8000 && ImmValue < 0) {
5565
ImmValue = -ImmValue;
5566
Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5567
} else {
5568
Opc = Mips::XORi;
5569
}
5570
5571
if (isUInt<16>(ImmValue)) {
5572
TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5573
TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5574
return false;
5575
}
5576
5577
unsigned ATReg = getATReg(IDLoc);
5578
if (!ATReg)
5579
return true;
5580
5581
if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
5582
false, IDLoc, Out, STI))
5583
return true;
5584
5585
TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5586
TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5587
return false;
5588
}
5589
5590
// Map the DSP accumulator and control register to the corresponding gpr
5591
// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5592
// do not map the DSP registers contigously to gpr registers.
5593
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5594
switch (Inst.getOpcode()) {
5595
case Mips::MFTLO:
5596
case Mips::MTTLO:
5597
switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5598
case Mips::AC0:
5599
return Mips::ZERO;
5600
case Mips::AC1:
5601
return Mips::A0;
5602
case Mips::AC2:
5603
return Mips::T0;
5604
case Mips::AC3:
5605
return Mips::T4;
5606
default:
5607
llvm_unreachable("Unknown register for 'mttr' alias!");
5608
}
5609
case Mips::MFTHI:
5610
case Mips::MTTHI:
5611
switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5612
case Mips::AC0:
5613
return Mips::AT;
5614
case Mips::AC1:
5615
return Mips::A1;
5616
case Mips::AC2:
5617
return Mips::T1;
5618
case Mips::AC3:
5619
return Mips::T5;
5620
default:
5621
llvm_unreachable("Unknown register for 'mttr' alias!");
5622
}
5623
case Mips::MFTACX:
5624
case Mips::MTTACX:
5625
switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5626
case Mips::AC0:
5627
return Mips::V0;
5628
case Mips::AC1:
5629
return Mips::A2;
5630
case Mips::AC2:
5631
return Mips::T2;
5632
case Mips::AC3:
5633
return Mips::T6;
5634
default:
5635
llvm_unreachable("Unknown register for 'mttr' alias!");
5636
}
5637
case Mips::MFTDSP:
5638
case Mips::MTTDSP:
5639
return Mips::S0;
5640
default:
5641
llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5642
}
5643
}
5644
5645
// Map the floating point register operand to the corresponding register
5646
// operand.
5647
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5648
switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5649
case Mips::F0: return Mips::ZERO;
5650
case Mips::F1: return Mips::AT;
5651
case Mips::F2: return Mips::V0;
5652
case Mips::F3: return Mips::V1;
5653
case Mips::F4: return Mips::A0;
5654
case Mips::F5: return Mips::A1;
5655
case Mips::F6: return Mips::A2;
5656
case Mips::F7: return Mips::A3;
5657
case Mips::F8: return Mips::T0;
5658
case Mips::F9: return Mips::T1;
5659
case Mips::F10: return Mips::T2;
5660
case Mips::F11: return Mips::T3;
5661
case Mips::F12: return Mips::T4;
5662
case Mips::F13: return Mips::T5;
5663
case Mips::F14: return Mips::T6;
5664
case Mips::F15: return Mips::T7;
5665
case Mips::F16: return Mips::S0;
5666
case Mips::F17: return Mips::S1;
5667
case Mips::F18: return Mips::S2;
5668
case Mips::F19: return Mips::S3;
5669
case Mips::F20: return Mips::S4;
5670
case Mips::F21: return Mips::S5;
5671
case Mips::F22: return Mips::S6;
5672
case Mips::F23: return Mips::S7;
5673
case Mips::F24: return Mips::T8;
5674
case Mips::F25: return Mips::T9;
5675
case Mips::F26: return Mips::K0;
5676
case Mips::F27: return Mips::K1;
5677
case Mips::F28: return Mips::GP;
5678
case Mips::F29: return Mips::SP;
5679
case Mips::F30: return Mips::FP;
5680
case Mips::F31: return Mips::RA;
5681
default: llvm_unreachable("Unknown register for mttc1 alias!");
5682
}
5683
}
5684
5685
// Map the coprocessor operand the corresponding gpr register operand.
5686
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5687
switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5688
case Mips::COP00: return Mips::ZERO;
5689
case Mips::COP01: return Mips::AT;
5690
case Mips::COP02: return Mips::V0;
5691
case Mips::COP03: return Mips::V1;
5692
case Mips::COP04: return Mips::A0;
5693
case Mips::COP05: return Mips::A1;
5694
case Mips::COP06: return Mips::A2;
5695
case Mips::COP07: return Mips::A3;
5696
case Mips::COP08: return Mips::T0;
5697
case Mips::COP09: return Mips::T1;
5698
case Mips::COP010: return Mips::T2;
5699
case Mips::COP011: return Mips::T3;
5700
case Mips::COP012: return Mips::T4;
5701
case Mips::COP013: return Mips::T5;
5702
case Mips::COP014: return Mips::T6;
5703
case Mips::COP015: return Mips::T7;
5704
case Mips::COP016: return Mips::S0;
5705
case Mips::COP017: return Mips::S1;
5706
case Mips::COP018: return Mips::S2;
5707
case Mips::COP019: return Mips::S3;
5708
case Mips::COP020: return Mips::S4;
5709
case Mips::COP021: return Mips::S5;
5710
case Mips::COP022: return Mips::S6;
5711
case Mips::COP023: return Mips::S7;
5712
case Mips::COP024: return Mips::T8;
5713
case Mips::COP025: return Mips::T9;
5714
case Mips::COP026: return Mips::K0;
5715
case Mips::COP027: return Mips::K1;
5716
case Mips::COP028: return Mips::GP;
5717
case Mips::COP029: return Mips::SP;
5718
case Mips::COP030: return Mips::FP;
5719
case Mips::COP031: return Mips::RA;
5720
default: llvm_unreachable("Unknown register for mttc0 alias!");
5721
}
5722
}
5723
5724
/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5725
/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5726
bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5727
const MCSubtargetInfo *STI) {
5728
MipsTargetStreamer &TOut = getTargetStreamer();
5729
unsigned rd = 0;
5730
unsigned u = 1;
5731
unsigned sel = 0;
5732
unsigned h = 0;
5733
bool IsMFTR = false;
5734
switch (Inst.getOpcode()) {
5735
case Mips::MFTC0:
5736
IsMFTR = true;
5737
[[fallthrough]];
5738
case Mips::MTTC0:
5739
u = 0;
5740
rd = getRegisterForMxtrC0(Inst, IsMFTR);
5741
sel = Inst.getOperand(2).getImm();
5742
break;
5743
case Mips::MFTGPR:
5744
IsMFTR = true;
5745
[[fallthrough]];
5746
case Mips::MTTGPR:
5747
rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5748
break;
5749
case Mips::MFTLO:
5750
case Mips::MFTHI:
5751
case Mips::MFTACX:
5752
case Mips::MFTDSP:
5753
IsMFTR = true;
5754
[[fallthrough]];
5755
case Mips::MTTLO:
5756
case Mips::MTTHI:
5757
case Mips::MTTACX:
5758
case Mips::MTTDSP:
5759
rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5760
sel = 1;
5761
break;
5762
case Mips::MFTHC1:
5763
h = 1;
5764
[[fallthrough]];
5765
case Mips::MFTC1:
5766
IsMFTR = true;
5767
rd = getRegisterForMxtrFP(Inst, IsMFTR);
5768
sel = 2;
5769
break;
5770
case Mips::MTTHC1:
5771
h = 1;
5772
[[fallthrough]];
5773
case Mips::MTTC1:
5774
rd = getRegisterForMxtrFP(Inst, IsMFTR);
5775
sel = 2;
5776
break;
5777
case Mips::CFTC1:
5778
IsMFTR = true;
5779
[[fallthrough]];
5780
case Mips::CTTC1:
5781
rd = getRegisterForMxtrFP(Inst, IsMFTR);
5782
sel = 3;
5783
break;
5784
}
5785
unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5786
unsigned Op1 =
5787
IsMFTR ? rd
5788
: (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5789
: Inst.getOperand(0).getReg());
5790
5791
TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5792
STI);
5793
return false;
5794
}
5795
5796
bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5797
const MCSubtargetInfo *STI) {
5798
assert(Inst.getNumOperands() == 3 && "expected three operands");
5799
assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5800
assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5801
5802
warnIfNoMacro(IDLoc);
5803
5804
MipsTargetStreamer &TOut = getTargetStreamer();
5805
unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5806
unsigned RtReg = Inst.getOperand(0).getReg();
5807
unsigned BaseReg = Inst.getOperand(1).getReg();
5808
const MCOperand &BaseOp = Inst.getOperand(2);
5809
5810
if (BaseOp.isImm()) {
5811
int64_t ImmValue = BaseOp.getImm();
5812
if (ImmValue == 0) {
5813
TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5814
return false;
5815
}
5816
}
5817
5818
unsigned ATReg = getATReg(IDLoc);
5819
if (!ATReg)
5820
return true;
5821
5822
if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5823
return true;
5824
5825
TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5826
return false;
5827
}
5828
5829
unsigned
5830
MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5831
const OperandVector &Operands) {
5832
switch (Inst.getOpcode()) {
5833
default:
5834
return Match_Success;
5835
case Mips::DATI:
5836
case Mips::DAHI:
5837
if (static_cast<MipsOperand &>(*Operands[1])
5838
.isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5839
return Match_Success;
5840
return Match_RequiresSameSrcAndDst;
5841
}
5842
}
5843
5844
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5845
switch (Inst.getOpcode()) {
5846
// As described by the MIPSR6 spec, daui must not use the zero operand for
5847
// its source operand.
5848
case Mips::DAUI:
5849
if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5850
Inst.getOperand(1).getReg() == Mips::ZERO_64)
5851
return Match_RequiresNoZeroRegister;
5852
return Match_Success;
5853
// As described by the Mips32r2 spec, the registers Rd and Rs for
5854
// jalr.hb must be different.
5855
// It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5856
// and registers Rd and Base for microMIPS lwp instruction
5857
case Mips::JALR_HB:
5858
case Mips::JALR_HB64:
5859
case Mips::JALRC_HB_MMR6:
5860
case Mips::JALRC_MMR6:
5861
if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5862
return Match_RequiresDifferentSrcAndDst;
5863
return Match_Success;
5864
case Mips::LWP_MM:
5865
if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5866
return Match_RequiresDifferentSrcAndDst;
5867
return Match_Success;
5868
case Mips::SYNC:
5869
if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5870
return Match_NonZeroOperandForSync;
5871
return Match_Success;
5872
case Mips::MFC0:
5873
case Mips::MTC0:
5874
case Mips::MTC2:
5875
case Mips::MFC2:
5876
if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5877
return Match_NonZeroOperandForMTCX;
5878
return Match_Success;
5879
// As described the MIPSR6 spec, the compact branches that compare registers
5880
// must:
5881
// a) Not use the zero register.
5882
// b) Not use the same register twice.
5883
// c) rs < rt for bnec, beqc.
5884
// NB: For this case, the encoding will swap the operands as their
5885
// ordering doesn't matter. GAS performs this transformation too.
5886
// Hence, that constraint does not have to be enforced.
5887
//
5888
// The compact branches that branch iff the signed addition of two registers
5889
// would overflow must have rs >= rt. That can be handled like beqc/bnec with
5890
// operand swapping. They do not have restriction of using the zero register.
5891
case Mips::BLEZC: case Mips::BLEZC_MMR6:
5892
case Mips::BGEZC: case Mips::BGEZC_MMR6:
5893
case Mips::BGTZC: case Mips::BGTZC_MMR6:
5894
case Mips::BLTZC: case Mips::BLTZC_MMR6:
5895
case Mips::BEQZC: case Mips::BEQZC_MMR6:
5896
case Mips::BNEZC: case Mips::BNEZC_MMR6:
5897
case Mips::BLEZC64:
5898
case Mips::BGEZC64:
5899
case Mips::BGTZC64:
5900
case Mips::BLTZC64:
5901
case Mips::BEQZC64:
5902
case Mips::BNEZC64:
5903
if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5904
Inst.getOperand(0).getReg() == Mips::ZERO_64)
5905
return Match_RequiresNoZeroRegister;
5906
return Match_Success;
5907
case Mips::BGEC: case Mips::BGEC_MMR6:
5908
case Mips::BLTC: case Mips::BLTC_MMR6:
5909
case Mips::BGEUC: case Mips::BGEUC_MMR6:
5910
case Mips::BLTUC: case Mips::BLTUC_MMR6:
5911
case Mips::BEQC: case Mips::BEQC_MMR6:
5912
case Mips::BNEC: case Mips::BNEC_MMR6:
5913
case Mips::BGEC64:
5914
case Mips::BLTC64:
5915
case Mips::BGEUC64:
5916
case Mips::BLTUC64:
5917
case Mips::BEQC64:
5918
case Mips::BNEC64:
5919
if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5920
Inst.getOperand(0).getReg() == Mips::ZERO_64)
5921
return Match_RequiresNoZeroRegister;
5922
if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5923
Inst.getOperand(1).getReg() == Mips::ZERO_64)
5924
return Match_RequiresNoZeroRegister;
5925
if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5926
return Match_RequiresDifferentOperands;
5927
return Match_Success;
5928
case Mips::DINS: {
5929
assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5930
"Operands must be immediates for dins!");
5931
const signed Pos = Inst.getOperand(2).getImm();
5932
const signed Size = Inst.getOperand(3).getImm();
5933
if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5934
return Match_RequiresPosSizeRange0_32;
5935
return Match_Success;
5936
}
5937
case Mips::DINSM:
5938
case Mips::DINSU: {
5939
assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5940
"Operands must be immediates for dinsm/dinsu!");
5941
const signed Pos = Inst.getOperand(2).getImm();
5942
const signed Size = Inst.getOperand(3).getImm();
5943
if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5944
return Match_RequiresPosSizeRange33_64;
5945
return Match_Success;
5946
}
5947
case Mips::DEXT: {
5948
assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5949
"Operands must be immediates for DEXTM!");
5950
const signed Pos = Inst.getOperand(2).getImm();
5951
const signed Size = Inst.getOperand(3).getImm();
5952
if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5953
return Match_RequiresPosSizeUImm6;
5954
return Match_Success;
5955
}
5956
case Mips::DEXTM:
5957
case Mips::DEXTU: {
5958
assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5959
"Operands must be immediates for dextm/dextu!");
5960
const signed Pos = Inst.getOperand(2).getImm();
5961
const signed Size = Inst.getOperand(3).getImm();
5962
if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5963
return Match_RequiresPosSizeRange33_64;
5964
return Match_Success;
5965
}
5966
case Mips::CRC32B: case Mips::CRC32CB:
5967
case Mips::CRC32H: case Mips::CRC32CH:
5968
case Mips::CRC32W: case Mips::CRC32CW:
5969
case Mips::CRC32D: case Mips::CRC32CD:
5970
if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5971
return Match_RequiresSameSrcAndDst;
5972
return Match_Success;
5973
}
5974
5975
uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5976
if ((TSFlags & MipsII::HasFCCRegOperand) &&
5977
(Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5978
return Match_NoFCCRegisterForCurrentISA;
5979
5980
return Match_Success;
5981
5982
}
5983
5984
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5985
uint64_t ErrorInfo) {
5986
if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5987
SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5988
if (ErrorLoc == SMLoc())
5989
return Loc;
5990
return ErrorLoc;
5991
}
5992
return Loc;
5993
}
5994
5995
bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5996
OperandVector &Operands,
5997
MCStreamer &Out,
5998
uint64_t &ErrorInfo,
5999
bool MatchingInlineAsm) {
6000
MCInst Inst;
6001
unsigned MatchResult =
6002
MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
6003
6004
switch (MatchResult) {
6005
case Match_Success:
6006
if (processInstruction(Inst, IDLoc, Out, STI))
6007
return true;
6008
return false;
6009
case Match_MissingFeature:
6010
Error(IDLoc, "instruction requires a CPU feature not currently enabled");
6011
return true;
6012
case Match_InvalidTiedOperand:
6013
Error(IDLoc, "operand must match destination register");
6014
return true;
6015
case Match_InvalidOperand: {
6016
SMLoc ErrorLoc = IDLoc;
6017
if (ErrorInfo != ~0ULL) {
6018
if (ErrorInfo >= Operands.size())
6019
return Error(IDLoc, "too few operands for instruction");
6020
6021
ErrorLoc = Operands[ErrorInfo]->getStartLoc();
6022
if (ErrorLoc == SMLoc())
6023
ErrorLoc = IDLoc;
6024
}
6025
6026
return Error(ErrorLoc, "invalid operand for instruction");
6027
}
6028
case Match_NonZeroOperandForSync:
6029
return Error(IDLoc,
6030
"s-type must be zero or unspecified for pre-MIPS32 ISAs");
6031
case Match_NonZeroOperandForMTCX:
6032
return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
6033
case Match_MnemonicFail:
6034
return Error(IDLoc, "invalid instruction");
6035
case Match_RequiresDifferentSrcAndDst:
6036
return Error(IDLoc, "source and destination must be different");
6037
case Match_RequiresDifferentOperands:
6038
return Error(IDLoc, "registers must be different");
6039
case Match_RequiresNoZeroRegister:
6040
return Error(IDLoc, "invalid operand ($zero) for instruction");
6041
case Match_RequiresSameSrcAndDst:
6042
return Error(IDLoc, "source and destination must match");
6043
case Match_NoFCCRegisterForCurrentISA:
6044
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6045
"non-zero fcc register doesn't exist in current ISA level");
6046
case Match_Immz:
6047
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
6048
case Match_UImm1_0:
6049
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6050
"expected 1-bit unsigned immediate");
6051
case Match_UImm2_0:
6052
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6053
"expected 2-bit unsigned immediate");
6054
case Match_UImm2_1:
6055
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6056
"expected immediate in range 1 .. 4");
6057
case Match_UImm3_0:
6058
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6059
"expected 3-bit unsigned immediate");
6060
case Match_UImm4_0:
6061
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6062
"expected 4-bit unsigned immediate");
6063
case Match_SImm4_0:
6064
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6065
"expected 4-bit signed immediate");
6066
case Match_UImm5_0:
6067
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6068
"expected 5-bit unsigned immediate");
6069
case Match_SImm5_0:
6070
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6071
"expected 5-bit signed immediate");
6072
case Match_UImm5_1:
6073
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6074
"expected immediate in range 1 .. 32");
6075
case Match_UImm5_32:
6076
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6077
"expected immediate in range 32 .. 63");
6078
case Match_UImm5_33:
6079
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6080
"expected immediate in range 33 .. 64");
6081
case Match_UImm5_0_Report_UImm6:
6082
// This is used on UImm5 operands that have a corresponding UImm5_32
6083
// operand to avoid confusing the user.
6084
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6085
"expected 6-bit unsigned immediate");
6086
case Match_UImm5_Lsl2:
6087
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6088
"expected both 7-bit unsigned immediate and multiple of 4");
6089
case Match_UImmRange2_64:
6090
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6091
"expected immediate in range 2 .. 64");
6092
case Match_UImm6_0:
6093
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6094
"expected 6-bit unsigned immediate");
6095
case Match_UImm6_Lsl2:
6096
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6097
"expected both 8-bit unsigned immediate and multiple of 4");
6098
case Match_SImm6_0:
6099
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6100
"expected 6-bit signed immediate");
6101
case Match_UImm7_0:
6102
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6103
"expected 7-bit unsigned immediate");
6104
case Match_UImm7_N1:
6105
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6106
"expected immediate in range -1 .. 126");
6107
case Match_SImm7_Lsl2:
6108
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6109
"expected both 9-bit signed immediate and multiple of 4");
6110
case Match_UImm8_0:
6111
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6112
"expected 8-bit unsigned immediate");
6113
case Match_UImm10_0:
6114
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6115
"expected 10-bit unsigned immediate");
6116
case Match_SImm10_0:
6117
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6118
"expected 10-bit signed immediate");
6119
case Match_SImm11_0:
6120
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6121
"expected 11-bit signed immediate");
6122
case Match_UImm16:
6123
case Match_UImm16_Relaxed:
6124
case Match_UImm16_AltRelaxed:
6125
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6126
"expected 16-bit unsigned immediate");
6127
case Match_SImm16:
6128
case Match_SImm16_Relaxed:
6129
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6130
"expected 16-bit signed immediate");
6131
case Match_SImm19_Lsl2:
6132
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6133
"expected both 19-bit signed immediate and multiple of 4");
6134
case Match_UImm20_0:
6135
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6136
"expected 20-bit unsigned immediate");
6137
case Match_UImm26_0:
6138
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6139
"expected 26-bit unsigned immediate");
6140
case Match_SImm32:
6141
case Match_SImm32_Relaxed:
6142
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6143
"expected 32-bit signed immediate");
6144
case Match_UImm32_Coerced:
6145
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6146
"expected 32-bit immediate");
6147
case Match_MemSImm9:
6148
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6149
"expected memory with 9-bit signed offset");
6150
case Match_MemSImm10:
6151
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6152
"expected memory with 10-bit signed offset");
6153
case Match_MemSImm10Lsl1:
6154
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6155
"expected memory with 11-bit signed offset and multiple of 2");
6156
case Match_MemSImm10Lsl2:
6157
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6158
"expected memory with 12-bit signed offset and multiple of 4");
6159
case Match_MemSImm10Lsl3:
6160
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6161
"expected memory with 13-bit signed offset and multiple of 8");
6162
case Match_MemSImm11:
6163
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6164
"expected memory with 11-bit signed offset");
6165
case Match_MemSImm12:
6166
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6167
"expected memory with 12-bit signed offset");
6168
case Match_MemSImm16:
6169
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6170
"expected memory with 16-bit signed offset");
6171
case Match_MemSImmPtr:
6172
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6173
"expected memory with 32-bit signed offset");
6174
case Match_RequiresPosSizeRange0_32: {
6175
SMLoc ErrorStart = Operands[3]->getStartLoc();
6176
SMLoc ErrorEnd = Operands[4]->getEndLoc();
6177
return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6178
SMRange(ErrorStart, ErrorEnd));
6179
}
6180
case Match_RequiresPosSizeUImm6: {
6181
SMLoc ErrorStart = Operands[3]->getStartLoc();
6182
SMLoc ErrorEnd = Operands[4]->getEndLoc();
6183
return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6184
SMRange(ErrorStart, ErrorEnd));
6185
}
6186
case Match_RequiresPosSizeRange33_64: {
6187
SMLoc ErrorStart = Operands[3]->getStartLoc();
6188
SMLoc ErrorEnd = Operands[4]->getEndLoc();
6189
return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6190
SMRange(ErrorStart, ErrorEnd));
6191
}
6192
}
6193
6194
llvm_unreachable("Implement any new match types added!");
6195
}
6196
6197
void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
6198
if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6199
Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
6200
") without \".set noat\"");
6201
}
6202
6203
void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6204
if (!AssemblerOptions.back()->isMacro())
6205
Warning(Loc, "macro instruction expanded into multiple instructions");
6206
}
6207
6208
void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6209
const OperandVector &Operands) {
6210
assert(
6211
(Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
6212
"Unexpected instruction!");
6213
((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6214
int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6215
Inst.addOperand(MCOperand::createReg(NextReg));
6216
((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6217
}
6218
6219
void
6220
MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6221
SMRange Range, bool ShowColors) {
6222
getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6223
Range, SMFixIt(Range, FixMsg),
6224
ShowColors);
6225
}
6226
6227
int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6228
int CC;
6229
6230
CC = StringSwitch<unsigned>(Name)
6231
.Case("zero", 0)
6232
.Cases("at", "AT", 1)
6233
.Case("a0", 4)
6234
.Case("a1", 5)
6235
.Case("a2", 6)
6236
.Case("a3", 7)
6237
.Case("v0", 2)
6238
.Case("v1", 3)
6239
.Case("s0", 16)
6240
.Case("s1", 17)
6241
.Case("s2", 18)
6242
.Case("s3", 19)
6243
.Case("s4", 20)
6244
.Case("s5", 21)
6245
.Case("s6", 22)
6246
.Case("s7", 23)
6247
.Case("k0", 26)
6248
.Case("k1", 27)
6249
.Case("gp", 28)
6250
.Case("sp", 29)
6251
.Case("fp", 30)
6252
.Case("s8", 30)
6253
.Case("ra", 31)
6254
.Case("t0", 8)
6255
.Case("t1", 9)
6256
.Case("t2", 10)
6257
.Case("t3", 11)
6258
.Case("t4", 12)
6259
.Case("t5", 13)
6260
.Case("t6", 14)
6261
.Case("t7", 15)
6262
.Case("t8", 24)
6263
.Case("t9", 25)
6264
.Default(-1);
6265
6266
if (!(isABI_N32() || isABI_N64()))
6267
return CC;
6268
6269
if (12 <= CC && CC <= 15) {
6270
// Name is one of t4-t7
6271
AsmToken RegTok = getLexer().peekTok();
6272
SMRange RegRange = RegTok.getLocRange();
6273
6274
StringRef FixedName = StringSwitch<StringRef>(Name)
6275
.Case("t4", "t0")
6276
.Case("t5", "t1")
6277
.Case("t6", "t2")
6278
.Case("t7", "t3")
6279
.Default("");
6280
assert(FixedName != "" && "Register name is not one of t4-t7.");
6281
6282
printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6283
"Did you mean $" + FixedName + "?", RegRange);
6284
}
6285
6286
// Although SGI documentation just cuts out t0-t3 for n32/n64,
6287
// GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
6288
// We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
6289
if (8 <= CC && CC <= 11)
6290
CC += 4;
6291
6292
if (CC == -1)
6293
CC = StringSwitch<unsigned>(Name)
6294
.Case("a4", 8)
6295
.Case("a5", 9)
6296
.Case("a6", 10)
6297
.Case("a7", 11)
6298
.Case("kt0", 26)
6299
.Case("kt1", 27)
6300
.Default(-1);
6301
6302
return CC;
6303
}
6304
6305
int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6306
int CC;
6307
6308
CC = StringSwitch<unsigned>(Name)
6309
.Case("hwr_cpunum", 0)
6310
.Case("hwr_synci_step", 1)
6311
.Case("hwr_cc", 2)
6312
.Case("hwr_ccres", 3)
6313
.Case("hwr_ulr", 29)
6314
.Default(-1);
6315
6316
return CC;
6317
}
6318
6319
int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6320
if (Name[0] == 'f') {
6321
StringRef NumString = Name.substr(1);
6322
unsigned IntVal;
6323
if (NumString.getAsInteger(10, IntVal))
6324
return -1; // This is not an integer.
6325
if (IntVal > 31) // Maximum index for fpu register.
6326
return -1;
6327
return IntVal;
6328
}
6329
return -1;
6330
}
6331
6332
int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6333
if (Name.starts_with("fcc")) {
6334
StringRef NumString = Name.substr(3);
6335
unsigned IntVal;
6336
if (NumString.getAsInteger(10, IntVal))
6337
return -1; // This is not an integer.
6338
if (IntVal > 7) // There are only 8 fcc registers.
6339
return -1;
6340
return IntVal;
6341
}
6342
return -1;
6343
}
6344
6345
int MipsAsmParser::matchACRegisterName(StringRef Name) {
6346
if (Name.starts_with("ac")) {
6347
StringRef NumString = Name.substr(2);
6348
unsigned IntVal;
6349
if (NumString.getAsInteger(10, IntVal))
6350
return -1; // This is not an integer.
6351
if (IntVal > 3) // There are only 3 acc registers.
6352
return -1;
6353
return IntVal;
6354
}
6355
return -1;
6356
}
6357
6358
int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6359
unsigned IntVal;
6360
6361
if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6362
return -1;
6363
6364
if (IntVal > 31)
6365
return -1;
6366
6367
return IntVal;
6368
}
6369
6370
int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6371
int CC;
6372
6373
CC = StringSwitch<unsigned>(Name)
6374
.Case("msair", 0)
6375
.Case("msacsr", 1)
6376
.Case("msaaccess", 2)
6377
.Case("msasave", 3)
6378
.Case("msamodify", 4)
6379
.Case("msarequest", 5)
6380
.Case("msamap", 6)
6381
.Case("msaunmap", 7)
6382
.Default(-1);
6383
6384
return CC;
6385
}
6386
6387
bool MipsAsmParser::canUseATReg() {
6388
return AssemblerOptions.back()->getATRegIndex() != 0;
6389
}
6390
6391
unsigned MipsAsmParser::getATReg(SMLoc Loc) {
6392
unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6393
if (ATIndex == 0) {
6394
reportParseError(Loc,
6395
"pseudo-instruction requires $at, which is not available");
6396
return 0;
6397
}
6398
unsigned AT = getReg(
6399
(isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6400
return AT;
6401
}
6402
6403
unsigned MipsAsmParser::getReg(int RC, int RegNo) {
6404
return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6405
}
6406
6407
bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6408
MCAsmParser &Parser = getParser();
6409
LLVM_DEBUG(dbgs() << "parseOperand\n");
6410
6411
// Check if the current operand has a custom associated parser, if so, try to
6412
// custom parse the operand, or fallback to the general approach.
6413
ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
6414
if (Res.isSuccess())
6415
return false;
6416
// If there wasn't a custom match, try the generic matcher below. Otherwise,
6417
// there was a match, but an error occurred, in which case, just return that
6418
// the operand parsing failed.
6419
if (Res.isFailure())
6420
return true;
6421
6422
LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6423
6424
switch (getLexer().getKind()) {
6425
case AsmToken::Dollar: {
6426
// Parse the register.
6427
SMLoc S = Parser.getTok().getLoc();
6428
6429
// Almost all registers have been parsed by custom parsers. There is only
6430
// one exception to this. $zero (and it's alias $0) will reach this point
6431
// for div, divu, and similar instructions because it is not an operand
6432
// to the instruction definition but an explicit register. Special case
6433
// this situation for now.
6434
if (!parseAnyRegister(Operands).isNoMatch())
6435
return false;
6436
6437
// Maybe it is a symbol reference.
6438
StringRef Identifier;
6439
if (Parser.parseIdentifier(Identifier))
6440
return true;
6441
6442
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6443
MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
6444
// Otherwise create a symbol reference.
6445
const MCExpr *SymRef =
6446
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
6447
6448
Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this));
6449
return false;
6450
}
6451
default: {
6452
LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6453
6454
const MCExpr *Expr;
6455
SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6456
if (getParser().parseExpression(Expr))
6457
return true;
6458
6459
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6460
6461
Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6462
return false;
6463
}
6464
} // switch(getLexer().getKind())
6465
return true;
6466
}
6467
6468
bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
6469
SMLoc &EndLoc) {
6470
return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6471
}
6472
6473
ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6474
SMLoc &EndLoc) {
6475
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6476
ParseStatus Res = parseAnyRegister(Operands);
6477
if (Res.isSuccess()) {
6478
assert(Operands.size() == 1);
6479
MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6480
StartLoc = Operand.getStartLoc();
6481
EndLoc = Operand.getEndLoc();
6482
6483
// AFAIK, we only support numeric registers and named GPR's in CFI
6484
// directives.
6485
// Don't worry about eating tokens before failing. Using an unrecognised
6486
// register is a parse error.
6487
if (Operand.isGPRAsmReg()) {
6488
// Resolve to GPR32 or GPR64 appropriately.
6489
Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6490
}
6491
6492
return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6493
}
6494
6495
assert(Operands.size() == 0);
6496
return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6497
}
6498
6499
bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
6500
SMLoc S;
6501
6502
if (isParenExpr)
6503
return getParser().parseParenExprOfDepth(0, Res, S);
6504
return getParser().parseExpression(Res);
6505
}
6506
6507
ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6508
MCAsmParser &Parser = getParser();
6509
LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6510
const MCExpr *IdVal = nullptr;
6511
SMLoc S;
6512
bool isParenExpr = false;
6513
ParseStatus Res = ParseStatus::NoMatch;
6514
// First operand is the offset.
6515
S = Parser.getTok().getLoc();
6516
6517
if (getLexer().getKind() == AsmToken::LParen) {
6518
Parser.Lex();
6519
isParenExpr = true;
6520
}
6521
6522
if (getLexer().getKind() != AsmToken::Dollar) {
6523
if (parseMemOffset(IdVal, isParenExpr))
6524
return ParseStatus::Failure;
6525
6526
const AsmToken &Tok = Parser.getTok(); // Get the next token.
6527
if (Tok.isNot(AsmToken::LParen)) {
6528
MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6529
if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6530
SMLoc E =
6531
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6532
Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6533
return ParseStatus::Success;
6534
}
6535
if (Tok.is(AsmToken::EndOfStatement)) {
6536
SMLoc E =
6537
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6538
6539
// Zero register assumed, add a memory operand with ZERO as its base.
6540
// "Base" will be managed by k_Memory.
6541
auto Base = MipsOperand::createGPRReg(
6542
0, "0", getContext().getRegisterInfo(), S, E, *this);
6543
Operands.push_back(
6544
MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6545
return ParseStatus::Success;
6546
}
6547
MCBinaryExpr::Opcode Opcode;
6548
// GAS and LLVM treat comparison operators different. GAS will generate -1
6549
// or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6550
// highly unlikely to be found in a memory offset expression, we don't
6551
// handle them.
6552
switch (Tok.getKind()) {
6553
case AsmToken::Plus:
6554
Opcode = MCBinaryExpr::Add;
6555
Parser.Lex();
6556
break;
6557
case AsmToken::Minus:
6558
Opcode = MCBinaryExpr::Sub;
6559
Parser.Lex();
6560
break;
6561
case AsmToken::Star:
6562
Opcode = MCBinaryExpr::Mul;
6563
Parser.Lex();
6564
break;
6565
case AsmToken::Pipe:
6566
Opcode = MCBinaryExpr::Or;
6567
Parser.Lex();
6568
break;
6569
case AsmToken::Amp:
6570
Opcode = MCBinaryExpr::And;
6571
Parser.Lex();
6572
break;
6573
case AsmToken::LessLess:
6574
Opcode = MCBinaryExpr::Shl;
6575
Parser.Lex();
6576
break;
6577
case AsmToken::GreaterGreater:
6578
Opcode = MCBinaryExpr::LShr;
6579
Parser.Lex();
6580
break;
6581
case AsmToken::Caret:
6582
Opcode = MCBinaryExpr::Xor;
6583
Parser.Lex();
6584
break;
6585
case AsmToken::Slash:
6586
Opcode = MCBinaryExpr::Div;
6587
Parser.Lex();
6588
break;
6589
case AsmToken::Percent:
6590
Opcode = MCBinaryExpr::Mod;
6591
Parser.Lex();
6592
break;
6593
default:
6594
return Error(Parser.getTok().getLoc(), "'(' or expression expected");
6595
}
6596
const MCExpr * NextExpr;
6597
if (getParser().parseExpression(NextExpr))
6598
return ParseStatus::Failure;
6599
IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6600
}
6601
6602
Parser.Lex(); // Eat the '(' token.
6603
}
6604
6605
Res = parseAnyRegister(Operands);
6606
if (!Res.isSuccess())
6607
return Res;
6608
6609
if (Parser.getTok().isNot(AsmToken::RParen))
6610
return Error(Parser.getTok().getLoc(), "')' expected");
6611
6612
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6613
6614
Parser.Lex(); // Eat the ')' token.
6615
6616
if (!IdVal)
6617
IdVal = MCConstantExpr::create(0, getContext());
6618
6619
// Replace the register operand with the memory operand.
6620
std::unique_ptr<MipsOperand> op(
6621
static_cast<MipsOperand *>(Operands.back().release()));
6622
// Remove the register from the operands.
6623
// "op" will be managed by k_Memory.
6624
Operands.pop_back();
6625
// Add the memory operand.
6626
if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6627
int64_t Imm;
6628
if (IdVal->evaluateAsAbsolute(Imm))
6629
IdVal = MCConstantExpr::create(Imm, getContext());
6630
else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6631
IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6632
getContext());
6633
}
6634
6635
Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6636
return ParseStatus::Success;
6637
}
6638
6639
bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6640
MCAsmParser &Parser = getParser();
6641
MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6642
if (!Sym)
6643
return false;
6644
6645
SMLoc S = Parser.getTok().getLoc();
6646
if (Sym->isVariable()) {
6647
const MCExpr *Expr = Sym->getVariableValue();
6648
if (Expr->getKind() == MCExpr::SymbolRef) {
6649
const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6650
StringRef DefSymbol = Ref->getSymbol().getName();
6651
if (DefSymbol.starts_with("$")) {
6652
ParseStatus Res =
6653
matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6654
if (Res.isSuccess()) {
6655
Parser.Lex();
6656
return true;
6657
}
6658
if (Res.isFailure())
6659
llvm_unreachable("Should never fail");
6660
}
6661
}
6662
} else if (Sym->isUnset()) {
6663
// If symbol is unset, it might be created in the `parseSetAssignment`
6664
// routine as an alias for a numeric register name.
6665
// Lookup in the aliases list.
6666
auto Entry = RegisterSets.find(Sym->getName());
6667
if (Entry != RegisterSets.end()) {
6668
ParseStatus Res =
6669
matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6670
if (Res.isSuccess()) {
6671
Parser.Lex();
6672
return true;
6673
}
6674
}
6675
}
6676
6677
return false;
6678
}
6679
6680
ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6681
OperandVector &Operands, StringRef Identifier, SMLoc S) {
6682
int Index = matchCPURegisterName(Identifier);
6683
if (Index != -1) {
6684
Operands.push_back(MipsOperand::createGPRReg(
6685
Index, Identifier, getContext().getRegisterInfo(), S,
6686
getLexer().getLoc(), *this));
6687
return ParseStatus::Success;
6688
}
6689
6690
Index = matchHWRegsRegisterName(Identifier);
6691
if (Index != -1) {
6692
Operands.push_back(MipsOperand::createHWRegsReg(
6693
Index, Identifier, getContext().getRegisterInfo(), S,
6694
getLexer().getLoc(), *this));
6695
return ParseStatus::Success;
6696
}
6697
6698
Index = matchFPURegisterName(Identifier);
6699
if (Index != -1) {
6700
Operands.push_back(MipsOperand::createFGRReg(
6701
Index, Identifier, getContext().getRegisterInfo(), S,
6702
getLexer().getLoc(), *this));
6703
return ParseStatus::Success;
6704
}
6705
6706
Index = matchFCCRegisterName(Identifier);
6707
if (Index != -1) {
6708
Operands.push_back(MipsOperand::createFCCReg(
6709
Index, Identifier, getContext().getRegisterInfo(), S,
6710
getLexer().getLoc(), *this));
6711
return ParseStatus::Success;
6712
}
6713
6714
Index = matchACRegisterName(Identifier);
6715
if (Index != -1) {
6716
Operands.push_back(MipsOperand::createACCReg(
6717
Index, Identifier, getContext().getRegisterInfo(), S,
6718
getLexer().getLoc(), *this));
6719
return ParseStatus::Success;
6720
}
6721
6722
Index = matchMSA128RegisterName(Identifier);
6723
if (Index != -1) {
6724
Operands.push_back(MipsOperand::createMSA128Reg(
6725
Index, Identifier, getContext().getRegisterInfo(), S,
6726
getLexer().getLoc(), *this));
6727
return ParseStatus::Success;
6728
}
6729
6730
Index = matchMSA128CtrlRegisterName(Identifier);
6731
if (Index != -1) {
6732
Operands.push_back(MipsOperand::createMSACtrlReg(
6733
Index, Identifier, getContext().getRegisterInfo(), S,
6734
getLexer().getLoc(), *this));
6735
return ParseStatus::Success;
6736
}
6737
6738
return ParseStatus::NoMatch;
6739
}
6740
6741
ParseStatus
6742
MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6743
const AsmToken &Token, SMLoc S) {
6744
if (Token.is(AsmToken::Identifier)) {
6745
LLVM_DEBUG(dbgs() << ".. identifier\n");
6746
StringRef Identifier = Token.getIdentifier();
6747
return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6748
}
6749
if (Token.is(AsmToken::Integer)) {
6750
LLVM_DEBUG(dbgs() << ".. integer\n");
6751
int64_t RegNum = Token.getIntVal();
6752
if (RegNum < 0 || RegNum > 31) {
6753
// Show the error, but treat invalid register
6754
// number as a normal one to continue parsing
6755
// and catch other possible errors.
6756
Error(getLexer().getLoc(), "invalid register number");
6757
}
6758
Operands.push_back(MipsOperand::createNumericReg(
6759
RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6760
Token.getLoc(), *this));
6761
return ParseStatus::Success;
6762
}
6763
6764
LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6765
6766
return ParseStatus::NoMatch;
6767
}
6768
6769
ParseStatus
6770
MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6771
auto Token = getLexer().peekTok(false);
6772
return matchAnyRegisterWithoutDollar(Operands, Token, S);
6773
}
6774
6775
ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6776
MCAsmParser &Parser = getParser();
6777
LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6778
6779
auto Token = Parser.getTok();
6780
6781
SMLoc S = Token.getLoc();
6782
6783
if (Token.isNot(AsmToken::Dollar)) {
6784
LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6785
if (Token.is(AsmToken::Identifier)) {
6786
if (searchSymbolAlias(Operands))
6787
return ParseStatus::Success;
6788
}
6789
LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6790
return ParseStatus::NoMatch;
6791
}
6792
LLVM_DEBUG(dbgs() << ".. $\n");
6793
6794
ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6795
if (Res.isSuccess()) {
6796
Parser.Lex(); // $
6797
Parser.Lex(); // identifier
6798
}
6799
return Res;
6800
}
6801
6802
ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6803
MCAsmParser &Parser = getParser();
6804
LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6805
6806
SMLoc S = getLexer().getLoc();
6807
6808
// Registers are a valid target and have priority over symbols.
6809
ParseStatus Res = parseAnyRegister(Operands);
6810
if (!Res.isNoMatch())
6811
return Res;
6812
6813
// Integers and expressions are acceptable
6814
const MCExpr *Expr = nullptr;
6815
if (Parser.parseExpression(Expr)) {
6816
// We have no way of knowing if a symbol was consumed so we must ParseFail
6817
return ParseStatus::Failure;
6818
}
6819
Operands.push_back(
6820
MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6821
return ParseStatus::Success;
6822
}
6823
6824
ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) {
6825
MCAsmParser &Parser = getParser();
6826
const MCExpr *IdVal;
6827
// If the first token is '$' we may have register operand. We have to reject
6828
// cases where it is not a register. Complicating the matter is that
6829
// register names are not reserved across all ABIs.
6830
// Peek past the dollar to see if it's a register name for this ABI.
6831
SMLoc S = Parser.getTok().getLoc();
6832
if (Parser.getTok().is(AsmToken::Dollar)) {
6833
return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6834
? ParseStatus::Failure
6835
: ParseStatus::NoMatch;
6836
}
6837
if (getParser().parseExpression(IdVal))
6838
return ParseStatus::Failure;
6839
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6840
if (!MCE)
6841
return ParseStatus::NoMatch;
6842
int64_t Val = MCE->getValue();
6843
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6844
Operands.push_back(MipsOperand::CreateImm(
6845
MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6846
return ParseStatus::Success;
6847
}
6848
6849
ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6850
MCAsmParser &Parser = getParser();
6851
SmallVector<unsigned, 10> Regs;
6852
unsigned RegNo;
6853
unsigned PrevReg = Mips::NoRegister;
6854
bool RegRange = false;
6855
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6856
6857
if (Parser.getTok().isNot(AsmToken::Dollar))
6858
return ParseStatus::Failure;
6859
6860
SMLoc S = Parser.getTok().getLoc();
6861
while (parseAnyRegister(TmpOperands).isSuccess()) {
6862
SMLoc E = getLexer().getLoc();
6863
MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6864
RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6865
if (RegRange) {
6866
// Remove last register operand because registers from register range
6867
// should be inserted first.
6868
if ((isGP64bit() && RegNo == Mips::RA_64) ||
6869
(!isGP64bit() && RegNo == Mips::RA)) {
6870
Regs.push_back(RegNo);
6871
} else {
6872
unsigned TmpReg = PrevReg + 1;
6873
while (TmpReg <= RegNo) {
6874
if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6875
(((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6876
isGP64bit()))
6877
return Error(E, "invalid register operand");
6878
6879
PrevReg = TmpReg;
6880
Regs.push_back(TmpReg++);
6881
}
6882
}
6883
6884
RegRange = false;
6885
} else {
6886
if ((PrevReg == Mips::NoRegister) &&
6887
((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6888
(!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6889
return Error(E, "$16 or $31 expected");
6890
if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6891
(RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6892
!isGP64bit()) ||
6893
((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6894
(RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6895
isGP64bit())))
6896
return Error(E, "invalid register operand");
6897
if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6898
((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6899
(RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6900
return Error(E, "consecutive register numbers expected");
6901
6902
Regs.push_back(RegNo);
6903
}
6904
6905
if (Parser.getTok().is(AsmToken::Minus))
6906
RegRange = true;
6907
6908
if (!Parser.getTok().isNot(AsmToken::Minus) &&
6909
!Parser.getTok().isNot(AsmToken::Comma))
6910
return Error(E, "',' or '-' expected");
6911
6912
Lex(); // Consume comma or minus
6913
if (Parser.getTok().isNot(AsmToken::Dollar))
6914
break;
6915
6916
PrevReg = RegNo;
6917
}
6918
6919
SMLoc E = Parser.getTok().getLoc();
6920
Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6921
parseMemOperand(Operands);
6922
return ParseStatus::Success;
6923
}
6924
6925
/// Sometimes (i.e. load/stores) the operand may be followed immediately by
6926
/// either this.
6927
/// ::= '(', register, ')'
6928
/// handle it before we iterate so we don't get tripped up by the lack of
6929
/// a comma.
6930
bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6931
MCAsmParser &Parser = getParser();
6932
if (getLexer().is(AsmToken::LParen)) {
6933
Operands.push_back(
6934
MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6935
Parser.Lex();
6936
if (parseOperand(Operands, Name)) {
6937
SMLoc Loc = getLexer().getLoc();
6938
return Error(Loc, "unexpected token in argument list");
6939
}
6940
if (Parser.getTok().isNot(AsmToken::RParen)) {
6941
SMLoc Loc = getLexer().getLoc();
6942
return Error(Loc, "unexpected token, expected ')'");
6943
}
6944
Operands.push_back(
6945
MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6946
Parser.Lex();
6947
}
6948
return false;
6949
}
6950
6951
/// Sometimes (i.e. in MSA) the operand may be followed immediately by
6952
/// either one of these.
6953
/// ::= '[', register, ']'
6954
/// ::= '[', integer, ']'
6955
/// handle it before we iterate so we don't get tripped up by the lack of
6956
/// a comma.
6957
bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6958
OperandVector &Operands) {
6959
MCAsmParser &Parser = getParser();
6960
if (getLexer().is(AsmToken::LBrac)) {
6961
Operands.push_back(
6962
MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6963
Parser.Lex();
6964
if (parseOperand(Operands, Name)) {
6965
SMLoc Loc = getLexer().getLoc();
6966
return Error(Loc, "unexpected token in argument list");
6967
}
6968
if (Parser.getTok().isNot(AsmToken::RBrac)) {
6969
SMLoc Loc = getLexer().getLoc();
6970
return Error(Loc, "unexpected token, expected ']'");
6971
}
6972
Operands.push_back(
6973
MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6974
Parser.Lex();
6975
}
6976
return false;
6977
}
6978
6979
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6980
unsigned VariantID = 0);
6981
6982
bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6983
const MCParsedAsmOperand &Op2) const {
6984
// This target-overriden function exists to maintain current behaviour for
6985
// e.g.
6986
// dahi $3, $3, 0x5678
6987
// as tested in test/MC/Mips/mips64r6/valid.s.
6988
// FIXME: Should this test actually fail with an error? If so, then remove
6989
// this overloaded method.
6990
if (!Op1.isReg() || !Op2.isReg())
6991
return true;
6992
return Op1.getReg() == Op2.getReg();
6993
}
6994
6995
bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6996
SMLoc NameLoc, OperandVector &Operands) {
6997
MCAsmParser &Parser = getParser();
6998
LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6999
7000
// We have reached first instruction, module directive are now forbidden.
7001
getTargetStreamer().forbidModuleDirective();
7002
7003
// Check if we have valid mnemonic
7004
if (!mnemonicIsValid(Name, 0)) {
7005
FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7006
std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
7007
return Error(NameLoc, "unknown instruction" + Suggestion);
7008
}
7009
// First operand in MCInst is instruction mnemonic.
7010
Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
7011
7012
// Read the remaining operands.
7013
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7014
// Read the first operand.
7015
if (parseOperand(Operands, Name)) {
7016
SMLoc Loc = getLexer().getLoc();
7017
return Error(Loc, "unexpected token in argument list");
7018
}
7019
if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7020
return true;
7021
// AFAIK, parenthesis suffixes are never on the first operand
7022
7023
while (getLexer().is(AsmToken::Comma)) {
7024
Parser.Lex(); // Eat the comma.
7025
// Parse and remember the operand.
7026
if (parseOperand(Operands, Name)) {
7027
SMLoc Loc = getLexer().getLoc();
7028
return Error(Loc, "unexpected token in argument list");
7029
}
7030
// Parse bracket and parenthesis suffixes before we iterate
7031
if (getLexer().is(AsmToken::LBrac)) {
7032
if (parseBracketSuffix(Name, Operands))
7033
return true;
7034
} else if (getLexer().is(AsmToken::LParen) &&
7035
parseParenSuffix(Name, Operands))
7036
return true;
7037
}
7038
}
7039
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7040
SMLoc Loc = getLexer().getLoc();
7041
return Error(Loc, "unexpected token in argument list");
7042
}
7043
Parser.Lex(); // Consume the EndOfStatement.
7044
return false;
7045
}
7046
7047
// FIXME: Given that these have the same name, these should both be
7048
// consistent on affecting the Parser.
7049
bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
7050
SMLoc Loc = getLexer().getLoc();
7051
return Error(Loc, ErrorMsg);
7052
}
7053
7054
bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
7055
return Error(Loc, ErrorMsg);
7056
}
7057
7058
bool MipsAsmParser::parseSetNoAtDirective() {
7059
MCAsmParser &Parser = getParser();
7060
// Line should look like: ".set noat".
7061
7062
// Set the $at register to $0.
7063
AssemblerOptions.back()->setATRegIndex(0);
7064
7065
Parser.Lex(); // Eat "noat".
7066
7067
// If this is not the end of the statement, report an error.
7068
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7069
reportParseError("unexpected token, expected end of statement");
7070
return false;
7071
}
7072
7073
getTargetStreamer().emitDirectiveSetNoAt();
7074
Parser.Lex(); // Consume the EndOfStatement.
7075
return false;
7076
}
7077
7078
bool MipsAsmParser::parseSetAtDirective() {
7079
// Line can be: ".set at", which sets $at to $1
7080
// or ".set at=$reg", which sets $at to $reg.
7081
MCAsmParser &Parser = getParser();
7082
Parser.Lex(); // Eat "at".
7083
7084
if (getLexer().is(AsmToken::EndOfStatement)) {
7085
// No register was specified, so we set $at to $1.
7086
AssemblerOptions.back()->setATRegIndex(1);
7087
7088
getTargetStreamer().emitDirectiveSetAt();
7089
Parser.Lex(); // Consume the EndOfStatement.
7090
return false;
7091
}
7092
7093
if (getLexer().isNot(AsmToken::Equal)) {
7094
reportParseError("unexpected token, expected equals sign");
7095
return false;
7096
}
7097
Parser.Lex(); // Eat "=".
7098
7099
if (getLexer().isNot(AsmToken::Dollar)) {
7100
if (getLexer().is(AsmToken::EndOfStatement)) {
7101
reportParseError("no register specified");
7102
return false;
7103
} else {
7104
reportParseError("unexpected token, expected dollar sign '$'");
7105
return false;
7106
}
7107
}
7108
Parser.Lex(); // Eat "$".
7109
7110
// Find out what "reg" is.
7111
unsigned AtRegNo;
7112
const AsmToken &Reg = Parser.getTok();
7113
if (Reg.is(AsmToken::Identifier)) {
7114
AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7115
} else if (Reg.is(AsmToken::Integer)) {
7116
AtRegNo = Reg.getIntVal();
7117
} else {
7118
reportParseError("unexpected token, expected identifier or integer");
7119
return false;
7120
}
7121
7122
// Check if $reg is a valid register. If it is, set $at to $reg.
7123
if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7124
reportParseError("invalid register");
7125
return false;
7126
}
7127
Parser.Lex(); // Eat "reg".
7128
7129
// If this is not the end of the statement, report an error.
7130
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7131
reportParseError("unexpected token, expected end of statement");
7132
return false;
7133
}
7134
7135
getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7136
7137
Parser.Lex(); // Consume the EndOfStatement.
7138
return false;
7139
}
7140
7141
bool MipsAsmParser::parseSetReorderDirective() {
7142
MCAsmParser &Parser = getParser();
7143
Parser.Lex();
7144
// If this is not the end of the statement, report an error.
7145
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7146
reportParseError("unexpected token, expected end of statement");
7147
return false;
7148
}
7149
AssemblerOptions.back()->setReorder();
7150
getTargetStreamer().emitDirectiveSetReorder();
7151
Parser.Lex(); // Consume the EndOfStatement.
7152
return false;
7153
}
7154
7155
bool MipsAsmParser::parseSetNoReorderDirective() {
7156
MCAsmParser &Parser = getParser();
7157
Parser.Lex();
7158
// If this is not the end of the statement, report an error.
7159
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7160
reportParseError("unexpected token, expected end of statement");
7161
return false;
7162
}
7163
AssemblerOptions.back()->setNoReorder();
7164
getTargetStreamer().emitDirectiveSetNoReorder();
7165
Parser.Lex(); // Consume the EndOfStatement.
7166
return false;
7167
}
7168
7169
bool MipsAsmParser::parseSetMacroDirective() {
7170
MCAsmParser &Parser = getParser();
7171
Parser.Lex();
7172
// If this is not the end of the statement, report an error.
7173
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7174
reportParseError("unexpected token, expected end of statement");
7175
return false;
7176
}
7177
AssemblerOptions.back()->setMacro();
7178
getTargetStreamer().emitDirectiveSetMacro();
7179
Parser.Lex(); // Consume the EndOfStatement.
7180
return false;
7181
}
7182
7183
bool MipsAsmParser::parseSetNoMacroDirective() {
7184
MCAsmParser &Parser = getParser();
7185
Parser.Lex();
7186
// If this is not the end of the statement, report an error.
7187
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7188
reportParseError("unexpected token, expected end of statement");
7189
return false;
7190
}
7191
if (AssemblerOptions.back()->isReorder()) {
7192
reportParseError("`noreorder' must be set before `nomacro'");
7193
return false;
7194
}
7195
AssemblerOptions.back()->setNoMacro();
7196
getTargetStreamer().emitDirectiveSetNoMacro();
7197
Parser.Lex(); // Consume the EndOfStatement.
7198
return false;
7199
}
7200
7201
bool MipsAsmParser::parseSetMsaDirective() {
7202
MCAsmParser &Parser = getParser();
7203
Parser.Lex();
7204
7205
// If this is not the end of the statement, report an error.
7206
if (getLexer().isNot(AsmToken::EndOfStatement))
7207
return reportParseError("unexpected token, expected end of statement");
7208
7209
setFeatureBits(Mips::FeatureMSA, "msa");
7210
getTargetStreamer().emitDirectiveSetMsa();
7211
return false;
7212
}
7213
7214
bool MipsAsmParser::parseSetNoMsaDirective() {
7215
MCAsmParser &Parser = getParser();
7216
Parser.Lex();
7217
7218
// If this is not the end of the statement, report an error.
7219
if (getLexer().isNot(AsmToken::EndOfStatement))
7220
return reportParseError("unexpected token, expected end of statement");
7221
7222
clearFeatureBits(Mips::FeatureMSA, "msa");
7223
getTargetStreamer().emitDirectiveSetNoMsa();
7224
return false;
7225
}
7226
7227
bool MipsAsmParser::parseSetNoDspDirective() {
7228
MCAsmParser &Parser = getParser();
7229
Parser.Lex(); // Eat "nodsp".
7230
7231
// If this is not the end of the statement, report an error.
7232
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7233
reportParseError("unexpected token, expected end of statement");
7234
return false;
7235
}
7236
7237
clearFeatureBits(Mips::FeatureDSP, "dsp");
7238
getTargetStreamer().emitDirectiveSetNoDsp();
7239
return false;
7240
}
7241
7242
bool MipsAsmParser::parseSetNoMips3DDirective() {
7243
MCAsmParser &Parser = getParser();
7244
Parser.Lex(); // Eat "nomips3d".
7245
7246
// If this is not the end of the statement, report an error.
7247
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7248
reportParseError("unexpected token, expected end of statement");
7249
return false;
7250
}
7251
7252
clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7253
getTargetStreamer().emitDirectiveSetNoMips3D();
7254
return false;
7255
}
7256
7257
bool MipsAsmParser::parseSetMips16Directive() {
7258
MCAsmParser &Parser = getParser();
7259
Parser.Lex(); // Eat "mips16".
7260
7261
// If this is not the end of the statement, report an error.
7262
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7263
reportParseError("unexpected token, expected end of statement");
7264
return false;
7265
}
7266
7267
setFeatureBits(Mips::FeatureMips16, "mips16");
7268
getTargetStreamer().emitDirectiveSetMips16();
7269
Parser.Lex(); // Consume the EndOfStatement.
7270
return false;
7271
}
7272
7273
bool MipsAsmParser::parseSetNoMips16Directive() {
7274
MCAsmParser &Parser = getParser();
7275
Parser.Lex(); // Eat "nomips16".
7276
7277
// If this is not the end of the statement, report an error.
7278
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7279
reportParseError("unexpected token, expected end of statement");
7280
return false;
7281
}
7282
7283
clearFeatureBits(Mips::FeatureMips16, "mips16");
7284
getTargetStreamer().emitDirectiveSetNoMips16();
7285
Parser.Lex(); // Consume the EndOfStatement.
7286
return false;
7287
}
7288
7289
bool MipsAsmParser::parseSetFpDirective() {
7290
MCAsmParser &Parser = getParser();
7291
MipsABIFlagsSection::FpABIKind FpAbiVal;
7292
// Line can be: .set fp=32
7293
// .set fp=xx
7294
// .set fp=64
7295
Parser.Lex(); // Eat fp token
7296
AsmToken Tok = Parser.getTok();
7297
if (Tok.isNot(AsmToken::Equal)) {
7298
reportParseError("unexpected token, expected equals sign '='");
7299
return false;
7300
}
7301
Parser.Lex(); // Eat '=' token.
7302
Tok = Parser.getTok();
7303
7304
if (!parseFpABIValue(FpAbiVal, ".set"))
7305
return false;
7306
7307
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7308
reportParseError("unexpected token, expected end of statement");
7309
return false;
7310
}
7311
getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7312
Parser.Lex(); // Consume the EndOfStatement.
7313
return false;
7314
}
7315
7316
bool MipsAsmParser::parseSetOddSPRegDirective() {
7317
MCAsmParser &Parser = getParser();
7318
7319
Parser.Lex(); // Eat "oddspreg".
7320
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7321
reportParseError("unexpected token, expected end of statement");
7322
return false;
7323
}
7324
7325
clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7326
getTargetStreamer().emitDirectiveSetOddSPReg();
7327
return false;
7328
}
7329
7330
bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7331
MCAsmParser &Parser = getParser();
7332
7333
Parser.Lex(); // Eat "nooddspreg".
7334
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7335
reportParseError("unexpected token, expected end of statement");
7336
return false;
7337
}
7338
7339
setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7340
getTargetStreamer().emitDirectiveSetNoOddSPReg();
7341
return false;
7342
}
7343
7344
bool MipsAsmParser::parseSetMtDirective() {
7345
MCAsmParser &Parser = getParser();
7346
Parser.Lex(); // Eat "mt".
7347
7348
// If this is not the end of the statement, report an error.
7349
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7350
reportParseError("unexpected token, expected end of statement");
7351
return false;
7352
}
7353
7354
setFeatureBits(Mips::FeatureMT, "mt");
7355
getTargetStreamer().emitDirectiveSetMt();
7356
Parser.Lex(); // Consume the EndOfStatement.
7357
return false;
7358
}
7359
7360
bool MipsAsmParser::parseSetNoMtDirective() {
7361
MCAsmParser &Parser = getParser();
7362
Parser.Lex(); // Eat "nomt".
7363
7364
// If this is not the end of the statement, report an error.
7365
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7366
reportParseError("unexpected token, expected end of statement");
7367
return false;
7368
}
7369
7370
clearFeatureBits(Mips::FeatureMT, "mt");
7371
7372
getTargetStreamer().emitDirectiveSetNoMt();
7373
Parser.Lex(); // Consume the EndOfStatement.
7374
return false;
7375
}
7376
7377
bool MipsAsmParser::parseSetNoCRCDirective() {
7378
MCAsmParser &Parser = getParser();
7379
Parser.Lex(); // Eat "nocrc".
7380
7381
// If this is not the end of the statement, report an error.
7382
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7383
reportParseError("unexpected token, expected end of statement");
7384
return false;
7385
}
7386
7387
clearFeatureBits(Mips::FeatureCRC, "crc");
7388
7389
getTargetStreamer().emitDirectiveSetNoCRC();
7390
Parser.Lex(); // Consume the EndOfStatement.
7391
return false;
7392
}
7393
7394
bool MipsAsmParser::parseSetNoVirtDirective() {
7395
MCAsmParser &Parser = getParser();
7396
Parser.Lex(); // Eat "novirt".
7397
7398
// If this is not the end of the statement, report an error.
7399
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7400
reportParseError("unexpected token, expected end of statement");
7401
return false;
7402
}
7403
7404
clearFeatureBits(Mips::FeatureVirt, "virt");
7405
7406
getTargetStreamer().emitDirectiveSetNoVirt();
7407
Parser.Lex(); // Consume the EndOfStatement.
7408
return false;
7409
}
7410
7411
bool MipsAsmParser::parseSetNoGINVDirective() {
7412
MCAsmParser &Parser = getParser();
7413
Parser.Lex(); // Eat "noginv".
7414
7415
// If this is not the end of the statement, report an error.
7416
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7417
reportParseError("unexpected token, expected end of statement");
7418
return false;
7419
}
7420
7421
clearFeatureBits(Mips::FeatureGINV, "ginv");
7422
7423
getTargetStreamer().emitDirectiveSetNoGINV();
7424
Parser.Lex(); // Consume the EndOfStatement.
7425
return false;
7426
}
7427
7428
bool MipsAsmParser::parseSetPopDirective() {
7429
MCAsmParser &Parser = getParser();
7430
SMLoc Loc = getLexer().getLoc();
7431
7432
Parser.Lex();
7433
if (getLexer().isNot(AsmToken::EndOfStatement))
7434
return reportParseError("unexpected token, expected end of statement");
7435
7436
// Always keep an element on the options "stack" to prevent the user
7437
// from changing the initial options. This is how we remember them.
7438
if (AssemblerOptions.size() == 2)
7439
return reportParseError(Loc, ".set pop with no .set push");
7440
7441
MCSubtargetInfo &STI = copySTI();
7442
AssemblerOptions.pop_back();
7443
setAvailableFeatures(
7444
ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7445
STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7446
7447
getTargetStreamer().emitDirectiveSetPop();
7448
return false;
7449
}
7450
7451
bool MipsAsmParser::parseSetPushDirective() {
7452
MCAsmParser &Parser = getParser();
7453
Parser.Lex();
7454
if (getLexer().isNot(AsmToken::EndOfStatement))
7455
return reportParseError("unexpected token, expected end of statement");
7456
7457
// Create a copy of the current assembler options environment and push it.
7458
AssemblerOptions.push_back(
7459
std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7460
7461
getTargetStreamer().emitDirectiveSetPush();
7462
return false;
7463
}
7464
7465
bool MipsAsmParser::parseSetSoftFloatDirective() {
7466
MCAsmParser &Parser = getParser();
7467
Parser.Lex();
7468
if (getLexer().isNot(AsmToken::EndOfStatement))
7469
return reportParseError("unexpected token, expected end of statement");
7470
7471
setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7472
getTargetStreamer().emitDirectiveSetSoftFloat();
7473
return false;
7474
}
7475
7476
bool MipsAsmParser::parseSetHardFloatDirective() {
7477
MCAsmParser &Parser = getParser();
7478
Parser.Lex();
7479
if (getLexer().isNot(AsmToken::EndOfStatement))
7480
return reportParseError("unexpected token, expected end of statement");
7481
7482
clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7483
getTargetStreamer().emitDirectiveSetHardFloat();
7484
return false;
7485
}
7486
7487
bool MipsAsmParser::parseSetAssignment() {
7488
StringRef Name;
7489
MCAsmParser &Parser = getParser();
7490
7491
if (Parser.parseIdentifier(Name))
7492
return reportParseError("expected identifier after .set");
7493
7494
if (getLexer().isNot(AsmToken::Comma))
7495
return reportParseError("unexpected token, expected comma");
7496
Lex(); // Eat comma
7497
7498
if (getLexer().is(AsmToken::Dollar) &&
7499
getLexer().peekTok().is(AsmToken::Integer)) {
7500
// Parse assignment of a numeric register:
7501
// .set r1,$1
7502
Parser.Lex(); // Eat $.
7503
RegisterSets[Name] = Parser.getTok();
7504
Parser.Lex(); // Eat identifier.
7505
getContext().getOrCreateSymbol(Name);
7506
return false;
7507
}
7508
7509
MCSymbol *Sym;
7510
const MCExpr *Value;
7511
if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7512
Parser, Sym, Value))
7513
return true;
7514
Sym->setVariableValue(Value);
7515
7516
return false;
7517
}
7518
7519
bool MipsAsmParser::parseSetMips0Directive() {
7520
MCAsmParser &Parser = getParser();
7521
Parser.Lex();
7522
if (getLexer().isNot(AsmToken::EndOfStatement))
7523
return reportParseError("unexpected token, expected end of statement");
7524
7525
// Reset assembler options to their initial values.
7526
MCSubtargetInfo &STI = copySTI();
7527
setAvailableFeatures(
7528
ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7529
STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7530
AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7531
7532
getTargetStreamer().emitDirectiveSetMips0();
7533
return false;
7534
}
7535
7536
bool MipsAsmParser::parseSetArchDirective() {
7537
MCAsmParser &Parser = getParser();
7538
Parser.Lex();
7539
if (getLexer().isNot(AsmToken::Equal))
7540
return reportParseError("unexpected token, expected equals sign");
7541
7542
Parser.Lex();
7543
StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7544
if (Arch.empty())
7545
return reportParseError("expected arch identifier");
7546
7547
StringRef ArchFeatureName =
7548
StringSwitch<StringRef>(Arch)
7549
.Case("mips1", "mips1")
7550
.Case("mips2", "mips2")
7551
.Case("mips3", "mips3")
7552
.Case("mips4", "mips4")
7553
.Case("mips5", "mips5")
7554
.Case("mips32", "mips32")
7555
.Case("mips32r2", "mips32r2")
7556
.Case("mips32r3", "mips32r3")
7557
.Case("mips32r5", "mips32r5")
7558
.Case("mips32r6", "mips32r6")
7559
.Case("mips64", "mips64")
7560
.Case("mips64r2", "mips64r2")
7561
.Case("mips64r3", "mips64r3")
7562
.Case("mips64r5", "mips64r5")
7563
.Case("mips64r6", "mips64r6")
7564
.Case("octeon", "cnmips")
7565
.Case("octeon+", "cnmipsp")
7566
.Case("r4000", "mips3") // This is an implementation of Mips3.
7567
.Default("");
7568
7569
if (ArchFeatureName.empty())
7570
return reportParseError("unsupported architecture");
7571
7572
if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7573
return reportParseError("mips64r6 does not support microMIPS");
7574
7575
selectArch(ArchFeatureName);
7576
getTargetStreamer().emitDirectiveSetArch(Arch);
7577
return false;
7578
}
7579
7580
bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7581
MCAsmParser &Parser = getParser();
7582
Parser.Lex();
7583
if (getLexer().isNot(AsmToken::EndOfStatement))
7584
return reportParseError("unexpected token, expected end of statement");
7585
7586
switch (Feature) {
7587
default:
7588
llvm_unreachable("Unimplemented feature");
7589
case Mips::FeatureMips3D:
7590
setFeatureBits(Mips::FeatureMips3D, "mips3d");
7591
getTargetStreamer().emitDirectiveSetMips3D();
7592
break;
7593
case Mips::FeatureDSP:
7594
setFeatureBits(Mips::FeatureDSP, "dsp");
7595
getTargetStreamer().emitDirectiveSetDsp();
7596
break;
7597
case Mips::FeatureDSPR2:
7598
setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7599
getTargetStreamer().emitDirectiveSetDspr2();
7600
break;
7601
case Mips::FeatureMicroMips:
7602
setFeatureBits(Mips::FeatureMicroMips, "micromips");
7603
getTargetStreamer().emitDirectiveSetMicroMips();
7604
break;
7605
case Mips::FeatureMips1:
7606
selectArch("mips1");
7607
getTargetStreamer().emitDirectiveSetMips1();
7608
break;
7609
case Mips::FeatureMips2:
7610
selectArch("mips2");
7611
getTargetStreamer().emitDirectiveSetMips2();
7612
break;
7613
case Mips::FeatureMips3:
7614
selectArch("mips3");
7615
getTargetStreamer().emitDirectiveSetMips3();
7616
break;
7617
case Mips::FeatureMips4:
7618
selectArch("mips4");
7619
getTargetStreamer().emitDirectiveSetMips4();
7620
break;
7621
case Mips::FeatureMips5:
7622
selectArch("mips5");
7623
getTargetStreamer().emitDirectiveSetMips5();
7624
break;
7625
case Mips::FeatureMips32:
7626
selectArch("mips32");
7627
getTargetStreamer().emitDirectiveSetMips32();
7628
break;
7629
case Mips::FeatureMips32r2:
7630
selectArch("mips32r2");
7631
getTargetStreamer().emitDirectiveSetMips32R2();
7632
break;
7633
case Mips::FeatureMips32r3:
7634
selectArch("mips32r3");
7635
getTargetStreamer().emitDirectiveSetMips32R3();
7636
break;
7637
case Mips::FeatureMips32r5:
7638
selectArch("mips32r5");
7639
getTargetStreamer().emitDirectiveSetMips32R5();
7640
break;
7641
case Mips::FeatureMips32r6:
7642
selectArch("mips32r6");
7643
getTargetStreamer().emitDirectiveSetMips32R6();
7644
break;
7645
case Mips::FeatureMips64:
7646
selectArch("mips64");
7647
getTargetStreamer().emitDirectiveSetMips64();
7648
break;
7649
case Mips::FeatureMips64r2:
7650
selectArch("mips64r2");
7651
getTargetStreamer().emitDirectiveSetMips64R2();
7652
break;
7653
case Mips::FeatureMips64r3:
7654
selectArch("mips64r3");
7655
getTargetStreamer().emitDirectiveSetMips64R3();
7656
break;
7657
case Mips::FeatureMips64r5:
7658
selectArch("mips64r5");
7659
getTargetStreamer().emitDirectiveSetMips64R5();
7660
break;
7661
case Mips::FeatureMips64r6:
7662
selectArch("mips64r6");
7663
getTargetStreamer().emitDirectiveSetMips64R6();
7664
break;
7665
case Mips::FeatureCRC:
7666
setFeatureBits(Mips::FeatureCRC, "crc");
7667
getTargetStreamer().emitDirectiveSetCRC();
7668
break;
7669
case Mips::FeatureVirt:
7670
setFeatureBits(Mips::FeatureVirt, "virt");
7671
getTargetStreamer().emitDirectiveSetVirt();
7672
break;
7673
case Mips::FeatureGINV:
7674
setFeatureBits(Mips::FeatureGINV, "ginv");
7675
getTargetStreamer().emitDirectiveSetGINV();
7676
break;
7677
}
7678
return false;
7679
}
7680
7681
bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7682
MCAsmParser &Parser = getParser();
7683
if (getLexer().isNot(AsmToken::Comma)) {
7684
SMLoc Loc = getLexer().getLoc();
7685
return Error(Loc, ErrorStr);
7686
}
7687
7688
Parser.Lex(); // Eat the comma.
7689
return true;
7690
}
7691
7692
// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7693
// In this class, it is only used for .cprestore.
7694
// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7695
// MipsTargetELFStreamer and MipsAsmParser.
7696
bool MipsAsmParser::isPicAndNotNxxAbi() {
7697
return inPicMode() && !(isABI_N32() || isABI_N64());
7698
}
7699
7700
bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7701
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7702
ParseStatus Res = parseAnyRegister(Reg);
7703
if (Res.isNoMatch() || Res.isFailure()) {
7704
reportParseError("expected register");
7705
return false;
7706
}
7707
7708
MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7709
if (!RegOpnd.isGPRAsmReg()) {
7710
reportParseError(RegOpnd.getStartLoc(), "invalid register");
7711
return false;
7712
}
7713
7714
// If this is not the end of the statement, report an error.
7715
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7716
reportParseError("unexpected token, expected end of statement");
7717
return false;
7718
}
7719
getParser().Lex(); // Consume the EndOfStatement.
7720
7721
getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7722
return false;
7723
}
7724
7725
bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7726
if (AssemblerOptions.back()->isReorder())
7727
Warning(Loc, ".cpload should be inside a noreorder section");
7728
7729
if (inMips16Mode()) {
7730
reportParseError(".cpload is not supported in Mips16 mode");
7731
return false;
7732
}
7733
7734
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7735
ParseStatus Res = parseAnyRegister(Reg);
7736
if (Res.isNoMatch() || Res.isFailure()) {
7737
reportParseError("expected register containing function address");
7738
return false;
7739
}
7740
7741
MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7742
if (!RegOpnd.isGPRAsmReg()) {
7743
reportParseError(RegOpnd.getStartLoc(), "invalid register");
7744
return false;
7745
}
7746
7747
// If this is not the end of the statement, report an error.
7748
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7749
reportParseError("unexpected token, expected end of statement");
7750
return false;
7751
}
7752
7753
getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7754
return false;
7755
}
7756
7757
bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7758
if (!isABI_N32() && !isABI_N64()) {
7759
reportParseError(".cplocal is allowed only in N32 or N64 mode");
7760
return false;
7761
}
7762
7763
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7764
ParseStatus Res = parseAnyRegister(Reg);
7765
if (Res.isNoMatch() || Res.isFailure()) {
7766
reportParseError("expected register containing global pointer");
7767
return false;
7768
}
7769
7770
MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7771
if (!RegOpnd.isGPRAsmReg()) {
7772
reportParseError(RegOpnd.getStartLoc(), "invalid register");
7773
return false;
7774
}
7775
7776
// If this is not the end of the statement, report an error.
7777
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7778
reportParseError("unexpected token, expected end of statement");
7779
return false;
7780
}
7781
getParser().Lex(); // Consume the EndOfStatement.
7782
7783
unsigned NewReg = RegOpnd.getGPR32Reg();
7784
if (IsPicEnabled)
7785
GPReg = NewReg;
7786
7787
getTargetStreamer().emitDirectiveCpLocal(NewReg);
7788
return false;
7789
}
7790
7791
bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7792
MCAsmParser &Parser = getParser();
7793
7794
// Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7795
// is used in non-PIC mode.
7796
7797
if (inMips16Mode()) {
7798
reportParseError(".cprestore is not supported in Mips16 mode");
7799
return false;
7800
}
7801
7802
// Get the stack offset value.
7803
const MCExpr *StackOffset;
7804
int64_t StackOffsetVal;
7805
if (Parser.parseExpression(StackOffset)) {
7806
reportParseError("expected stack offset value");
7807
return false;
7808
}
7809
7810
if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7811
reportParseError("stack offset is not an absolute expression");
7812
return false;
7813
}
7814
7815
if (StackOffsetVal < 0) {
7816
Warning(Loc, ".cprestore with negative stack offset has no effect");
7817
IsCpRestoreSet = false;
7818
} else {
7819
IsCpRestoreSet = true;
7820
CpRestoreOffset = StackOffsetVal;
7821
}
7822
7823
// If this is not the end of the statement, report an error.
7824
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7825
reportParseError("unexpected token, expected end of statement");
7826
return false;
7827
}
7828
7829
if (!getTargetStreamer().emitDirectiveCpRestore(
7830
CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7831
return true;
7832
Parser.Lex(); // Consume the EndOfStatement.
7833
return false;
7834
}
7835
7836
bool MipsAsmParser::parseDirectiveCPSetup() {
7837
MCAsmParser &Parser = getParser();
7838
unsigned FuncReg;
7839
unsigned Save;
7840
bool SaveIsReg = true;
7841
7842
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7843
ParseStatus Res = parseAnyRegister(TmpReg);
7844
if (Res.isNoMatch()) {
7845
reportParseError("expected register containing function address");
7846
return false;
7847
}
7848
7849
MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7850
if (!FuncRegOpnd.isGPRAsmReg()) {
7851
reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7852
return false;
7853
}
7854
7855
FuncReg = FuncRegOpnd.getGPR32Reg();
7856
TmpReg.clear();
7857
7858
if (!eatComma("unexpected token, expected comma"))
7859
return true;
7860
7861
Res = parseAnyRegister(TmpReg);
7862
if (Res.isNoMatch()) {
7863
const MCExpr *OffsetExpr;
7864
int64_t OffsetVal;
7865
SMLoc ExprLoc = getLexer().getLoc();
7866
7867
if (Parser.parseExpression(OffsetExpr) ||
7868
!OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7869
reportParseError(ExprLoc, "expected save register or stack offset");
7870
return false;
7871
}
7872
7873
Save = OffsetVal;
7874
SaveIsReg = false;
7875
} else {
7876
MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7877
if (!SaveOpnd.isGPRAsmReg()) {
7878
reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7879
return false;
7880
}
7881
Save = SaveOpnd.getGPR32Reg();
7882
}
7883
7884
if (!eatComma("unexpected token, expected comma"))
7885
return true;
7886
7887
const MCExpr *Expr;
7888
if (Parser.parseExpression(Expr)) {
7889
reportParseError("expected expression");
7890
return false;
7891
}
7892
7893
if (Expr->getKind() != MCExpr::SymbolRef) {
7894
reportParseError("expected symbol");
7895
return false;
7896
}
7897
const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7898
7899
CpSaveLocation = Save;
7900
CpSaveLocationIsRegister = SaveIsReg;
7901
7902
getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7903
SaveIsReg);
7904
return false;
7905
}
7906
7907
bool MipsAsmParser::parseDirectiveCPReturn() {
7908
getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7909
CpSaveLocationIsRegister);
7910
return false;
7911
}
7912
7913
bool MipsAsmParser::parseDirectiveNaN() {
7914
MCAsmParser &Parser = getParser();
7915
if (getLexer().isNot(AsmToken::EndOfStatement)) {
7916
const AsmToken &Tok = Parser.getTok();
7917
7918
if (Tok.getString() == "2008") {
7919
Parser.Lex();
7920
getTargetStreamer().emitDirectiveNaN2008();
7921
return false;
7922
} else if (Tok.getString() == "legacy") {
7923
Parser.Lex();
7924
getTargetStreamer().emitDirectiveNaNLegacy();
7925
return false;
7926
}
7927
}
7928
// If we don't recognize the option passed to the .nan
7929
// directive (e.g. no option or unknown option), emit an error.
7930
reportParseError("invalid option in .nan directive");
7931
return false;
7932
}
7933
7934
bool MipsAsmParser::parseDirectiveSet() {
7935
const AsmToken &Tok = getParser().getTok();
7936
StringRef IdVal = Tok.getString();
7937
SMLoc Loc = Tok.getLoc();
7938
7939
if (IdVal == "noat")
7940
return parseSetNoAtDirective();
7941
if (IdVal == "at")
7942
return parseSetAtDirective();
7943
if (IdVal == "arch")
7944
return parseSetArchDirective();
7945
if (IdVal == "bopt") {
7946
Warning(Loc, "'bopt' feature is unsupported");
7947
getParser().Lex();
7948
return false;
7949
}
7950
if (IdVal == "nobopt") {
7951
// We're already running in nobopt mode, so nothing to do.
7952
getParser().Lex();
7953
return false;
7954
}
7955
if (IdVal == "fp")
7956
return parseSetFpDirective();
7957
if (IdVal == "oddspreg")
7958
return parseSetOddSPRegDirective();
7959
if (IdVal == "nooddspreg")
7960
return parseSetNoOddSPRegDirective();
7961
if (IdVal == "pop")
7962
return parseSetPopDirective();
7963
if (IdVal == "push")
7964
return parseSetPushDirective();
7965
if (IdVal == "reorder")
7966
return parseSetReorderDirective();
7967
if (IdVal == "noreorder")
7968
return parseSetNoReorderDirective();
7969
if (IdVal == "macro")
7970
return parseSetMacroDirective();
7971
if (IdVal == "nomacro")
7972
return parseSetNoMacroDirective();
7973
if (IdVal == "mips16")
7974
return parseSetMips16Directive();
7975
if (IdVal == "nomips16")
7976
return parseSetNoMips16Directive();
7977
if (IdVal == "nomicromips") {
7978
clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7979
getTargetStreamer().emitDirectiveSetNoMicroMips();
7980
getParser().eatToEndOfStatement();
7981
return false;
7982
}
7983
if (IdVal == "micromips") {
7984
if (hasMips64r6()) {
7985
Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7986
return false;
7987
}
7988
return parseSetFeature(Mips::FeatureMicroMips);
7989
}
7990
if (IdVal == "mips0")
7991
return parseSetMips0Directive();
7992
if (IdVal == "mips1")
7993
return parseSetFeature(Mips::FeatureMips1);
7994
if (IdVal == "mips2")
7995
return parseSetFeature(Mips::FeatureMips2);
7996
if (IdVal == "mips3")
7997
return parseSetFeature(Mips::FeatureMips3);
7998
if (IdVal == "mips4")
7999
return parseSetFeature(Mips::FeatureMips4);
8000
if (IdVal == "mips5")
8001
return parseSetFeature(Mips::FeatureMips5);
8002
if (IdVal == "mips32")
8003
return parseSetFeature(Mips::FeatureMips32);
8004
if (IdVal == "mips32r2")
8005
return parseSetFeature(Mips::FeatureMips32r2);
8006
if (IdVal == "mips32r3")
8007
return parseSetFeature(Mips::FeatureMips32r3);
8008
if (IdVal == "mips32r5")
8009
return parseSetFeature(Mips::FeatureMips32r5);
8010
if (IdVal == "mips32r6")
8011
return parseSetFeature(Mips::FeatureMips32r6);
8012
if (IdVal == "mips64")
8013
return parseSetFeature(Mips::FeatureMips64);
8014
if (IdVal == "mips64r2")
8015
return parseSetFeature(Mips::FeatureMips64r2);
8016
if (IdVal == "mips64r3")
8017
return parseSetFeature(Mips::FeatureMips64r3);
8018
if (IdVal == "mips64r5")
8019
return parseSetFeature(Mips::FeatureMips64r5);
8020
if (IdVal == "mips64r6") {
8021
if (inMicroMipsMode()) {
8022
Error(Loc, "MIPS64R6 is not supported with microMIPS");
8023
return false;
8024
}
8025
return parseSetFeature(Mips::FeatureMips64r6);
8026
}
8027
if (IdVal == "dsp")
8028
return parseSetFeature(Mips::FeatureDSP);
8029
if (IdVal == "dspr2")
8030
return parseSetFeature(Mips::FeatureDSPR2);
8031
if (IdVal == "nodsp")
8032
return parseSetNoDspDirective();
8033
if (IdVal == "mips3d")
8034
return parseSetFeature(Mips::FeatureMips3D);
8035
if (IdVal == "nomips3d")
8036
return parseSetNoMips3DDirective();
8037
if (IdVal == "msa")
8038
return parseSetMsaDirective();
8039
if (IdVal == "nomsa")
8040
return parseSetNoMsaDirective();
8041
if (IdVal == "mt")
8042
return parseSetMtDirective();
8043
if (IdVal == "nomt")
8044
return parseSetNoMtDirective();
8045
if (IdVal == "softfloat")
8046
return parseSetSoftFloatDirective();
8047
if (IdVal == "hardfloat")
8048
return parseSetHardFloatDirective();
8049
if (IdVal == "crc")
8050
return parseSetFeature(Mips::FeatureCRC);
8051
if (IdVal == "nocrc")
8052
return parseSetNoCRCDirective();
8053
if (IdVal == "virt")
8054
return parseSetFeature(Mips::FeatureVirt);
8055
if (IdVal == "novirt")
8056
return parseSetNoVirtDirective();
8057
if (IdVal == "ginv")
8058
return parseSetFeature(Mips::FeatureGINV);
8059
if (IdVal == "noginv")
8060
return parseSetNoGINVDirective();
8061
8062
// It is just an identifier, look for an assignment.
8063
return parseSetAssignment();
8064
}
8065
8066
/// parseDirectiveGpWord
8067
/// ::= .gpword local_sym
8068
bool MipsAsmParser::parseDirectiveGpWord() {
8069
MCAsmParser &Parser = getParser();
8070
const MCExpr *Value;
8071
// EmitGPRel32Value requires an expression, so we are using base class
8072
// method to evaluate the expression.
8073
if (getParser().parseExpression(Value))
8074
return true;
8075
getParser().getStreamer().emitGPRel32Value(Value);
8076
8077
if (getLexer().isNot(AsmToken::EndOfStatement))
8078
return Error(getLexer().getLoc(),
8079
"unexpected token, expected end of statement");
8080
Parser.Lex(); // Eat EndOfStatement token.
8081
return false;
8082
}
8083
8084
/// parseDirectiveGpDWord
8085
/// ::= .gpdword local_sym
8086
bool MipsAsmParser::parseDirectiveGpDWord() {
8087
MCAsmParser &Parser = getParser();
8088
const MCExpr *Value;
8089
// EmitGPRel64Value requires an expression, so we are using base class
8090
// method to evaluate the expression.
8091
if (getParser().parseExpression(Value))
8092
return true;
8093
getParser().getStreamer().emitGPRel64Value(Value);
8094
8095
if (getLexer().isNot(AsmToken::EndOfStatement))
8096
return Error(getLexer().getLoc(),
8097
"unexpected token, expected end of statement");
8098
Parser.Lex(); // Eat EndOfStatement token.
8099
return false;
8100
}
8101
8102
/// parseDirectiveDtpRelWord
8103
/// ::= .dtprelword tls_sym
8104
bool MipsAsmParser::parseDirectiveDtpRelWord() {
8105
MCAsmParser &Parser = getParser();
8106
const MCExpr *Value;
8107
// EmitDTPRel32Value requires an expression, so we are using base class
8108
// method to evaluate the expression.
8109
if (getParser().parseExpression(Value))
8110
return true;
8111
getParser().getStreamer().emitDTPRel32Value(Value);
8112
8113
if (getLexer().isNot(AsmToken::EndOfStatement))
8114
return Error(getLexer().getLoc(),
8115
"unexpected token, expected end of statement");
8116
Parser.Lex(); // Eat EndOfStatement token.
8117
return false;
8118
}
8119
8120
/// parseDirectiveDtpRelDWord
8121
/// ::= .dtpreldword tls_sym
8122
bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8123
MCAsmParser &Parser = getParser();
8124
const MCExpr *Value;
8125
// EmitDTPRel64Value requires an expression, so we are using base class
8126
// method to evaluate the expression.
8127
if (getParser().parseExpression(Value))
8128
return true;
8129
getParser().getStreamer().emitDTPRel64Value(Value);
8130
8131
if (getLexer().isNot(AsmToken::EndOfStatement))
8132
return Error(getLexer().getLoc(),
8133
"unexpected token, expected end of statement");
8134
Parser.Lex(); // Eat EndOfStatement token.
8135
return false;
8136
}
8137
8138
/// parseDirectiveTpRelWord
8139
/// ::= .tprelword tls_sym
8140
bool MipsAsmParser::parseDirectiveTpRelWord() {
8141
MCAsmParser &Parser = getParser();
8142
const MCExpr *Value;
8143
// EmitTPRel32Value requires an expression, so we are using base class
8144
// method to evaluate the expression.
8145
if (getParser().parseExpression(Value))
8146
return true;
8147
getParser().getStreamer().emitTPRel32Value(Value);
8148
8149
if (getLexer().isNot(AsmToken::EndOfStatement))
8150
return Error(getLexer().getLoc(),
8151
"unexpected token, expected end of statement");
8152
Parser.Lex(); // Eat EndOfStatement token.
8153
return false;
8154
}
8155
8156
/// parseDirectiveTpRelDWord
8157
/// ::= .tpreldword tls_sym
8158
bool MipsAsmParser::parseDirectiveTpRelDWord() {
8159
MCAsmParser &Parser = getParser();
8160
const MCExpr *Value;
8161
// EmitTPRel64Value requires an expression, so we are using base class
8162
// method to evaluate the expression.
8163
if (getParser().parseExpression(Value))
8164
return true;
8165
getParser().getStreamer().emitTPRel64Value(Value);
8166
8167
if (getLexer().isNot(AsmToken::EndOfStatement))
8168
return Error(getLexer().getLoc(),
8169
"unexpected token, expected end of statement");
8170
Parser.Lex(); // Eat EndOfStatement token.
8171
return false;
8172
}
8173
8174
bool MipsAsmParser::parseDirectiveOption() {
8175
MCAsmParser &Parser = getParser();
8176
// Get the option token.
8177
AsmToken Tok = Parser.getTok();
8178
// At the moment only identifiers are supported.
8179
if (Tok.isNot(AsmToken::Identifier)) {
8180
return Error(Parser.getTok().getLoc(),
8181
"unexpected token, expected identifier");
8182
}
8183
8184
StringRef Option = Tok.getIdentifier();
8185
8186
if (Option == "pic0") {
8187
// MipsAsmParser needs to know if the current PIC mode changes.
8188
IsPicEnabled = false;
8189
8190
getTargetStreamer().emitDirectiveOptionPic0();
8191
Parser.Lex();
8192
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8193
return Error(Parser.getTok().getLoc(),
8194
"unexpected token, expected end of statement");
8195
}
8196
return false;
8197
}
8198
8199
if (Option == "pic2") {
8200
// MipsAsmParser needs to know if the current PIC mode changes.
8201
IsPicEnabled = true;
8202
8203
getTargetStreamer().emitDirectiveOptionPic2();
8204
Parser.Lex();
8205
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8206
return Error(Parser.getTok().getLoc(),
8207
"unexpected token, expected end of statement");
8208
}
8209
return false;
8210
}
8211
8212
// Unknown option.
8213
Warning(Parser.getTok().getLoc(),
8214
"unknown option, expected 'pic0' or 'pic2'");
8215
Parser.eatToEndOfStatement();
8216
return false;
8217
}
8218
8219
/// parseInsnDirective
8220
/// ::= .insn
8221
bool MipsAsmParser::parseInsnDirective() {
8222
// If this is not the end of the statement, report an error.
8223
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8224
reportParseError("unexpected token, expected end of statement");
8225
return false;
8226
}
8227
8228
// The actual label marking happens in
8229
// MipsELFStreamer::createPendingLabelRelocs().
8230
getTargetStreamer().emitDirectiveInsn();
8231
8232
getParser().Lex(); // Eat EndOfStatement token.
8233
return false;
8234
}
8235
8236
/// parseRSectionDirective
8237
/// ::= .rdata
8238
bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8239
// If this is not the end of the statement, report an error.
8240
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8241
reportParseError("unexpected token, expected end of statement");
8242
return false;
8243
}
8244
8245
MCSection *ELFSection = getContext().getELFSection(
8246
Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
8247
getParser().getStreamer().switchSection(ELFSection);
8248
8249
getParser().Lex(); // Eat EndOfStatement token.
8250
return false;
8251
}
8252
8253
/// parseSSectionDirective
8254
/// ::= .sbss
8255
/// ::= .sdata
8256
bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8257
// If this is not the end of the statement, report an error.
8258
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8259
reportParseError("unexpected token, expected end of statement");
8260
return false;
8261
}
8262
8263
MCSection *ELFSection = getContext().getELFSection(
8264
Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
8265
getParser().getStreamer().switchSection(ELFSection);
8266
8267
getParser().Lex(); // Eat EndOfStatement token.
8268
return false;
8269
}
8270
8271
/// parseDirectiveModule
8272
/// ::= .module oddspreg
8273
/// ::= .module nooddspreg
8274
/// ::= .module fp=value
8275
/// ::= .module softfloat
8276
/// ::= .module hardfloat
8277
/// ::= .module mt
8278
/// ::= .module crc
8279
/// ::= .module nocrc
8280
/// ::= .module virt
8281
/// ::= .module novirt
8282
/// ::= .module ginv
8283
/// ::= .module noginv
8284
bool MipsAsmParser::parseDirectiveModule() {
8285
MCAsmParser &Parser = getParser();
8286
MCAsmLexer &Lexer = getLexer();
8287
SMLoc L = Lexer.getLoc();
8288
8289
if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8290
// TODO : get a better message.
8291
reportParseError(".module directive must appear before any code");
8292
return false;
8293
}
8294
8295
StringRef Option;
8296
if (Parser.parseIdentifier(Option)) {
8297
reportParseError("expected .module option identifier");
8298
return false;
8299
}
8300
8301
if (Option == "oddspreg") {
8302
clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8303
8304
// Synchronize the abiflags information with the FeatureBits information we
8305
// changed above.
8306
getTargetStreamer().updateABIInfo(*this);
8307
8308
// If printing assembly, use the recently updated abiflags information.
8309
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8310
// emitted at the end).
8311
getTargetStreamer().emitDirectiveModuleOddSPReg();
8312
8313
// If this is not the end of the statement, report an error.
8314
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8315
reportParseError("unexpected token, expected end of statement");
8316
return false;
8317
}
8318
8319
return false; // parseDirectiveModule has finished successfully.
8320
} else if (Option == "nooddspreg") {
8321
if (!isABI_O32()) {
8322
return Error(L, "'.module nooddspreg' requires the O32 ABI");
8323
}
8324
8325
setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8326
8327
// Synchronize the abiflags information with the FeatureBits information we
8328
// changed above.
8329
getTargetStreamer().updateABIInfo(*this);
8330
8331
// If printing assembly, use the recently updated abiflags information.
8332
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8333
// emitted at the end).
8334
getTargetStreamer().emitDirectiveModuleOddSPReg();
8335
8336
// If this is not the end of the statement, report an error.
8337
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8338
reportParseError("unexpected token, expected end of statement");
8339
return false;
8340
}
8341
8342
return false; // parseDirectiveModule has finished successfully.
8343
} else if (Option == "fp") {
8344
return parseDirectiveModuleFP();
8345
} else if (Option == "softfloat") {
8346
setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8347
8348
// Synchronize the ABI Flags information with the FeatureBits information we
8349
// updated above.
8350
getTargetStreamer().updateABIInfo(*this);
8351
8352
// If printing assembly, use the recently updated ABI Flags information.
8353
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8354
// emitted later).
8355
getTargetStreamer().emitDirectiveModuleSoftFloat();
8356
8357
// If this is not the end of the statement, report an error.
8358
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8359
reportParseError("unexpected token, expected end of statement");
8360
return false;
8361
}
8362
8363
return false; // parseDirectiveModule has finished successfully.
8364
} else if (Option == "hardfloat") {
8365
clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8366
8367
// Synchronize the ABI Flags information with the FeatureBits information we
8368
// updated above.
8369
getTargetStreamer().updateABIInfo(*this);
8370
8371
// If printing assembly, use the recently updated ABI Flags information.
8372
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8373
// emitted later).
8374
getTargetStreamer().emitDirectiveModuleHardFloat();
8375
8376
// If this is not the end of the statement, report an error.
8377
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8378
reportParseError("unexpected token, expected end of statement");
8379
return false;
8380
}
8381
8382
return false; // parseDirectiveModule has finished successfully.
8383
} else if (Option == "mt") {
8384
setModuleFeatureBits(Mips::FeatureMT, "mt");
8385
8386
// Synchronize the ABI Flags information with the FeatureBits information we
8387
// updated above.
8388
getTargetStreamer().updateABIInfo(*this);
8389
8390
// If printing assembly, use the recently updated ABI Flags information.
8391
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8392
// emitted later).
8393
getTargetStreamer().emitDirectiveModuleMT();
8394
8395
// If this is not the end of the statement, report an error.
8396
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8397
reportParseError("unexpected token, expected end of statement");
8398
return false;
8399
}
8400
8401
return false; // parseDirectiveModule has finished successfully.
8402
} else if (Option == "crc") {
8403
setModuleFeatureBits(Mips::FeatureCRC, "crc");
8404
8405
// Synchronize the ABI Flags information with the FeatureBits information we
8406
// updated above.
8407
getTargetStreamer().updateABIInfo(*this);
8408
8409
// If printing assembly, use the recently updated ABI Flags information.
8410
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8411
// emitted later).
8412
getTargetStreamer().emitDirectiveModuleCRC();
8413
8414
// If this is not the end of the statement, report an error.
8415
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8416
reportParseError("unexpected token, expected end of statement");
8417
return false;
8418
}
8419
8420
return false; // parseDirectiveModule has finished successfully.
8421
} else if (Option == "nocrc") {
8422
clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8423
8424
// Synchronize the ABI Flags information with the FeatureBits information we
8425
// updated above.
8426
getTargetStreamer().updateABIInfo(*this);
8427
8428
// If printing assembly, use the recently updated ABI Flags information.
8429
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8430
// emitted later).
8431
getTargetStreamer().emitDirectiveModuleNoCRC();
8432
8433
// If this is not the end of the statement, report an error.
8434
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8435
reportParseError("unexpected token, expected end of statement");
8436
return false;
8437
}
8438
8439
return false; // parseDirectiveModule has finished successfully.
8440
} else if (Option == "virt") {
8441
setModuleFeatureBits(Mips::FeatureVirt, "virt");
8442
8443
// Synchronize the ABI Flags information with the FeatureBits information we
8444
// updated above.
8445
getTargetStreamer().updateABIInfo(*this);
8446
8447
// If printing assembly, use the recently updated ABI Flags information.
8448
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8449
// emitted later).
8450
getTargetStreamer().emitDirectiveModuleVirt();
8451
8452
// If this is not the end of the statement, report an error.
8453
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8454
reportParseError("unexpected token, expected end of statement");
8455
return false;
8456
}
8457
8458
return false; // parseDirectiveModule has finished successfully.
8459
} else if (Option == "novirt") {
8460
clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8461
8462
// Synchronize the ABI Flags information with the FeatureBits information we
8463
// updated above.
8464
getTargetStreamer().updateABIInfo(*this);
8465
8466
// If printing assembly, use the recently updated ABI Flags information.
8467
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8468
// emitted later).
8469
getTargetStreamer().emitDirectiveModuleNoVirt();
8470
8471
// If this is not the end of the statement, report an error.
8472
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8473
reportParseError("unexpected token, expected end of statement");
8474
return false;
8475
}
8476
8477
return false; // parseDirectiveModule has finished successfully.
8478
} else if (Option == "ginv") {
8479
setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8480
8481
// Synchronize the ABI Flags information with the FeatureBits information we
8482
// updated above.
8483
getTargetStreamer().updateABIInfo(*this);
8484
8485
// If printing assembly, use the recently updated ABI Flags information.
8486
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8487
// emitted later).
8488
getTargetStreamer().emitDirectiveModuleGINV();
8489
8490
// If this is not the end of the statement, report an error.
8491
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8492
reportParseError("unexpected token, expected end of statement");
8493
return false;
8494
}
8495
8496
return false; // parseDirectiveModule has finished successfully.
8497
} else if (Option == "noginv") {
8498
clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8499
8500
// Synchronize the ABI Flags information with the FeatureBits information we
8501
// updated above.
8502
getTargetStreamer().updateABIInfo(*this);
8503
8504
// If printing assembly, use the recently updated ABI Flags information.
8505
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8506
// emitted later).
8507
getTargetStreamer().emitDirectiveModuleNoGINV();
8508
8509
// If this is not the end of the statement, report an error.
8510
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8511
reportParseError("unexpected token, expected end of statement");
8512
return false;
8513
}
8514
8515
return false; // parseDirectiveModule has finished successfully.
8516
} else {
8517
return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8518
}
8519
}
8520
8521
/// parseDirectiveModuleFP
8522
/// ::= =32
8523
/// ::= =xx
8524
/// ::= =64
8525
bool MipsAsmParser::parseDirectiveModuleFP() {
8526
MCAsmParser &Parser = getParser();
8527
MCAsmLexer &Lexer = getLexer();
8528
8529
if (Lexer.isNot(AsmToken::Equal)) {
8530
reportParseError("unexpected token, expected equals sign '='");
8531
return false;
8532
}
8533
Parser.Lex(); // Eat '=' token.
8534
8535
MipsABIFlagsSection::FpABIKind FpABI;
8536
if (!parseFpABIValue(FpABI, ".module"))
8537
return false;
8538
8539
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8540
reportParseError("unexpected token, expected end of statement");
8541
return false;
8542
}
8543
8544
// Synchronize the abiflags information with the FeatureBits information we
8545
// changed above.
8546
getTargetStreamer().updateABIInfo(*this);
8547
8548
// If printing assembly, use the recently updated abiflags information.
8549
// If generating ELF, don't do anything (the .MIPS.abiflags section gets
8550
// emitted at the end).
8551
getTargetStreamer().emitDirectiveModuleFP();
8552
8553
Parser.Lex(); // Consume the EndOfStatement.
8554
return false;
8555
}
8556
8557
bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8558
StringRef Directive) {
8559
MCAsmParser &Parser = getParser();
8560
MCAsmLexer &Lexer = getLexer();
8561
bool ModuleLevelOptions = Directive == ".module";
8562
8563
if (Lexer.is(AsmToken::Identifier)) {
8564
StringRef Value = Parser.getTok().getString();
8565
Parser.Lex();
8566
8567
if (Value != "xx") {
8568
reportParseError("unsupported value, expected 'xx', '32' or '64'");
8569
return false;
8570
}
8571
8572
if (!isABI_O32()) {
8573
reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8574
return false;
8575
}
8576
8577
FpABI = MipsABIFlagsSection::FpABIKind::XX;
8578
if (ModuleLevelOptions) {
8579
setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8580
clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8581
} else {
8582
setFeatureBits(Mips::FeatureFPXX, "fpxx");
8583
clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8584
}
8585
return true;
8586
}
8587
8588
if (Lexer.is(AsmToken::Integer)) {
8589
unsigned Value = Parser.getTok().getIntVal();
8590
Parser.Lex();
8591
8592
if (Value != 32 && Value != 64) {
8593
reportParseError("unsupported value, expected 'xx', '32' or '64'");
8594
return false;
8595
}
8596
8597
if (Value == 32) {
8598
if (!isABI_O32()) {
8599
reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8600
return false;
8601
}
8602
8603
FpABI = MipsABIFlagsSection::FpABIKind::S32;
8604
if (ModuleLevelOptions) {
8605
clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8606
clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8607
} else {
8608
clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8609
clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8610
}
8611
} else {
8612
FpABI = MipsABIFlagsSection::FpABIKind::S64;
8613
if (ModuleLevelOptions) {
8614
clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8615
setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8616
} else {
8617
clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8618
setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8619
}
8620
}
8621
8622
return true;
8623
}
8624
8625
return false;
8626
}
8627
8628
bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8629
// This returns false if this function recognizes the directive
8630
// regardless of whether it is successfully handles or reports an
8631
// error. Otherwise it returns true to give the generic parser a
8632
// chance at recognizing it.
8633
8634
MCAsmParser &Parser = getParser();
8635
StringRef IDVal = DirectiveID.getString();
8636
8637
if (IDVal == ".cpadd") {
8638
parseDirectiveCpAdd(DirectiveID.getLoc());
8639
return false;
8640
}
8641
if (IDVal == ".cpload") {
8642
parseDirectiveCpLoad(DirectiveID.getLoc());
8643
return false;
8644
}
8645
if (IDVal == ".cprestore") {
8646
parseDirectiveCpRestore(DirectiveID.getLoc());
8647
return false;
8648
}
8649
if (IDVal == ".cplocal") {
8650
parseDirectiveCpLocal(DirectiveID.getLoc());
8651
return false;
8652
}
8653
if (IDVal == ".ent") {
8654
StringRef SymbolName;
8655
8656
if (Parser.parseIdentifier(SymbolName)) {
8657
reportParseError("expected identifier after .ent");
8658
return false;
8659
}
8660
8661
// There's an undocumented extension that allows an integer to
8662
// follow the name of the procedure which AFAICS is ignored by GAS.
8663
// Example: .ent foo,2
8664
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8665
if (getLexer().isNot(AsmToken::Comma)) {
8666
// Even though we accept this undocumented extension for compatibility
8667
// reasons, the additional integer argument does not actually change
8668
// the behaviour of the '.ent' directive, so we would like to discourage
8669
// its use. We do this by not referring to the extended version in
8670
// error messages which are not directly related to its use.
8671
reportParseError("unexpected token, expected end of statement");
8672
return false;
8673
}
8674
Parser.Lex(); // Eat the comma.
8675
const MCExpr *DummyNumber;
8676
int64_t DummyNumberVal;
8677
// If the user was explicitly trying to use the extended version,
8678
// we still give helpful extension-related error messages.
8679
if (Parser.parseExpression(DummyNumber)) {
8680
reportParseError("expected number after comma");
8681
return false;
8682
}
8683
if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8684
reportParseError("expected an absolute expression after comma");
8685
return false;
8686
}
8687
}
8688
8689
// If this is not the end of the statement, report an error.
8690
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8691
reportParseError("unexpected token, expected end of statement");
8692
return false;
8693
}
8694
8695
MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8696
8697
getTargetStreamer().emitDirectiveEnt(*Sym);
8698
CurrentFn = Sym;
8699
IsCpRestoreSet = false;
8700
return false;
8701
}
8702
8703
if (IDVal == ".end") {
8704
StringRef SymbolName;
8705
8706
if (Parser.parseIdentifier(SymbolName)) {
8707
reportParseError("expected identifier after .end");
8708
return false;
8709
}
8710
8711
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8712
reportParseError("unexpected token, expected end of statement");
8713
return false;
8714
}
8715
8716
if (CurrentFn == nullptr) {
8717
reportParseError(".end used without .ent");
8718
return false;
8719
}
8720
8721
if ((SymbolName != CurrentFn->getName())) {
8722
reportParseError(".end symbol does not match .ent symbol");
8723
return false;
8724
}
8725
8726
getTargetStreamer().emitDirectiveEnd(SymbolName);
8727
CurrentFn = nullptr;
8728
IsCpRestoreSet = false;
8729
return false;
8730
}
8731
8732
if (IDVal == ".frame") {
8733
// .frame $stack_reg, frame_size_in_bytes, $return_reg
8734
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8735
ParseStatus Res = parseAnyRegister(TmpReg);
8736
if (Res.isNoMatch() || Res.isFailure()) {
8737
reportParseError("expected stack register");
8738
return false;
8739
}
8740
8741
MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8742
if (!StackRegOpnd.isGPRAsmReg()) {
8743
reportParseError(StackRegOpnd.getStartLoc(),
8744
"expected general purpose register");
8745
return false;
8746
}
8747
unsigned StackReg = StackRegOpnd.getGPR32Reg();
8748
8749
if (Parser.getTok().is(AsmToken::Comma))
8750
Parser.Lex();
8751
else {
8752
reportParseError("unexpected token, expected comma");
8753
return false;
8754
}
8755
8756
// Parse the frame size.
8757
const MCExpr *FrameSize;
8758
int64_t FrameSizeVal;
8759
8760
if (Parser.parseExpression(FrameSize)) {
8761
reportParseError("expected frame size value");
8762
return false;
8763
}
8764
8765
if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8766
reportParseError("frame size not an absolute expression");
8767
return false;
8768
}
8769
8770
if (Parser.getTok().is(AsmToken::Comma))
8771
Parser.Lex();
8772
else {
8773
reportParseError("unexpected token, expected comma");
8774
return false;
8775
}
8776
8777
// Parse the return register.
8778
TmpReg.clear();
8779
Res = parseAnyRegister(TmpReg);
8780
if (Res.isNoMatch() || Res.isFailure()) {
8781
reportParseError("expected return register");
8782
return false;
8783
}
8784
8785
MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8786
if (!ReturnRegOpnd.isGPRAsmReg()) {
8787
reportParseError(ReturnRegOpnd.getStartLoc(),
8788
"expected general purpose register");
8789
return false;
8790
}
8791
8792
// If this is not the end of the statement, report an error.
8793
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8794
reportParseError("unexpected token, expected end of statement");
8795
return false;
8796
}
8797
8798
getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8799
ReturnRegOpnd.getGPR32Reg());
8800
IsCpRestoreSet = false;
8801
return false;
8802
}
8803
8804
if (IDVal == ".set") {
8805
parseDirectiveSet();
8806
return false;
8807
}
8808
8809
if (IDVal == ".mask" || IDVal == ".fmask") {
8810
// .mask bitmask, frame_offset
8811
// bitmask: One bit for each register used.
8812
// frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8813
// first register is expected to be saved.
8814
// Examples:
8815
// .mask 0x80000000, -4
8816
// .fmask 0x80000000, -4
8817
//
8818
8819
// Parse the bitmask
8820
const MCExpr *BitMask;
8821
int64_t BitMaskVal;
8822
8823
if (Parser.parseExpression(BitMask)) {
8824
reportParseError("expected bitmask value");
8825
return false;
8826
}
8827
8828
if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8829
reportParseError("bitmask not an absolute expression");
8830
return false;
8831
}
8832
8833
if (Parser.getTok().is(AsmToken::Comma))
8834
Parser.Lex();
8835
else {
8836
reportParseError("unexpected token, expected comma");
8837
return false;
8838
}
8839
8840
// Parse the frame_offset
8841
const MCExpr *FrameOffset;
8842
int64_t FrameOffsetVal;
8843
8844
if (Parser.parseExpression(FrameOffset)) {
8845
reportParseError("expected frame offset value");
8846
return false;
8847
}
8848
8849
if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8850
reportParseError("frame offset not an absolute expression");
8851
return false;
8852
}
8853
8854
// If this is not the end of the statement, report an error.
8855
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8856
reportParseError("unexpected token, expected end of statement");
8857
return false;
8858
}
8859
8860
if (IDVal == ".mask")
8861
getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8862
else
8863
getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8864
return false;
8865
}
8866
8867
if (IDVal == ".nan")
8868
return parseDirectiveNaN();
8869
8870
if (IDVal == ".gpword") {
8871
parseDirectiveGpWord();
8872
return false;
8873
}
8874
8875
if (IDVal == ".gpdword") {
8876
parseDirectiveGpDWord();
8877
return false;
8878
}
8879
8880
if (IDVal == ".dtprelword") {
8881
parseDirectiveDtpRelWord();
8882
return false;
8883
}
8884
8885
if (IDVal == ".dtpreldword") {
8886
parseDirectiveDtpRelDWord();
8887
return false;
8888
}
8889
8890
if (IDVal == ".tprelword") {
8891
parseDirectiveTpRelWord();
8892
return false;
8893
}
8894
8895
if (IDVal == ".tpreldword") {
8896
parseDirectiveTpRelDWord();
8897
return false;
8898
}
8899
8900
if (IDVal == ".option") {
8901
parseDirectiveOption();
8902
return false;
8903
}
8904
8905
if (IDVal == ".abicalls") {
8906
getTargetStreamer().emitDirectiveAbiCalls();
8907
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8908
Error(Parser.getTok().getLoc(),
8909
"unexpected token, expected end of statement");
8910
}
8911
return false;
8912
}
8913
8914
if (IDVal == ".cpsetup") {
8915
parseDirectiveCPSetup();
8916
return false;
8917
}
8918
if (IDVal == ".cpreturn") {
8919
parseDirectiveCPReturn();
8920
return false;
8921
}
8922
if (IDVal == ".module") {
8923
parseDirectiveModule();
8924
return false;
8925
}
8926
if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8927
parseInternalDirectiveReallowModule();
8928
return false;
8929
}
8930
if (IDVal == ".insn") {
8931
parseInsnDirective();
8932
return false;
8933
}
8934
if (IDVal == ".rdata") {
8935
parseRSectionDirective(".rodata");
8936
return false;
8937
}
8938
if (IDVal == ".sbss") {
8939
parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8940
return false;
8941
}
8942
if (IDVal == ".sdata") {
8943
parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8944
return false;
8945
}
8946
8947
return true;
8948
}
8949
8950
bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8951
// If this is not the end of the statement, report an error.
8952
if (getLexer().isNot(AsmToken::EndOfStatement)) {
8953
reportParseError("unexpected token, expected end of statement");
8954
return false;
8955
}
8956
8957
getTargetStreamer().reallowModuleDirective();
8958
8959
getParser().Lex(); // Eat EndOfStatement token.
8960
return false;
8961
}
8962
8963
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser() {
8964
RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8965
RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8966
RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8967
RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8968
}
8969
8970
#define GET_REGISTER_MATCHER
8971
#define GET_MATCHER_IMPLEMENTATION
8972
#define GET_MNEMONIC_SPELL_CHECKER
8973
#include "MipsGenAsmMatcher.inc"
8974
8975
bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8976
// Find the appropriate table for this asm variant.
8977
const MatchEntry *Start, *End;
8978
switch (VariantID) {
8979
default: llvm_unreachable("invalid variant!");
8980
case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8981
}
8982
// Search the table.
8983
auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8984
return MnemonicRange.first != MnemonicRange.second;
8985
}
8986
8987