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