Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp
35293 views
1
//===---- CSKYAsmParser.cpp - Parse CSKY 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/CSKYInstPrinter.h"
10
#include "MCTargetDesc/CSKYMCExpr.h"
11
#include "MCTargetDesc/CSKYMCTargetDesc.h"
12
#include "MCTargetDesc/CSKYTargetStreamer.h"
13
#include "TargetInfo/CSKYTargetInfo.h"
14
#include "llvm/ADT/STLExtras.h"
15
#include "llvm/ADT/Statistic.h"
16
#include "llvm/ADT/StringExtras.h"
17
#include "llvm/ADT/StringSwitch.h"
18
#include "llvm/BinaryFormat/ELF.h"
19
#include "llvm/CodeGen/Register.h"
20
#include "llvm/MC/MCContext.h"
21
#include "llvm/MC/MCExpr.h"
22
#include "llvm/MC/MCInst.h"
23
#include "llvm/MC/MCInstrInfo.h"
24
#include "llvm/MC/MCParser/MCAsmLexer.h"
25
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
27
#include "llvm/MC/MCRegisterInfo.h"
28
#include "llvm/MC/MCSectionELF.h"
29
#include "llvm/MC/MCStreamer.h"
30
#include "llvm/MC/MCSubtargetInfo.h"
31
#include "llvm/MC/TargetRegistry.h"
32
#include "llvm/Support/CSKYAttributes.h"
33
#include "llvm/Support/Casting.h"
34
#include "llvm/Support/CommandLine.h"
35
#include "llvm/Support/Debug.h"
36
#include "llvm/TargetParser/CSKYTargetParser.h"
37
38
using namespace llvm;
39
40
#define DEBUG_TYPE "csky-asm-parser"
41
42
// Include the auto-generated portion of the compress emitter.
43
#define GEN_COMPRESS_INSTR
44
#include "CSKYGenCompressInstEmitter.inc"
45
46
STATISTIC(CSKYNumInstrsCompressed,
47
"Number of C-SKY Compressed instructions emitted");
48
49
static cl::opt<bool>
50
EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,
51
cl::init(false),
52
cl::desc("Enable C-SKY asm compressed instruction"));
53
54
namespace {
55
struct CSKYOperand;
56
57
class CSKYAsmParser : public MCTargetAsmParser {
58
59
const MCRegisterInfo *MRI;
60
61
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
62
unsigned Kind) override;
63
64
bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
65
int64_t Lower, int64_t Upper,
66
const Twine &Msg);
67
68
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
69
70
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
71
OperandVector &Operands, MCStreamer &Out,
72
uint64_t &ErrorInfo,
73
bool MatchingInlineAsm) override;
74
75
bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
76
77
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
78
SMLoc NameLoc, OperandVector &Operands) override;
79
80
ParseStatus parseDirective(AsmToken DirectiveID) override;
81
82
// Helper to actually emit an instruction to the MCStreamer. Also, when
83
// possible, compression of the instruction is performed.
84
void emitToStreamer(MCStreamer &S, const MCInst &Inst);
85
86
ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
87
SMLoc &EndLoc) override;
88
89
bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
90
MCStreamer &Out);
91
bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
92
bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
93
bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
94
95
CSKYTargetStreamer &getTargetStreamer() {
96
assert(getParser().getStreamer().getTargetStreamer() &&
97
"do not have a target streamer");
98
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
99
return static_cast<CSKYTargetStreamer &>(TS);
100
}
101
102
// Auto-generated instruction matching functions
103
#define GET_ASSEMBLER_HEADER
104
#include "CSKYGenAsmMatcher.inc"
105
106
ParseStatus parseImmediate(OperandVector &Operands);
107
ParseStatus parseRegister(OperandVector &Operands);
108
ParseStatus parseBaseRegImm(OperandVector &Operands);
109
ParseStatus parseCSKYSymbol(OperandVector &Operands);
110
ParseStatus parseConstpoolSymbol(OperandVector &Operands);
111
ParseStatus parseDataSymbol(OperandVector &Operands);
112
ParseStatus parsePSRFlag(OperandVector &Operands);
113
ParseStatus parseRegSeq(OperandVector &Operands);
114
ParseStatus parseRegList(OperandVector &Operands);
115
116
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
117
118
bool parseDirectiveAttribute();
119
120
public:
121
enum CSKYMatchResultTy {
122
Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
123
Match_RequiresSameSrcAndDst,
124
Match_InvalidRegOutOfRange,
125
#define GET_OPERAND_DIAGNOSTIC_TYPES
126
#include "CSKYGenAsmMatcher.inc"
127
#undef GET_OPERAND_DIAGNOSTIC_TYPES
128
};
129
130
CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
131
const MCInstrInfo &MII, const MCTargetOptions &Options)
132
: MCTargetAsmParser(Options, STI, MII) {
133
134
MCAsmParserExtension::Initialize(Parser);
135
136
// Cache the MCRegisterInfo.
137
MRI = getContext().getRegisterInfo();
138
139
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
140
getTargetStreamer().emitTargetAttributes(STI);
141
}
142
};
143
144
/// Instances of this class represent a parsed machine instruction.
145
struct CSKYOperand : public MCParsedAsmOperand {
146
147
enum KindTy {
148
Token,
149
Register,
150
Immediate,
151
RegisterSeq,
152
CPOP,
153
RegisterList
154
} Kind;
155
156
struct RegOp {
157
unsigned RegNum;
158
};
159
160
struct ImmOp {
161
const MCExpr *Val;
162
};
163
164
struct ConstpoolOp {
165
const MCExpr *Val;
166
};
167
168
struct RegSeqOp {
169
unsigned RegNumFrom;
170
unsigned RegNumTo;
171
};
172
173
struct RegListOp {
174
unsigned List1From = 0;
175
unsigned List1To = 0;
176
unsigned List2From = 0;
177
unsigned List2To = 0;
178
unsigned List3From = 0;
179
unsigned List3To = 0;
180
unsigned List4From = 0;
181
unsigned List4To = 0;
182
};
183
184
SMLoc StartLoc, EndLoc;
185
union {
186
StringRef Tok;
187
RegOp Reg;
188
ImmOp Imm;
189
ConstpoolOp CPool;
190
RegSeqOp RegSeq;
191
RegListOp RegList;
192
};
193
194
CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
195
196
public:
197
CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
198
Kind = o.Kind;
199
StartLoc = o.StartLoc;
200
EndLoc = o.EndLoc;
201
switch (Kind) {
202
case Register:
203
Reg = o.Reg;
204
break;
205
case RegisterSeq:
206
RegSeq = o.RegSeq;
207
break;
208
case CPOP:
209
CPool = o.CPool;
210
break;
211
case Immediate:
212
Imm = o.Imm;
213
break;
214
case Token:
215
Tok = o.Tok;
216
break;
217
case RegisterList:
218
RegList = o.RegList;
219
break;
220
}
221
}
222
223
bool isToken() const override { return Kind == Token; }
224
bool isReg() const override { return Kind == Register; }
225
bool isImm() const override { return Kind == Immediate; }
226
bool isRegisterSeq() const { return Kind == RegisterSeq; }
227
bool isRegisterList() const { return Kind == RegisterList; }
228
bool isConstPoolOp() const { return Kind == CPOP; }
229
230
bool isMem() const override { return false; }
231
232
static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
233
if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
234
Imm = CE->getValue();
235
return true;
236
}
237
238
return false;
239
}
240
241
template <unsigned num, unsigned shift = 0> bool isUImm() const {
242
if (!isImm())
243
return false;
244
245
int64_t Imm;
246
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
247
return IsConstantImm && isShiftedUInt<num, shift>(Imm);
248
}
249
250
template <unsigned num> bool isOImm() const {
251
if (!isImm())
252
return false;
253
254
int64_t Imm;
255
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
256
return IsConstantImm && isUInt<num>(Imm - 1);
257
}
258
259
template <unsigned num, unsigned shift = 0> bool isSImm() const {
260
if (!isImm())
261
return false;
262
263
int64_t Imm;
264
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
265
return IsConstantImm && isShiftedInt<num, shift>(Imm);
266
}
267
268
bool isUImm1() const { return isUImm<1>(); }
269
bool isUImm2() const { return isUImm<2>(); }
270
bool isUImm3() const { return isUImm<3>(); }
271
bool isUImm4() const { return isUImm<4>(); }
272
bool isUImm5() const { return isUImm<5>(); }
273
bool isUImm6() const { return isUImm<6>(); }
274
bool isUImm7() const { return isUImm<7>(); }
275
bool isUImm8() const { return isUImm<8>(); }
276
bool isUImm12() const { return isUImm<12>(); }
277
bool isUImm16() const { return isUImm<16>(); }
278
bool isUImm20() const { return isUImm<20>(); }
279
bool isUImm24() const { return isUImm<24>(); }
280
281
bool isOImm3() const { return isOImm<3>(); }
282
bool isOImm4() const { return isOImm<4>(); }
283
bool isOImm5() const { return isOImm<5>(); }
284
bool isOImm6() const { return isOImm<6>(); }
285
bool isOImm8() const { return isOImm<8>(); }
286
bool isOImm12() const { return isOImm<12>(); }
287
bool isOImm16() const { return isOImm<16>(); }
288
289
bool isSImm8() const { return isSImm<8>(); }
290
291
bool isUImm5Shift1() { return isUImm<5, 1>(); }
292
bool isUImm5Shift2() { return isUImm<5, 2>(); }
293
bool isUImm7Shift1() { return isUImm<7, 1>(); }
294
bool isUImm7Shift2() { return isUImm<7, 2>(); }
295
bool isUImm7Shift3() { return isUImm<7, 3>(); }
296
bool isUImm8Shift2() { return isUImm<8, 2>(); }
297
bool isUImm8Shift3() { return isUImm<8, 3>(); }
298
bool isUImm8Shift8() { return isUImm<8, 8>(); }
299
bool isUImm8Shift16() { return isUImm<8, 16>(); }
300
bool isUImm8Shift24() { return isUImm<8, 24>(); }
301
bool isUImm12Shift1() { return isUImm<12, 1>(); }
302
bool isUImm12Shift2() { return isUImm<12, 2>(); }
303
bool isUImm16Shift8() { return isUImm<16, 8>(); }
304
bool isUImm16Shift16() { return isUImm<16, 16>(); }
305
bool isUImm24Shift8() { return isUImm<24, 8>(); }
306
307
bool isSImm16Shift1() { return isSImm<16, 1>(); }
308
309
bool isCSKYSymbol() const { return isImm(); }
310
311
bool isConstpool() const { return isConstPoolOp(); }
312
bool isDataSymbol() const { return isConstPoolOp(); }
313
314
bool isPSRFlag() const {
315
int64_t Imm;
316
// Must be of 'immediate' type and a constant.
317
if (!isImm() || !evaluateConstantImm(getImm(), Imm))
318
return false;
319
320
return isUInt<5>(Imm);
321
}
322
323
template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {
324
if (!isRegisterSeq())
325
return false;
326
327
std::pair<unsigned, unsigned> regSeq = getRegSeq();
328
329
return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
330
regSeq.second <= MAX;
331
}
332
333
bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
334
335
bool isRegSeqV1() const {
336
return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
337
}
338
339
bool isRegSeqV2() const {
340
return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
341
}
342
343
static bool isLegalRegList(unsigned from, unsigned to) {
344
if (from == 0 && to == 0)
345
return true;
346
347
if (from == to) {
348
if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
349
from != CSKY::R28)
350
return false;
351
352
return true;
353
} else {
354
if (from != CSKY::R4 && from != CSKY::R16)
355
return false;
356
357
if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
358
return true;
359
else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
360
return true;
361
else
362
return false;
363
}
364
}
365
366
bool isRegList() const {
367
if (!isRegisterList())
368
return false;
369
370
auto regList = getRegList();
371
372
if (!isLegalRegList(regList.List1From, regList.List1To))
373
return false;
374
if (!isLegalRegList(regList.List2From, regList.List2To))
375
return false;
376
if (!isLegalRegList(regList.List3From, regList.List3To))
377
return false;
378
if (!isLegalRegList(regList.List4From, regList.List4To))
379
return false;
380
381
return true;
382
}
383
384
bool isExtImm6() {
385
if (!isImm())
386
return false;
387
388
int64_t Imm;
389
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
390
if (!IsConstantImm)
391
return false;
392
393
int uimm4 = Imm & 0xf;
394
395
return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
396
}
397
398
/// Gets location of the first token of this operand.
399
SMLoc getStartLoc() const override { return StartLoc; }
400
/// Gets location of the last token of this operand.
401
SMLoc getEndLoc() const override { return EndLoc; }
402
403
MCRegister getReg() const override {
404
assert(Kind == Register && "Invalid type access!");
405
return Reg.RegNum;
406
}
407
408
std::pair<unsigned, unsigned> getRegSeq() const {
409
assert(Kind == RegisterSeq && "Invalid type access!");
410
return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
411
}
412
413
RegListOp getRegList() const {
414
assert(Kind == RegisterList && "Invalid type access!");
415
return RegList;
416
}
417
418
const MCExpr *getImm() const {
419
assert(Kind == Immediate && "Invalid type access!");
420
return Imm.Val;
421
}
422
423
const MCExpr *getConstpoolOp() const {
424
assert(Kind == CPOP && "Invalid type access!");
425
return CPool.Val;
426
}
427
428
StringRef getToken() const {
429
assert(Kind == Token && "Invalid type access!");
430
return Tok;
431
}
432
433
void print(raw_ostream &OS) const override {
434
auto RegName = [](MCRegister Reg) {
435
if (Reg)
436
return CSKYInstPrinter::getRegisterName(Reg);
437
else
438
return "noreg";
439
};
440
441
switch (Kind) {
442
case CPOP:
443
OS << *getConstpoolOp();
444
break;
445
case Immediate:
446
OS << *getImm();
447
break;
448
case KindTy::Register:
449
OS << "<register " << RegName(getReg()) << ">";
450
break;
451
case RegisterSeq:
452
OS << "<register-seq ";
453
OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)
454
<< ">";
455
break;
456
case RegisterList:
457
OS << "<register-list ";
458
OS << RegName(getRegList().List1From) << "-"
459
<< RegName(getRegList().List1To) << ",";
460
OS << RegName(getRegList().List2From) << "-"
461
<< RegName(getRegList().List2To) << ",";
462
OS << RegName(getRegList().List3From) << "-"
463
<< RegName(getRegList().List3To) << ",";
464
OS << RegName(getRegList().List4From) << "-"
465
<< RegName(getRegList().List4To);
466
break;
467
case Token:
468
OS << "'" << getToken() << "'";
469
break;
470
}
471
}
472
473
static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
474
auto Op = std::make_unique<CSKYOperand>(Token);
475
Op->Tok = Str;
476
Op->StartLoc = S;
477
Op->EndLoc = S;
478
return Op;
479
}
480
481
static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
482
SMLoc E) {
483
auto Op = std::make_unique<CSKYOperand>(Register);
484
Op->Reg.RegNum = RegNo;
485
Op->StartLoc = S;
486
Op->EndLoc = E;
487
return Op;
488
}
489
490
static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,
491
unsigned RegNoTo, SMLoc S) {
492
auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
493
Op->RegSeq.RegNumFrom = RegNoFrom;
494
Op->RegSeq.RegNumTo = RegNoTo;
495
Op->StartLoc = S;
496
Op->EndLoc = S;
497
return Op;
498
}
499
500
static std::unique_ptr<CSKYOperand>
501
createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {
502
auto Op = std::make_unique<CSKYOperand>(RegisterList);
503
Op->RegList.List1From = 0;
504
Op->RegList.List1To = 0;
505
Op->RegList.List2From = 0;
506
Op->RegList.List2To = 0;
507
Op->RegList.List3From = 0;
508
Op->RegList.List3To = 0;
509
Op->RegList.List4From = 0;
510
Op->RegList.List4To = 0;
511
512
for (unsigned i = 0; i < reglist.size(); i += 2) {
513
if (Op->RegList.List1From == 0) {
514
Op->RegList.List1From = reglist[i];
515
Op->RegList.List1To = reglist[i + 1];
516
} else if (Op->RegList.List2From == 0) {
517
Op->RegList.List2From = reglist[i];
518
Op->RegList.List2To = reglist[i + 1];
519
} else if (Op->RegList.List3From == 0) {
520
Op->RegList.List3From = reglist[i];
521
Op->RegList.List3To = reglist[i + 1];
522
} else if (Op->RegList.List4From == 0) {
523
Op->RegList.List4From = reglist[i];
524
Op->RegList.List4To = reglist[i + 1];
525
} else {
526
assert(0);
527
}
528
}
529
530
Op->StartLoc = S;
531
Op->EndLoc = S;
532
return Op;
533
}
534
535
static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
536
SMLoc E) {
537
auto Op = std::make_unique<CSKYOperand>(Immediate);
538
Op->Imm.Val = Val;
539
Op->StartLoc = S;
540
Op->EndLoc = E;
541
return Op;
542
}
543
544
static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,
545
SMLoc S, SMLoc E) {
546
auto Op = std::make_unique<CSKYOperand>(CPOP);
547
Op->CPool.Val = Val;
548
Op->StartLoc = S;
549
Op->EndLoc = E;
550
return Op;
551
}
552
553
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
554
assert(Expr && "Expr shouldn't be null!");
555
if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
556
Inst.addOperand(MCOperand::createImm(CE->getValue()));
557
else
558
Inst.addOperand(MCOperand::createExpr(Expr));
559
}
560
561
// Used by the TableGen Code.
562
void addRegOperands(MCInst &Inst, unsigned N) const {
563
assert(N == 1 && "Invalid number of operands!");
564
Inst.addOperand(MCOperand::createReg(getReg()));
565
}
566
567
void addImmOperands(MCInst &Inst, unsigned N) const {
568
assert(N == 1 && "Invalid number of operands!");
569
addExpr(Inst, getImm());
570
}
571
572
void addConstpoolOperands(MCInst &Inst, unsigned N) const {
573
assert(N == 1 && "Invalid number of operands!");
574
Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));
575
}
576
577
void addRegSeqOperands(MCInst &Inst, unsigned N) const {
578
assert(N == 2 && "Invalid number of operands!");
579
auto regSeq = getRegSeq();
580
581
Inst.addOperand(MCOperand::createReg(regSeq.first));
582
Inst.addOperand(MCOperand::createReg(regSeq.second));
583
}
584
585
static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {
586
if (ListFrom == ListTo && ListFrom == CSKY::R15)
587
return (1 << 4);
588
else if (ListFrom == ListTo && ListFrom == CSKY::R28)
589
return (1 << 8);
590
else if (ListFrom == CSKY::R4)
591
return ListTo - ListFrom + 1;
592
else if (ListFrom == CSKY::R16)
593
return ((ListTo - ListFrom + 1) << 5);
594
else
595
return 0;
596
}
597
598
void addRegListOperands(MCInst &Inst, unsigned N) const {
599
assert(N == 1 && "Invalid number of operands!");
600
auto regList = getRegList();
601
602
unsigned V = 0;
603
604
unsigned T = getListValue(regList.List1From, regList.List1To);
605
if (T != 0)
606
V = V | T;
607
608
T = getListValue(regList.List2From, regList.List2To);
609
if (T != 0)
610
V = V | T;
611
612
T = getListValue(regList.List3From, regList.List3To);
613
if (T != 0)
614
V = V | T;
615
616
T = getListValue(regList.List4From, regList.List4To);
617
if (T != 0)
618
V = V | T;
619
620
Inst.addOperand(MCOperand::createImm(V));
621
}
622
623
bool isValidForTie(const CSKYOperand &Other) const {
624
if (Kind != Other.Kind)
625
return false;
626
627
switch (Kind) {
628
default:
629
llvm_unreachable("Unexpected kind");
630
return false;
631
case Register:
632
return Reg.RegNum == Other.Reg.RegNum;
633
}
634
}
635
};
636
} // end anonymous namespace.
637
638
#define GET_REGISTER_MATCHER
639
#define GET_SUBTARGET_FEATURE_NAME
640
#define GET_MATCHER_IMPLEMENTATION
641
#define GET_MNEMONIC_SPELL_CHECKER
642
#include "CSKYGenAsmMatcher.inc"
643
644
static MCRegister convertFPR32ToFPR64(MCRegister Reg) {
645
assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");
646
return Reg - CSKY::F0_32 + CSKY::F0_64;
647
}
648
649
static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
650
unsigned VariantID = 0);
651
652
bool CSKYAsmParser::generateImmOutOfRangeError(
653
OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
654
const Twine &Msg = "immediate must be an integer in the range") {
655
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
656
return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
657
}
658
659
bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
660
OperandVector &Operands,
661
MCStreamer &Out,
662
uint64_t &ErrorInfo,
663
bool MatchingInlineAsm) {
664
MCInst Inst;
665
FeatureBitset MissingFeatures;
666
667
auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
668
MatchingInlineAsm);
669
switch (Result) {
670
default:
671
break;
672
case Match_Success:
673
return processInstruction(Inst, IDLoc, Operands, Out);
674
case Match_MissingFeature: {
675
assert(MissingFeatures.any() && "Unknown missing features!");
676
ListSeparator LS;
677
std::string Msg = "instruction requires the following: ";
678
for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
679
if (MissingFeatures[i]) {
680
Msg += LS;
681
Msg += getSubtargetFeatureName(i);
682
}
683
}
684
return Error(IDLoc, Msg);
685
}
686
case Match_MnemonicFail: {
687
FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
688
std::string Suggestion =
689
CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
690
return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
691
}
692
case Match_InvalidTiedOperand:
693
case Match_InvalidOperand: {
694
SMLoc ErrorLoc = IDLoc;
695
if (ErrorInfo != ~0U) {
696
if (ErrorInfo >= Operands.size())
697
return Error(ErrorLoc, "too few operands for instruction");
698
699
ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
700
if (ErrorLoc == SMLoc())
701
ErrorLoc = IDLoc;
702
}
703
return Error(ErrorLoc, "invalid operand for instruction");
704
}
705
}
706
707
// Handle the case when the error message is of specific type
708
// other than the generic Match_InvalidOperand, and the
709
// corresponding operand is missing.
710
if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
711
SMLoc ErrorLoc = IDLoc;
712
if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
713
return Error(ErrorLoc, "too few operands for instruction");
714
}
715
716
switch (Result) {
717
default:
718
break;
719
case Match_InvalidSImm8:
720
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
721
(1 << 7) - 1);
722
case Match_InvalidOImm3:
723
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
724
case Match_InvalidOImm4:
725
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
726
case Match_InvalidOImm5:
727
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
728
case Match_InvalidOImm6:
729
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
730
case Match_InvalidOImm8:
731
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
732
case Match_InvalidOImm12:
733
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
734
case Match_InvalidOImm16:
735
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
736
case Match_InvalidUImm1:
737
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
738
case Match_InvalidUImm2:
739
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
740
case Match_InvalidUImm3:
741
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
742
case Match_InvalidUImm4:
743
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
744
case Match_InvalidUImm5:
745
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
746
case Match_InvalidUImm6:
747
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
748
case Match_InvalidUImm7:
749
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
750
case Match_InvalidUImm8:
751
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
752
case Match_InvalidUImm12:
753
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
754
case Match_InvalidUImm16:
755
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
756
case Match_InvalidUImm5Shift1:
757
return generateImmOutOfRangeError(
758
Operands, ErrorInfo, 0, (1 << 5) - 2,
759
"immediate must be a multiple of 2 bytes in the range");
760
case Match_InvalidUImm12Shift1:
761
return generateImmOutOfRangeError(
762
Operands, ErrorInfo, 0, (1 << 12) - 2,
763
"immediate must be a multiple of 2 bytes in the range");
764
case Match_InvalidUImm5Shift2:
765
return generateImmOutOfRangeError(
766
Operands, ErrorInfo, 0, (1 << 5) - 4,
767
"immediate must be a multiple of 4 bytes in the range");
768
case Match_InvalidUImm7Shift1:
769
return generateImmOutOfRangeError(
770
Operands, ErrorInfo, 0, (1 << 7) - 2,
771
"immediate must be a multiple of 2 bytes in the range");
772
case Match_InvalidUImm7Shift2:
773
return generateImmOutOfRangeError(
774
Operands, ErrorInfo, 0, (1 << 7) - 4,
775
"immediate must be a multiple of 4 bytes in the range");
776
case Match_InvalidUImm8Shift2:
777
return generateImmOutOfRangeError(
778
Operands, ErrorInfo, 0, (1 << 8) - 4,
779
"immediate must be a multiple of 4 bytes in the range");
780
case Match_InvalidUImm8Shift3:
781
return generateImmOutOfRangeError(
782
Operands, ErrorInfo, 0, (1 << 8) - 8,
783
"immediate must be a multiple of 8 bytes in the range");
784
case Match_InvalidUImm8Shift8:
785
return generateImmOutOfRangeError(
786
Operands, ErrorInfo, 0, (1 << 8) - 256,
787
"immediate must be a multiple of 256 bytes in the range");
788
case Match_InvalidUImm12Shift2:
789
return generateImmOutOfRangeError(
790
Operands, ErrorInfo, 0, (1 << 12) - 4,
791
"immediate must be a multiple of 4 bytes in the range");
792
case Match_InvalidCSKYSymbol: {
793
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
794
return Error(ErrorLoc, "operand must be a symbol name");
795
}
796
case Match_InvalidConstpool: {
797
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
798
return Error(ErrorLoc, "operand must be a constpool symbol name");
799
}
800
case Match_InvalidPSRFlag: {
801
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
802
return Error(ErrorLoc, "psrset operand is not valid");
803
}
804
case Match_InvalidRegSeq: {
805
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
806
return Error(ErrorLoc, "Register sequence is not valid");
807
}
808
case Match_InvalidRegOutOfRange: {
809
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
810
return Error(ErrorLoc, "register is out of range");
811
}
812
case Match_RequiresSameSrcAndDst: {
813
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
814
return Error(ErrorLoc, "src and dst operand must be same");
815
}
816
case Match_InvalidRegList: {
817
SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
818
return Error(ErrorLoc, "invalid register list");
819
}
820
}
821
LLVM_DEBUG(dbgs() << "Result = " << Result);
822
llvm_unreachable("Unknown match type detected!");
823
}
824
825
bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
826
Inst.setLoc(IDLoc);
827
828
unsigned Opcode;
829
MCOperand Op;
830
if (Inst.getOpcode() == CSKY::PseudoLRW16)
831
Opcode = CSKY::LRW16;
832
else
833
Opcode = CSKY::LRW32;
834
835
if (Inst.getOperand(1).isImm()) {
836
if (isUInt<8>(Inst.getOperand(1).getImm()) &&
837
Inst.getOperand(0).getReg() <= CSKY::R7) {
838
Opcode = CSKY::MOVI16;
839
} else if (getSTI().hasFeature(CSKY::HasE2) &&
840
isUInt<16>(Inst.getOperand(1).getImm())) {
841
Opcode = CSKY::MOVI32;
842
} else {
843
auto *Expr = getTargetStreamer().addConstantPoolEntry(
844
MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),
845
Inst.getLoc());
846
Inst.erase(std::prev(Inst.end()));
847
Inst.addOperand(MCOperand::createExpr(Expr));
848
}
849
} else {
850
const MCExpr *AdjustExpr = nullptr;
851
if (const CSKYMCExpr *CSKYExpr =
852
dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) {
853
if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD ||
854
CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE ||
855
CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) {
856
MCSymbol *Dot = getContext().createNamedTempSymbol();
857
Out.emitLabel(Dot);
858
AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());
859
}
860
}
861
auto *Expr = getTargetStreamer().addConstantPoolEntry(
862
Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);
863
Inst.erase(std::prev(Inst.end()));
864
Inst.addOperand(MCOperand::createExpr(Expr));
865
}
866
867
Inst.setOpcode(Opcode);
868
869
Out.emitInstruction(Inst, getSTI());
870
return false;
871
}
872
873
bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
874
Inst.setLoc(IDLoc);
875
876
if (Inst.getOperand(0).isImm()) {
877
const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
878
MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
879
Inst.getLoc());
880
Inst.setOpcode(CSKY::JSRI32);
881
Inst.erase(std::prev(Inst.end()));
882
Inst.addOperand(MCOperand::createExpr(Expr));
883
} else {
884
const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
885
Inst.getOperand(0).getExpr(), Inst.getLoc());
886
Inst.setOpcode(CSKY::JBSR32);
887
Inst.addOperand(MCOperand::createExpr(Expr));
888
}
889
890
Out.emitInstruction(Inst, getSTI());
891
return false;
892
}
893
894
bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
895
Inst.setLoc(IDLoc);
896
897
if (Inst.getOperand(0).isImm()) {
898
const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
899
MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
900
Inst.getLoc());
901
Inst.setOpcode(CSKY::JMPI32);
902
Inst.erase(std::prev(Inst.end()));
903
Inst.addOperand(MCOperand::createExpr(Expr));
904
} else {
905
const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
906
Inst.getOperand(0).getExpr(), Inst.getLoc());
907
Inst.setOpcode(CSKY::JBR32);
908
Inst.addOperand(MCOperand::createExpr(Expr));
909
}
910
911
Out.emitInstruction(Inst, getSTI());
912
return false;
913
}
914
915
bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
916
OperandVector &Operands,
917
MCStreamer &Out) {
918
919
switch (Inst.getOpcode()) {
920
default:
921
break;
922
case CSKY::LDQ32:
923
case CSKY::STQ32:
924
if (Inst.getOperand(1).getReg() != CSKY::R4 ||
925
Inst.getOperand(2).getReg() != CSKY::R7) {
926
return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");
927
}
928
Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);
929
break;
930
case CSKY::SEXT32:
931
case CSKY::ZEXT32:
932
if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())
933
return Error(IDLoc, "msb must be greater or equal to lsb");
934
break;
935
case CSKY::INS32:
936
if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())
937
return Error(IDLoc, "msb must be greater or equal to lsb");
938
break;
939
case CSKY::IDLY32:
940
if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)
941
return Error(IDLoc, "n must be in range [0,32]");
942
break;
943
case CSKY::ADDC32:
944
case CSKY::SUBC32:
945
case CSKY::ADDC16:
946
case CSKY::SUBC16:
947
Inst.erase(std::next(Inst.begin()));
948
Inst.erase(std::prev(Inst.end()));
949
Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));
950
Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
951
break;
952
case CSKY::CMPNEI32:
953
case CSKY::CMPNEI16:
954
case CSKY::CMPNE32:
955
case CSKY::CMPNE16:
956
case CSKY::CMPHSI32:
957
case CSKY::CMPHSI16:
958
case CSKY::CMPHS32:
959
case CSKY::CMPHS16:
960
case CSKY::CMPLTI32:
961
case CSKY::CMPLTI16:
962
case CSKY::CMPLT32:
963
case CSKY::CMPLT16:
964
case CSKY::BTSTI32:
965
Inst.erase(Inst.begin());
966
Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));
967
break;
968
case CSKY::MVCV32:
969
Inst.erase(std::next(Inst.begin()));
970
Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
971
break;
972
case CSKY::PseudoLRW16:
973
case CSKY::PseudoLRW32:
974
return processLRW(Inst, IDLoc, Out);
975
case CSKY::PseudoJSRI32:
976
return processJSRI(Inst, IDLoc, Out);
977
case CSKY::PseudoJMPI32:
978
return processJMPI(Inst, IDLoc, Out);
979
case CSKY::JBSR32:
980
case CSKY::JBR16:
981
case CSKY::JBT16:
982
case CSKY::JBF16:
983
case CSKY::JBR32:
984
case CSKY::JBT32:
985
case CSKY::JBF32:
986
unsigned Num = Inst.getNumOperands() - 1;
987
assert(Inst.getOperand(Num).isExpr());
988
989
const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
990
Inst.getOperand(Num).getExpr(), Inst.getLoc());
991
992
Inst.addOperand(MCOperand::createExpr(Expr));
993
break;
994
}
995
996
emitToStreamer(Out, Inst);
997
return false;
998
}
999
1000
// Attempts to match Name as a register (either using the default name or
1001
// alternative ABI names), setting RegNo to the matching register. Upon
1002
// failure, returns true and sets RegNo to 0.
1003
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg,
1004
StringRef Name) {
1005
Reg = MatchRegisterName(Name);
1006
1007
if (Reg == CSKY::NoRegister)
1008
Reg = MatchRegisterAltName(Name);
1009
1010
return Reg == CSKY::NoRegister;
1011
}
1012
1013
bool CSKYAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1014
SMLoc &EndLoc) {
1015
const AsmToken &Tok = getParser().getTok();
1016
StartLoc = Tok.getLoc();
1017
EndLoc = Tok.getEndLoc();
1018
StringRef Name = getLexer().getTok().getIdentifier();
1019
1020
if (!matchRegisterNameHelper(getSTI(), Reg, Name)) {
1021
getParser().Lex(); // Eat identifier token.
1022
return false;
1023
}
1024
1025
return true;
1026
}
1027
1028
ParseStatus CSKYAsmParser::parseRegister(OperandVector &Operands) {
1029
SMLoc S = getLoc();
1030
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1031
1032
switch (getLexer().getKind()) {
1033
default:
1034
return ParseStatus::NoMatch;
1035
case AsmToken::Identifier: {
1036
StringRef Name = getLexer().getTok().getIdentifier();
1037
MCRegister Reg;
1038
1039
if (matchRegisterNameHelper(getSTI(), Reg, Name))
1040
return ParseStatus::NoMatch;
1041
1042
getLexer().Lex();
1043
Operands.push_back(CSKYOperand::createReg(Reg, S, E));
1044
1045
return ParseStatus::Success;
1046
}
1047
}
1048
}
1049
1050
ParseStatus CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
1051
assert(getLexer().is(AsmToken::LParen));
1052
1053
Operands.push_back(CSKYOperand::createToken("(", getLoc()));
1054
1055
auto Tok = getParser().Lex(); // Eat '('
1056
1057
if (!parseRegister(Operands).isSuccess()) {
1058
getLexer().UnLex(Tok);
1059
Operands.pop_back();
1060
return ParseStatus::NoMatch;
1061
}
1062
1063
if (getLexer().is(AsmToken::RParen)) {
1064
Operands.push_back(CSKYOperand::createToken(")", getLoc()));
1065
getParser().Lex(); // Eat ')'
1066
return ParseStatus::Success;
1067
}
1068
1069
if (getLexer().isNot(AsmToken::Comma))
1070
return Error(getLoc(), "expected ','");
1071
1072
getParser().Lex(); // Eat ','
1073
1074
if (parseRegister(Operands).isSuccess()) {
1075
if (getLexer().isNot(AsmToken::LessLess))
1076
return Error(getLoc(), "expected '<<'");
1077
1078
Operands.push_back(CSKYOperand::createToken("<<", getLoc()));
1079
1080
getParser().Lex(); // Eat '<<'
1081
1082
if (!parseImmediate(Operands).isSuccess())
1083
return Error(getLoc(), "expected imm");
1084
1085
} else if (!parseImmediate(Operands).isSuccess()) {
1086
return Error(getLoc(), "expected imm");
1087
}
1088
1089
if (getLexer().isNot(AsmToken::RParen))
1090
return Error(getLoc(), "expected ')'");
1091
1092
Operands.push_back(CSKYOperand::createToken(")", getLoc()));
1093
1094
getParser().Lex(); // Eat ')'
1095
1096
return ParseStatus::Success;
1097
}
1098
1099
ParseStatus CSKYAsmParser::parseImmediate(OperandVector &Operands) {
1100
switch (getLexer().getKind()) {
1101
default:
1102
return ParseStatus::NoMatch;
1103
case AsmToken::LParen:
1104
case AsmToken::Minus:
1105
case AsmToken::Plus:
1106
case AsmToken::Integer:
1107
case AsmToken::String:
1108
break;
1109
}
1110
1111
const MCExpr *IdVal;
1112
SMLoc S = getLoc();
1113
if (getParser().parseExpression(IdVal))
1114
return Error(getLoc(), "unknown expression");
1115
1116
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1117
Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
1118
return ParseStatus::Success;
1119
}
1120
1121
/// Looks at a token type and creates the relevant operand from this
1122
/// information, adding to Operands. If operand was parsed, returns false, else
1123
/// true.
1124
bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1125
// Check if the current operand has a custom associated parser, if so, try to
1126
// custom parse the operand, or fallback to the general approach.
1127
ParseStatus Result =
1128
MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1129
if (Result.isSuccess())
1130
return false;
1131
if (Result.isFailure())
1132
return true;
1133
1134
// Attempt to parse token as register
1135
auto Res = parseRegister(Operands);
1136
if (Res.isSuccess())
1137
return false;
1138
if (Res.isFailure())
1139
return true;
1140
1141
// Attempt to parse token as (register, imm)
1142
if (getLexer().is(AsmToken::LParen)) {
1143
Res = parseBaseRegImm(Operands);
1144
if (Res.isSuccess())
1145
return false;
1146
if (Res.isFailure())
1147
return true;
1148
}
1149
1150
Res = parseImmediate(Operands);
1151
if (Res.isSuccess())
1152
return false;
1153
if (Res.isFailure())
1154
return true;
1155
1156
// Finally we have exhausted all options and must declare defeat.
1157
Error(getLoc(), "unknown operand");
1158
return true;
1159
}
1160
1161
ParseStatus CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
1162
SMLoc S = getLoc();
1163
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1164
const MCExpr *Res;
1165
1166
if (getLexer().getKind() != AsmToken::Identifier)
1167
return ParseStatus::NoMatch;
1168
1169
StringRef Identifier;
1170
AsmToken Tok = getLexer().getTok();
1171
1172
if (getParser().parseIdentifier(Identifier))
1173
return Error(getLoc(), "unknown identifier");
1174
1175
CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
1176
if (Identifier.consume_back("@GOT"))
1177
Kind = CSKYMCExpr::VK_CSKY_GOT;
1178
else if (Identifier.consume_back("@GOTOFF"))
1179
Kind = CSKYMCExpr::VK_CSKY_GOTOFF;
1180
else if (Identifier.consume_back("@PLT"))
1181
Kind = CSKYMCExpr::VK_CSKY_PLT;
1182
else if (Identifier.consume_back("@GOTPC"))
1183
Kind = CSKYMCExpr::VK_CSKY_GOTPC;
1184
else if (Identifier.consume_back("@TLSGD32"))
1185
Kind = CSKYMCExpr::VK_CSKY_TLSGD;
1186
else if (Identifier.consume_back("@GOTTPOFF"))
1187
Kind = CSKYMCExpr::VK_CSKY_TLSIE;
1188
else if (Identifier.consume_back("@TPOFF"))
1189
Kind = CSKYMCExpr::VK_CSKY_TLSLE;
1190
else if (Identifier.consume_back("@TLSLDM32"))
1191
Kind = CSKYMCExpr::VK_CSKY_TLSLDM;
1192
else if (Identifier.consume_back("@TLSLDO32"))
1193
Kind = CSKYMCExpr::VK_CSKY_TLSLDO;
1194
1195
MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1196
1197
if (!Sym)
1198
Sym = getContext().getOrCreateSymbol(Identifier);
1199
1200
if (Sym->isVariable()) {
1201
const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1202
if (!isa<MCSymbolRefExpr>(V)) {
1203
getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1204
return Error(getLoc(), "unknown symbol");
1205
}
1206
Res = V;
1207
} else
1208
Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1209
1210
MCBinaryExpr::Opcode Opcode;
1211
switch (getLexer().getKind()) {
1212
default:
1213
if (Kind != CSKYMCExpr::VK_CSKY_None)
1214
Res = CSKYMCExpr::create(Res, Kind, getContext());
1215
1216
Operands.push_back(CSKYOperand::createImm(Res, S, E));
1217
return ParseStatus::Success;
1218
case AsmToken::Plus:
1219
Opcode = MCBinaryExpr::Add;
1220
break;
1221
case AsmToken::Minus:
1222
Opcode = MCBinaryExpr::Sub;
1223
break;
1224
}
1225
1226
getLexer().Lex(); // eat + or -
1227
1228
const MCExpr *Expr;
1229
if (getParser().parseExpression(Expr))
1230
return Error(getLoc(), "unknown expression");
1231
Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1232
Operands.push_back(CSKYOperand::createImm(Res, S, E));
1233
return ParseStatus::Success;
1234
}
1235
1236
ParseStatus CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {
1237
SMLoc S = getLoc();
1238
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1239
const MCExpr *Res;
1240
1241
if (!parseOptionalToken(AsmToken::LBrac))
1242
return ParseStatus::NoMatch;
1243
if (getLexer().getKind() != AsmToken::Identifier) {
1244
const MCExpr *Expr;
1245
if (getParser().parseExpression(Expr))
1246
return Error(getLoc(), "unknown expression");
1247
1248
if (parseToken(AsmToken::RBrac, "expected ']'"))
1249
return ParseStatus::Failure;
1250
1251
Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1252
return ParseStatus::Success;
1253
}
1254
1255
AsmToken Tok = getLexer().getTok();
1256
StringRef Identifier;
1257
1258
if (getParser().parseIdentifier(Identifier))
1259
return Error(getLoc(), "unknown identifier " + Identifier);
1260
1261
CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
1262
if (Identifier.consume_back("@GOT"))
1263
Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4;
1264
else if (Identifier.consume_back("@PLT"))
1265
Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4;
1266
1267
MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1268
1269
if (!Sym)
1270
Sym = getContext().getOrCreateSymbol(Identifier);
1271
1272
if (Sym->isVariable()) {
1273
const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1274
if (!isa<MCSymbolRefExpr>(V)) {
1275
getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1276
return Error(getLoc(), "unknown symbol");
1277
}
1278
Res = V;
1279
} else {
1280
Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1281
}
1282
1283
MCBinaryExpr::Opcode Opcode;
1284
switch (getLexer().getKind()) {
1285
default:
1286
return Error(getLoc(), "unknown symbol");
1287
case AsmToken::RBrac:
1288
1289
getLexer().Lex(); // Eat ']'.
1290
1291
if (Kind != CSKYMCExpr::VK_CSKY_None)
1292
Res = CSKYMCExpr::create(Res, Kind, getContext());
1293
1294
Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1295
return ParseStatus::Success;
1296
case AsmToken::Plus:
1297
Opcode = MCBinaryExpr::Add;
1298
break;
1299
case AsmToken::Minus:
1300
Opcode = MCBinaryExpr::Sub;
1301
break;
1302
}
1303
1304
getLexer().Lex(); // eat + or -
1305
1306
const MCExpr *Expr;
1307
if (getParser().parseExpression(Expr))
1308
return Error(getLoc(), "unknown expression");
1309
if (parseToken(AsmToken::RBrac, "expected ']'"))
1310
return ParseStatus::Failure;
1311
1312
Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1313
Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1314
return ParseStatus::Success;
1315
}
1316
1317
ParseStatus CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
1318
SMLoc S = getLoc();
1319
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1320
const MCExpr *Res;
1321
1322
if (!parseOptionalToken(AsmToken::LBrac))
1323
return ParseStatus::NoMatch;
1324
1325
if (getLexer().getKind() != AsmToken::Identifier) {
1326
const MCExpr *Expr;
1327
if (getParser().parseExpression(Expr))
1328
return Error(getLoc(), "unknown expression");
1329
if (parseToken(AsmToken::RBrac))
1330
return ParseStatus::Failure;
1331
1332
Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1333
return ParseStatus::Success;
1334
}
1335
1336
AsmToken Tok = getLexer().getTok();
1337
StringRef Identifier;
1338
1339
if (getParser().parseIdentifier(Identifier))
1340
return Error(getLoc(), "unknown identifier");
1341
1342
MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1343
1344
if (!Sym)
1345
Sym = getContext().getOrCreateSymbol(Identifier);
1346
1347
if (Sym->isVariable()) {
1348
const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1349
if (!isa<MCSymbolRefExpr>(V)) {
1350
getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1351
return Error(getLoc(), "unknown symbol");
1352
}
1353
Res = V;
1354
} else {
1355
Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1356
}
1357
1358
MCBinaryExpr::Opcode Opcode;
1359
switch (getLexer().getKind()) {
1360
default:
1361
return Error(getLoc(), "unknown symbol");
1362
case AsmToken::RBrac:
1363
1364
getLexer().Lex(); // Eat ']'.
1365
1366
Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1367
return ParseStatus::Success;
1368
case AsmToken::Plus:
1369
Opcode = MCBinaryExpr::Add;
1370
break;
1371
case AsmToken::Minus:
1372
Opcode = MCBinaryExpr::Sub;
1373
break;
1374
}
1375
1376
getLexer().Lex(); // eat + or -
1377
1378
const MCExpr *Expr;
1379
if (getParser().parseExpression(Expr))
1380
return Error(getLoc(), "unknown expression");
1381
if (parseToken(AsmToken::RBrac, "expected ']'"))
1382
return ParseStatus::Failure;
1383
1384
Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1385
Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1386
return ParseStatus::Success;
1387
}
1388
1389
ParseStatus CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {
1390
SMLoc S = getLoc();
1391
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1392
1393
unsigned Flag = 0;
1394
1395
while (getLexer().isNot(AsmToken::EndOfStatement)) {
1396
StringRef Identifier;
1397
if (getParser().parseIdentifier(Identifier))
1398
return Error(getLoc(), "unknown identifier " + Identifier);
1399
1400
if (Identifier == "sie")
1401
Flag = (1 << 4) | Flag;
1402
else if (Identifier == "ee")
1403
Flag = (1 << 3) | Flag;
1404
else if (Identifier == "ie")
1405
Flag = (1 << 2) | Flag;
1406
else if (Identifier == "fe")
1407
Flag = (1 << 1) | Flag;
1408
else if (Identifier == "af")
1409
Flag = (1 << 0) | Flag;
1410
else
1411
return Error(getLoc(), "expected " + Identifier);
1412
1413
if (getLexer().is(AsmToken::EndOfStatement))
1414
break;
1415
1416
if (parseToken(AsmToken::Comma, "expected ','"))
1417
return ParseStatus::Failure;
1418
}
1419
1420
Operands.push_back(
1421
CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));
1422
return ParseStatus::Success;
1423
}
1424
1425
ParseStatus CSKYAsmParser::parseRegSeq(OperandVector &Operands) {
1426
SMLoc S = getLoc();
1427
1428
if (!parseRegister(Operands).isSuccess())
1429
return ParseStatus::NoMatch;
1430
1431
auto Ry = Operands.back()->getReg();
1432
Operands.pop_back();
1433
1434
if (parseToken(AsmToken::Minus, "expected '-'"))
1435
return ParseStatus::Failure;
1436
if (!parseRegister(Operands).isSuccess())
1437
return Error(getLoc(), "invalid register");
1438
1439
auto Rz = Operands.back()->getReg();
1440
Operands.pop_back();
1441
1442
Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1443
return ParseStatus::Success;
1444
}
1445
1446
ParseStatus CSKYAsmParser::parseRegList(OperandVector &Operands) {
1447
SMLoc S = getLoc();
1448
1449
SmallVector<unsigned, 4> reglist;
1450
1451
while (true) {
1452
1453
if (!parseRegister(Operands).isSuccess())
1454
return Error(getLoc(), "invalid register");
1455
1456
auto Ry = Operands.back()->getReg();
1457
Operands.pop_back();
1458
1459
if (parseOptionalToken(AsmToken::Minus)) {
1460
if (!parseRegister(Operands).isSuccess())
1461
return Error(getLoc(), "invalid register");
1462
1463
auto Rz = Operands.back()->getReg();
1464
Operands.pop_back();
1465
1466
reglist.push_back(Ry);
1467
reglist.push_back(Rz);
1468
1469
if (getLexer().is(AsmToken::EndOfStatement))
1470
break;
1471
(void)parseOptionalToken(AsmToken::Comma);
1472
} else if (parseOptionalToken(AsmToken::Comma)) {
1473
reglist.push_back(Ry);
1474
reglist.push_back(Ry);
1475
} else if (getLexer().is(AsmToken::EndOfStatement)) {
1476
reglist.push_back(Ry);
1477
reglist.push_back(Ry);
1478
break;
1479
} else {
1480
return Error(getLoc(), "invalid register list");
1481
}
1482
}
1483
1484
Operands.push_back(CSKYOperand::createRegList(reglist, S));
1485
return ParseStatus::Success;
1486
}
1487
1488
bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1489
SMLoc NameLoc, OperandVector &Operands) {
1490
// First operand is token for instruction.
1491
Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
1492
1493
// If there are no more operands, then finish.
1494
if (getLexer().is(AsmToken::EndOfStatement))
1495
return false;
1496
1497
// Parse first operand.
1498
if (parseOperand(Operands, Name))
1499
return true;
1500
1501
// Parse until end of statement, consuming commas between operands.
1502
while (parseOptionalToken(AsmToken::Comma))
1503
if (parseOperand(Operands, Name))
1504
return true;
1505
1506
if (getLexer().isNot(AsmToken::EndOfStatement)) {
1507
SMLoc Loc = getLexer().getLoc();
1508
getParser().eatToEndOfStatement();
1509
return Error(Loc, "unexpected token");
1510
}
1511
1512
getParser().Lex(); // Consume the EndOfStatement.
1513
return false;
1514
}
1515
1516
ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1517
SMLoc &EndLoc) {
1518
const AsmToken &Tok = getParser().getTok();
1519
StartLoc = Tok.getLoc();
1520
EndLoc = Tok.getEndLoc();
1521
1522
StringRef Name = getLexer().getTok().getIdentifier();
1523
1524
if (matchRegisterNameHelper(getSTI(), Reg, Name))
1525
return ParseStatus::NoMatch;
1526
1527
getParser().Lex(); // Eat identifier token.
1528
return ParseStatus::Success;
1529
}
1530
1531
ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {
1532
StringRef IDVal = DirectiveID.getString();
1533
1534
if (IDVal == ".csky_attribute")
1535
return parseDirectiveAttribute();
1536
1537
return ParseStatus::NoMatch;
1538
}
1539
1540
/// parseDirectiveAttribute
1541
/// ::= .attribute expression ',' ( expression | "string" )
1542
bool CSKYAsmParser::parseDirectiveAttribute() {
1543
MCAsmParser &Parser = getParser();
1544
int64_t Tag;
1545
SMLoc TagLoc;
1546
TagLoc = Parser.getTok().getLoc();
1547
if (Parser.getTok().is(AsmToken::Identifier)) {
1548
StringRef Name = Parser.getTok().getIdentifier();
1549
std::optional<unsigned> Ret =
1550
ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags());
1551
if (!Ret)
1552
return Error(TagLoc, "attribute name not recognised: " + Name);
1553
Tag = *Ret;
1554
Parser.Lex();
1555
} else {
1556
const MCExpr *AttrExpr;
1557
1558
TagLoc = Parser.getTok().getLoc();
1559
if (Parser.parseExpression(AttrExpr))
1560
return true;
1561
1562
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
1563
if (!CE)
1564
return Error(TagLoc, "expected numeric constant");
1565
1566
Tag = CE->getValue();
1567
}
1568
1569
if (Parser.parseComma())
1570
return true;
1571
1572
StringRef StringValue;
1573
int64_t IntegerValue = 0;
1574
bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) &&
1575
(Tag != CSKYAttrs::CSKY_CPU_NAME) &&
1576
(Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE));
1577
1578
SMLoc ValueExprLoc = Parser.getTok().getLoc();
1579
if (IsIntegerValue) {
1580
const MCExpr *ValueExpr;
1581
if (Parser.parseExpression(ValueExpr))
1582
return true;
1583
1584
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
1585
if (!CE)
1586
return Error(ValueExprLoc, "expected numeric constant");
1587
IntegerValue = CE->getValue();
1588
} else {
1589
if (Parser.getTok().isNot(AsmToken::String))
1590
return Error(Parser.getTok().getLoc(), "expected string constant");
1591
1592
StringValue = Parser.getTok().getStringContents();
1593
Parser.Lex();
1594
}
1595
1596
if (Parser.parseEOL())
1597
return true;
1598
1599
if (IsIntegerValue)
1600
getTargetStreamer().emitAttribute(Tag, IntegerValue);
1601
else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME)
1602
getTargetStreamer().emitTextAttribute(Tag, StringValue);
1603
else {
1604
CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME)
1605
? CSKY::parseArch(StringValue)
1606
: CSKY::parseCPUArch(StringValue);
1607
if (ID == CSKY::ArchKind::INVALID)
1608
return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME)
1609
? "unknown arch name"
1610
: "unknown cpu name");
1611
1612
getTargetStreamer().emitTextAttribute(Tag, StringValue);
1613
}
1614
1615
return false;
1616
}
1617
1618
unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1619
unsigned Kind) {
1620
CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);
1621
1622
if (!Op.isReg())
1623
return Match_InvalidOperand;
1624
1625
MCRegister Reg = Op.getReg();
1626
1627
if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {
1628
// As the parser couldn't differentiate an FPR64 from an FPR32, coerce the
1629
// register from FPR32 to FPR64 if necessary.
1630
if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1631
Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
1632
if (Kind == MCK_sFPR64 &&
1633
(Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))
1634
return Match_InvalidRegOutOfRange;
1635
if (Kind == MCK_FPR64 &&
1636
(Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))
1637
return Match_InvalidRegOutOfRange;
1638
return Match_Success;
1639
}
1640
}
1641
1642
if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {
1643
if (Kind == MCK_GPRPair) {
1644
Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;
1645
return Match_Success;
1646
}
1647
}
1648
1649
return Match_InvalidOperand;
1650
}
1651
1652
void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1653
MCInst CInst;
1654
bool Res = false;
1655
if (EnableCompressedInst)
1656
Res = compressInst(CInst, Inst, getSTI());
1657
if (Res)
1658
++CSKYNumInstrsCompressed;
1659
S.emitInstruction((Res ? CInst : Inst), getSTI());
1660
}
1661
1662
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {
1663
RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());
1664
}
1665
1666