Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.0.0git
LanaiAsmParser.cpp
Go to the documentation of this file.
1//===-- LanaiAsmParser.cpp - Parse Lanai 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 "LanaiAluCode.h"
10#include "LanaiCondCode.h"
11#include "LanaiInstrInfo.h"
14#include "llvm/ADT/StringRef.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCStreamer.h"
25#include "llvm/MC/MCSymbol.h"
31#include "llvm/Support/SMLoc.h"
33#include <cassert>
34#include <cstddef>
35#include <cstdint>
36#include <memory>
37#include <optional>
38
39using namespace llvm;
40
41// Auto-generated by TableGen
43
44namespace {
45
46struct LanaiOperand;
47
48class LanaiAsmParser : public MCTargetAsmParser {
49 // Parse operands
50 std::unique_ptr<LanaiOperand> parseRegister(bool RestoreOnFailure = false);
51
52 std::unique_ptr<LanaiOperand> parseImmediate();
53
54 std::unique_ptr<LanaiOperand> parseIdentifier();
55
56 unsigned parseAluOperator(bool PreOp, bool PostOp);
57
58 // Split the mnemonic stripping conditional code and quantifiers
59 StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
61
62 bool parsePrePost(StringRef Type, int *OffsetValue);
63
64 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
65 SMLoc NameLoc, OperandVector &Operands) override;
66
67 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
68 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
69 SMLoc &EndLoc) override;
70
71 bool matchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
74 bool MatchingInlineAsm) override;
75
76// Auto-generated instruction matching functions
77#define GET_ASSEMBLER_HEADER
78#include "LanaiGenAsmMatcher.inc"
79
80 ParseStatus parseOperand(OperandVector *Operands, StringRef Mnemonic);
81
82 ParseStatus parseMemoryOperand(OperandVector &Operands);
83
84public:
85 LanaiAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
86 const MCInstrInfo &MII, const MCTargetOptions &Options)
87 : MCTargetAsmParser(Options, STI, MII), Parser(Parser),
88 Lexer(Parser.getLexer()), SubtargetInfo(STI) {
89 setAvailableFeatures(
90 ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
91 }
92
93private:
94 MCAsmParser &Parser;
95 AsmLexer &Lexer;
96
97 const MCSubtargetInfo &SubtargetInfo;
98};
99
100// LanaiOperand - Instances of this class represented a parsed machine
101// instruction
102struct LanaiOperand : public MCParsedAsmOperand {
103 enum KindTy {
104 TOKEN,
105 REGISTER,
106 IMMEDIATE,
107 MEMORY_IMM,
108 MEMORY_REG_IMM,
109 MEMORY_REG_REG,
110 } Kind;
111
112 SMLoc StartLoc, EndLoc;
113
114 struct Token {
115 const char *Data;
116 unsigned Length;
117 };
118
119 struct RegOp {
120 MCRegister RegNum;
121 };
122
123 struct ImmOp {
124 const MCExpr *Value;
125 };
126
127 struct MemOp {
128 MCRegister BaseReg;
129 MCRegister OffsetReg;
130 unsigned AluOp;
131 const MCExpr *Offset;
132 };
133
134 union {
135 struct Token Tok;
136 struct RegOp Reg;
137 struct ImmOp Imm;
138 struct MemOp Mem;
139 };
140
141 explicit LanaiOperand(KindTy Kind) : Kind(Kind) {}
142
143public:
144 // The functions below are used by the autogenerated ASM matcher and hence to
145 // be of the form expected.
146
147 // getStartLoc - Gets location of the first token of this operand
148 SMLoc getStartLoc() const override { return StartLoc; }
149
150 // getEndLoc - Gets location of the last token of this operand
151 SMLoc getEndLoc() const override { return EndLoc; }
152
153 MCRegister getReg() const override {
154 assert(isReg() && "Invalid type access!");
155 return Reg.RegNum;
156 }
157
158 const MCExpr *getImm() const {
159 assert(isImm() && "Invalid type access!");
160 return Imm.Value;
161 }
162
163 StringRef getToken() const {
164 assert(isToken() && "Invalid type access!");
165 return StringRef(Tok.Data, Tok.Length);
166 }
167
168 MCRegister getMemBaseReg() const {
169 assert(isMem() && "Invalid type access!");
170 return Mem.BaseReg;
171 }
172
173 MCRegister getMemOffsetReg() const {
174 assert(isMem() && "Invalid type access!");
175 return Mem.OffsetReg;
176 }
177
178 const MCExpr *getMemOffset() const {
179 assert(isMem() && "Invalid type access!");
180 return Mem.Offset;
181 }
182
183 unsigned getMemOp() const {
184 assert(isMem() && "Invalid type access!");
185 return Mem.AluOp;
186 }
187
188 // Functions for testing operand type
189 bool isReg() const override { return Kind == REGISTER; }
190
191 bool isImm() const override { return Kind == IMMEDIATE; }
192
193 bool isMem() const override {
194 return isMemImm() || isMemRegImm() || isMemRegReg();
195 }
196
197 bool isMemImm() const { return Kind == MEMORY_IMM; }
198
199 bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }
200
201 bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }
202
203 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
204
205 bool isToken() const override { return Kind == TOKEN; }
206
207 bool isBrImm() {
208 if (!isImm())
209 return false;
210
211 // Constant case
212 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm.Value);
213 if (!MCE)
214 return true;
215 int64_t Value = MCE->getValue();
216 // Check if value fits in 25 bits with 2 least significant bits 0.
217 return isShiftedUInt<23, 2>(static_cast<int32_t>(Value));
218 }
219
220 bool isBrTarget() { return isBrImm() || isToken(); }
221
222 bool isCallTarget() { return isImm() || isToken(); }
223
224 bool isHiImm16() {
225 if (!isImm())
226 return false;
227
228 // Constant case
229 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
230 int64_t Value = ConstExpr->getValue();
231 return Value != 0 && isShiftedUInt<16, 16>(Value);
232 }
233
234 // Symbolic reference expression
235 if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
236 return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_HI;
237
238 // Binary expression
239 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
240 if (const auto *SymbolRefExpr =
241 dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
242 return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_HI;
243
244 return false;
245 }
246
247 bool isHiImm16And() {
248 if (!isImm())
249 return false;
250
251 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
252 if (ConstExpr) {
253 int64_t Value = ConstExpr->getValue();
254 // Check if in the form 0xXYZWffff
255 return (Value != 0) && ((Value & ~0xffff0000) == 0xffff);
256 }
257 return false;
258 }
259
260 bool isLoImm16() {
261 if (!isImm())
262 return false;
263
264 // Constant case
265 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
266 int64_t Value = ConstExpr->getValue();
267 // Check if value fits in 16 bits
268 return isUInt<16>(static_cast<int32_t>(Value));
269 }
270
271 // Symbolic reference expression
272 if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
273 return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
274
275 // Binary expression
276 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
277 if (const auto *SymbolRefExpr =
278 dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
279 return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
280
281 return false;
282 }
283
284 bool isLoImm16Signed() {
285 if (!isImm())
286 return false;
287
288 // Constant case
289 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
290 int64_t Value = ConstExpr->getValue();
291 // Check if value fits in 16 bits or value of the form 0xffffxyzw
292 return isInt<16>(static_cast<int32_t>(Value));
293 }
294
295 // Symbolic reference expression
296 if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
297 return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
298
299 // Binary expression
300 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
301 if (const auto *SymbolRefExpr =
302 dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
303 return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
304
305 return false;
306 }
307
308 bool isLoImm16And() {
309 if (!isImm())
310 return false;
311
312 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
313 if (ConstExpr) {
314 int64_t Value = ConstExpr->getValue();
315 // Check if in the form 0xffffXYZW
316 return ((Value & ~0xffff) == 0xffff0000);
317 }
318 return false;
319 }
320
321 bool isImmShift() {
322 if (!isImm())
323 return false;
324
325 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
326 if (!ConstExpr)
327 return false;
328 int64_t Value = ConstExpr->getValue();
329 return (Value >= -31) && (Value <= 31);
330 }
331
332 bool isLoImm21() {
333 if (!isImm())
334 return false;
335
336 // Constant case
337 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
338 int64_t Value = ConstExpr->getValue();
339 return isUInt<21>(Value);
340 }
341
342 // Symbolic reference expression
343 if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
344 return SymbolRefExpr->getSpecifier() == Lanai::S_None;
345 if (const MCSymbolRefExpr *SymbolRefExpr =
347 return SymbolRefExpr->getSpecifier() == 0;
348 }
349
350 // Binary expression
351 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
352 if (const auto *SymbolRefExpr =
353 dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
354 return SymbolRefExpr->getSpecifier() == Lanai::S_None;
355 if (const MCSymbolRefExpr *SymbolRefExpr =
356 dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
357 return SymbolRefExpr->getSpecifier() == 0;
358 }
359
360 return false;
361 }
362
363 bool isImm10() {
364 if (!isImm())
365 return false;
366
367 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
368 if (!ConstExpr)
369 return false;
370 int64_t Value = ConstExpr->getValue();
371 return isInt<10>(Value);
372 }
373
374 bool isCondCode() {
375 if (!isImm())
376 return false;
377
378 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
379 if (!ConstExpr)
380 return false;
381 uint64_t Value = ConstExpr->getValue();
382 // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
383 // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
384 // value corresponds to a valid condition code.
385 return Value < LPCC::UNKNOWN;
386 }
387
388 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
389 // Add as immediates where possible. Null MCExpr = 0
390 if (Expr == nullptr)
392 else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
393 Inst.addOperand(
394 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
395 else
397 }
398
399 void addRegOperands(MCInst &Inst, unsigned N) const {
400 assert(N == 1 && "Invalid number of operands!");
402 }
403
404 void addImmOperands(MCInst &Inst, unsigned N) const {
405 assert(N == 1 && "Invalid number of operands!");
406 addExpr(Inst, getImm());
407 }
408
409 void addBrTargetOperands(MCInst &Inst, unsigned N) const {
410 assert(N == 1 && "Invalid number of operands!");
411 addExpr(Inst, getImm());
412 }
413
414 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
415 assert(N == 1 && "Invalid number of operands!");
416 addExpr(Inst, getImm());
417 }
418
419 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
420 assert(N == 1 && "Invalid number of operands!");
421 addExpr(Inst, getImm());
422 }
423
424 void addMemImmOperands(MCInst &Inst, unsigned N) const {
425 assert(N == 1 && "Invalid number of operands!");
426 const MCExpr *Expr = getMemOffset();
427 addExpr(Inst, Expr);
428 }
429
430 void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
431 assert(N == 3 && "Invalid number of operands!");
432 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
433 const MCExpr *Expr = getMemOffset();
434 addExpr(Inst, Expr);
435 Inst.addOperand(MCOperand::createImm(getMemOp()));
436 }
437
438 void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
439 assert(N == 3 && "Invalid number of operands!");
440 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
441 assert(getMemOffsetReg() && "Invalid offset");
442 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
443 Inst.addOperand(MCOperand::createImm(getMemOp()));
444 }
445
446 void addMemSplsOperands(MCInst &Inst, unsigned N) const {
447 if (isMemRegImm())
448 addMemRegImmOperands(Inst, N);
449 if (isMemRegReg())
450 addMemRegRegOperands(Inst, N);
451 }
452
453 void addImmShiftOperands(MCInst &Inst, unsigned N) const {
454 assert(N == 1 && "Invalid number of operands!");
455 addExpr(Inst, getImm());
456 }
457
458 void addImm10Operands(MCInst &Inst, unsigned N) const {
459 assert(N == 1 && "Invalid number of operands!");
460 addExpr(Inst, getImm());
461 }
462
463 void addLoImm16Operands(MCInst &Inst, unsigned N) const {
464 assert(N == 1 && "Invalid number of operands!");
465 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
466 Inst.addOperand(
467 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
468 else if (isa<MCSpecifierExpr>(getImm())) {
469#ifndef NDEBUG
470 const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(getImm());
471 assert(SymbolRefExpr && SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO);
472#endif
474 } else if (isa<MCBinaryExpr>(getImm())) {
475#ifndef NDEBUG
476 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
477 assert(BinaryExpr && isa<MCSpecifierExpr>(BinaryExpr->getLHS()) &&
478 cast<MCSpecifierExpr>(BinaryExpr->getLHS())->getSpecifier() ==
480#endif
482 } else
483 assert(false && "Operand type not supported.");
484 }
485
486 void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
487 assert(N == 1 && "Invalid number of operands!");
488 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
489 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
490 else
491 assert(false && "Operand type not supported.");
492 }
493
494 void addHiImm16Operands(MCInst &Inst, unsigned N) const {
495 assert(N == 1 && "Invalid number of operands!");
496 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
497 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
498 else if (isa<MCSpecifierExpr>(getImm())) {
499#ifndef NDEBUG
500 const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(getImm());
501 assert(SymbolRefExpr && SymbolRefExpr->getSpecifier() == Lanai::S_ABS_HI);
502#endif
504 } else if (isa<MCBinaryExpr>(getImm())) {
505#ifndef NDEBUG
506 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
507 assert(BinaryExpr && isa<MCSpecifierExpr>(BinaryExpr->getLHS()) &&
508 cast<MCSpecifierExpr>(BinaryExpr->getLHS())->getSpecifier() ==
510#endif
512 } else
513 assert(false && "Operand type not supported.");
514 }
515
516 void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
517 assert(N == 1 && "Invalid number of operands!");
518 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
519 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
520 else
521 assert(false && "Operand type not supported.");
522 }
523
524 void addLoImm21Operands(MCInst &Inst, unsigned N) const {
525 assert(N == 1 && "Invalid number of operands!");
526 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
527 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
528 else if (isa<MCSpecifierExpr>(getImm())) {
529#ifndef NDEBUG
530 const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(getImm());
531 assert(SymbolRefExpr && SymbolRefExpr->getSpecifier() == Lanai::S_None);
532#endif
534 } else if (isa<MCSymbolRefExpr>(getImm())) {
535#ifndef NDEBUG
536 const MCSymbolRefExpr *SymbolRefExpr =
538 assert(SymbolRefExpr && SymbolRefExpr->getSpecifier() == 0);
539#endif
541 } else if (isa<MCBinaryExpr>(getImm())) {
542#ifndef NDEBUG
543 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
544 assert(BinaryExpr && isa<MCSpecifierExpr>(BinaryExpr->getLHS()) &&
545 cast<MCSpecifierExpr>(BinaryExpr->getLHS())->getSpecifier() ==
547#endif
549 } else
550 assert(false && "Operand type not supported.");
551 }
552
553 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {
554 switch (Kind) {
555 case IMMEDIATE:
556 OS << "Imm: " << getImm() << "\n";
557 break;
558 case TOKEN:
559 OS << "Token: " << getToken() << "\n";
560 break;
561 case REGISTER:
562 OS << "Reg: %r" << getReg() << "\n";
563 break;
564 case MEMORY_IMM:
565 OS << "MemImm: ";
566 MAI.printExpr(OS, *getMemOffset());
567 OS << '\n';
568 break;
569 case MEMORY_REG_IMM:
570 OS << "MemRegImm: " << getMemBaseReg() << "+";
571 MAI.printExpr(OS, *getMemOffset());
572 OS << '\n';
573 break;
574 case MEMORY_REG_REG:
575 assert(getMemOffset() == nullptr);
576 OS << "MemRegReg: " << getMemBaseReg() << "+"
577 << "%r" << getMemOffsetReg() << "\n";
578 break;
579 }
580 }
581
582 static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
583 auto Op = std::make_unique<LanaiOperand>(TOKEN);
584 Op->Tok.Data = Str.data();
585 Op->Tok.Length = Str.size();
586 Op->StartLoc = Start;
587 Op->EndLoc = Start;
588 return Op;
589 }
590
591 static std::unique_ptr<LanaiOperand> createReg(MCRegister Reg, SMLoc Start,
592 SMLoc End) {
593 auto Op = std::make_unique<LanaiOperand>(REGISTER);
594 Op->Reg.RegNum = Reg;
595 Op->StartLoc = Start;
596 Op->EndLoc = End;
597 return Op;
598 }
599
600 static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
601 SMLoc Start, SMLoc End) {
602 auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
603 Op->Imm.Value = Value;
604 Op->StartLoc = Start;
605 Op->EndLoc = End;
606 return Op;
607 }
608
609 static std::unique_ptr<LanaiOperand>
610 MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
611 const MCExpr *Imm = Op->getImm();
612 Op->Kind = MEMORY_IMM;
613 Op->Mem.BaseReg = MCRegister();
614 Op->Mem.AluOp = LPAC::ADD;
615 Op->Mem.OffsetReg = 0;
616 Op->Mem.Offset = Imm;
617 return Op;
618 }
619
620 static std::unique_ptr<LanaiOperand>
621 MorphToMemRegReg(MCRegister BaseReg, std::unique_ptr<LanaiOperand> Op,
622 unsigned AluOp) {
623 MCRegister OffsetReg = Op->getReg();
624 Op->Kind = MEMORY_REG_REG;
625 Op->Mem.BaseReg = BaseReg;
626 Op->Mem.AluOp = AluOp;
627 Op->Mem.OffsetReg = OffsetReg;
628 Op->Mem.Offset = nullptr;
629 return Op;
630 }
631
632 static std::unique_ptr<LanaiOperand>
633 MorphToMemRegImm(MCRegister BaseReg, std::unique_ptr<LanaiOperand> Op,
634 unsigned AluOp) {
635 const MCExpr *Imm = Op->getImm();
636 Op->Kind = MEMORY_REG_IMM;
637 Op->Mem.BaseReg = BaseReg;
638 Op->Mem.AluOp = AluOp;
639 Op->Mem.OffsetReg = 0;
640 Op->Mem.Offset = Imm;
641 return Op;
642 }
643};
644
645} // end anonymous namespace
646
647bool LanaiAsmParser::matchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
649 MCStreamer &Out,
651 bool MatchingInlineAsm) {
652 MCInst Inst;
653 SMLoc ErrorLoc;
654
655 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
656 case Match_Success:
657 Out.emitInstruction(Inst, SubtargetInfo);
658 Opcode = Inst.getOpcode();
659 return false;
660 case Match_MissingFeature:
661 return Error(IdLoc, "Instruction use requires option to be enabled");
662 case Match_MnemonicFail:
663 return Error(IdLoc, "Unrecognized instruction mnemonic");
664 case Match_InvalidOperand: {
665 ErrorLoc = IdLoc;
666 if (ErrorInfo != ~0U) {
667 if (ErrorInfo >= Operands.size())
668 return Error(IdLoc, "Too few operands for instruction");
669
670 ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
671 if (ErrorLoc == SMLoc())
672 ErrorLoc = IdLoc;
673 }
674 return Error(ErrorLoc, "Invalid operand for instruction");
675 }
676 default:
677 break;
678 }
679
680 llvm_unreachable("Unknown match type detected!");
681}
682
683// Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
684// backwards compatible with GCC and the different ways inline assembly is
685// handled.
686// TODO: see if there isn't a better way to do this.
687std::unique_ptr<LanaiOperand>
688LanaiAsmParser::parseRegister(bool RestoreOnFailure) {
689 SMLoc Start = Parser.getTok().getLoc();
690 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
691 std::optional<AsmToken> PercentTok;
692
693 MCRegister Reg;
694 // Eat the '%'.
695 if (Lexer.getKind() == AsmToken::Percent) {
696 PercentTok = Parser.getTok();
697 Parser.Lex();
698 }
699 if (Lexer.getKind() == AsmToken::Identifier) {
701 if (!Reg) {
702 if (PercentTok && RestoreOnFailure)
703 Lexer.UnLex(*PercentTok);
704 return nullptr;
705 }
706 Parser.Lex(); // Eat identifier token
707 return LanaiOperand::createReg(Reg, Start, End);
708 }
709 if (PercentTok && RestoreOnFailure)
710 Lexer.UnLex(*PercentTok);
711 return nullptr;
712}
713
714bool LanaiAsmParser::parseRegister(MCRegister &RegNum, SMLoc &StartLoc,
715 SMLoc &EndLoc) {
716 const AsmToken &Tok = getParser().getTok();
717 StartLoc = Tok.getLoc();
718 EndLoc = Tok.getEndLoc();
719 std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/false);
720 if (Op != nullptr)
721 RegNum = Op->getReg();
722 return (Op == nullptr);
723}
724
725ParseStatus LanaiAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
726 SMLoc &EndLoc) {
727 const AsmToken &Tok = getParser().getTok();
728 StartLoc = Tok.getLoc();
729 EndLoc = Tok.getEndLoc();
730 std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/true);
731 if (Op == nullptr)
733 Reg = Op->getReg();
735}
736
737std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
738 SMLoc Start = Parser.getTok().getLoc();
739 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
740 const MCExpr *Res, *RHS = nullptr;
741 auto Kind = Lanai::S_None;
742
743 if (Lexer.getKind() != AsmToken::Identifier)
744 return nullptr;
745
746 StringRef Identifier;
747 if (Parser.parseIdentifier(Identifier))
748 return nullptr;
749
750 // Check if identifier has a modifier
751 if (Identifier.equals_insensitive("hi"))
753 else if (Identifier.equals_insensitive("lo"))
755
756 // If the identifier corresponds to a variant then extract the real
757 // identifier.
758 if (Kind != Lanai::S_None) {
759 if (Lexer.getKind() != AsmToken::LParen) {
760 Error(Lexer.getLoc(), "Expected '('");
761 return nullptr;
762 }
763 Lexer.Lex(); // lex '('
764
765 // Parse identifier
766 if (Parser.parseIdentifier(Identifier))
767 return nullptr;
768 }
769
770 // If addition parse the RHS.
771 if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
772 return nullptr;
773
774 // For variants parse the final ')'
775 if (Kind != Lanai::S_None) {
776 if (Lexer.getKind() != AsmToken::RParen) {
777 Error(Lexer.getLoc(), "Expected ')'");
778 return nullptr;
779 }
780 Lexer.Lex(); // lex ')'
781 }
782
783 End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
784 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
785 Res = MCSpecifierExpr::create(Sym, Kind, getContext());
786
787 // Nest if this was an addition
788 if (RHS)
790
791 return LanaiOperand::createImm(Res, Start, End);
792}
793
794std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
795 SMLoc Start = Parser.getTok().getLoc();
796 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
797
798 const MCExpr *ExprVal;
799 switch (Lexer.getKind()) {
801 return parseIdentifier();
802 case AsmToken::Plus:
803 case AsmToken::Minus:
805 case AsmToken::Dot:
806 if (!Parser.parseExpression(ExprVal))
807 return LanaiOperand::createImm(ExprVal, Start, End);
808 [[fallthrough]];
809 default:
810 return nullptr;
811 }
812}
813
814static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
815 if (PreOp)
816 return LPAC::makePreOp(AluCode);
817 if (PostOp)
818 return LPAC::makePostOp(AluCode);
819 return AluCode;
820}
821
822unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
823 StringRef IdString;
824 Parser.parseIdentifier(IdString);
825 unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
826 if (AluCode == LPAC::UNKNOWN) {
827 Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
828 return 0;
829 }
830 return AluCode;
831}
832
834 return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
835}
836
837bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
838 bool PreOrPost = false;
839 if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
840 PreOrPost = true;
841 if (Lexer.is(AsmToken::Minus))
842 *OffsetValue = -SizeForSuffix(Type);
843 else if (Lexer.is(AsmToken::Plus))
844 *OffsetValue = SizeForSuffix(Type);
845 else
846 return false;
847
848 // Eat the '-' '-' or '+' '+'
849 Parser.Lex();
850 Parser.Lex();
851 } else if (Lexer.is(AsmToken::Star)) {
852 Parser.Lex(); // Eat the '*'
853 PreOrPost = true;
854 }
855
856 return PreOrPost;
857}
858
859bool shouldBeSls(const LanaiOperand &Op) {
860 // The instruction should be encoded as an SLS if the constant is word
861 // aligned and will fit in 21 bits
862 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
863 int64_t Value = ConstExpr->getValue();
864 return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
865 }
866 // The instruction should be encoded as an SLS if the operand is a symbolic
867 // reference with no variant.
868 if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Op.getImm()))
869 return SymbolRefExpr->getSpecifier() == Lanai::S_None;
870 // The instruction should be encoded as an SLS if the operand is a binary
871 // expression with the left-hand side being a symbolic reference with no
872 // variant.
873 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
874 const auto *LHSSymbolRefExpr =
876 return (LHSSymbolRefExpr &&
877 LHSSymbolRefExpr->getSpecifier() == Lanai::S_None);
878 }
879 return false;
880}
881
882// Matches memory operand. Returns true if error encountered.
883ParseStatus LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
884 // Try to match a memory operand.
885 // The memory operands are of the form:
886 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
887 // ^
888 // (2) '[' '*'? Register '*'? AluOperator Register ']'
889 // ^
890 // (3) '[' '--'|'++' Register '--'|'++' ']'
891 //
892 // (4) '[' Immediate ']' (for SLS)
893
894 // Store the type for use in parsing pre/post increment/decrement operators
895 StringRef Type;
896 if (Operands[0]->isToken())
897 Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
898
899 // Use 0 if no offset given
900 int OffsetValue = 0;
901 MCRegister BaseReg;
902 unsigned AluOp = LPAC::ADD;
903 bool PostOp = false, PreOp = false;
904
905 // Try to parse the offset
906 std::unique_ptr<LanaiOperand> Op = parseRegister();
907 if (!Op)
908 Op = parseImmediate();
909
910 // Only continue if next token is '['
911 if (Lexer.isNot(AsmToken::LBrac)) {
912 if (!Op)
914
915 // The start of this custom parsing overlaps with register/immediate so
916 // consider this as a successful match of an operand of that type as the
917 // token stream can't be rewound to allow them to match separately.
918 Operands.push_back(std::move(Op));
920 }
921
922 Parser.Lex(); // Eat the '['.
923 std::unique_ptr<LanaiOperand> Offset = nullptr;
924 if (Op)
925 Offset.swap(Op);
926
927 // Determine if a pre operation
928 PreOp = parsePrePost(Type, &OffsetValue);
929
930 Op = parseRegister();
931 if (!Op) {
932 if (!Offset) {
933 if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
934 Parser.Lex(); // Eat the ']'
935
936 // Memory address operations aligned to word boundary are encoded as
937 // SLS, the rest as RM.
938 if (shouldBeSls(*Op)) {
939 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
940 } else {
941 if (!Op->isLoImm16Signed())
942 return Error(Parser.getTok().getLoc(),
943 "Memory address is not word aligned and larger than "
944 "class RM can handle");
945 Operands.push_back(LanaiOperand::MorphToMemRegImm(
946 Lanai::R0, std::move(Op), LPAC::ADD));
947 }
949 }
950 }
951
952 return Error(Parser.getTok().getLoc(),
953 "Unknown operand, expected register or immediate");
954 }
955 BaseReg = Op->getReg();
956
957 // Determine if a post operation
958 if (!PreOp)
959 PostOp = parsePrePost(Type, &OffsetValue);
960
961 // If ] match form (1) else match form (2)
962 if (Lexer.is(AsmToken::RBrac)) {
963 Parser.Lex(); // Eat the ']'.
964 if (!Offset) {
965 SMLoc Start = Parser.getTok().getLoc();
966 SMLoc End =
968 const MCConstantExpr *OffsetConstExpr =
969 MCConstantExpr::create(OffsetValue, getContext());
970 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
971 }
972 } else {
973 if (Offset || OffsetValue != 0)
974 return Error(Parser.getTok().getLoc(), "Expected ']'");
975
976 // Parse operator
977 AluOp = parseAluOperator(PreOp, PostOp);
978
979 // Second form requires offset register
980 Offset = parseRegister();
981 if (!BaseReg || Lexer.isNot(AsmToken::RBrac))
982 return Error(Parser.getTok().getLoc(), "Expected ']'");
983 Parser.Lex(); // Eat the ']'.
984 }
985
986 // First form has addition as operator. Add pre- or post-op indicator as
987 // needed.
988 AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
989
990 // Ensure immediate offset is not too large
991 if (Offset->isImm() && !Offset->isLoImm16Signed())
992 return Error(Parser.getTok().getLoc(),
993 "Memory address is not word aligned and larger than class RM "
994 "can handle");
995
996 Operands.push_back(
997 Offset->isImm()
998 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
999 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
1000
1001 return ParseStatus::Success;
1002}
1003
1004// Looks at a token type and creates the relevant operand from this
1005// information, adding to operands.
1006// If operand was parsed, returns false, else true.
1007ParseStatus LanaiAsmParser::parseOperand(OperandVector *Operands,
1008 StringRef Mnemonic) {
1009 // Check if the current operand has a custom associated parser, if so, try to
1010 // custom parse the operand, or fallback to the general approach.
1011 ParseStatus Result = MatchOperandParserImpl(*Operands, Mnemonic);
1012
1013 if (Result.isSuccess())
1014 return Result;
1015 if (Result.isFailure()) {
1016 Parser.eatToEndOfStatement();
1017 return Result;
1018 }
1019
1020 // Attempt to parse token as register
1021 std::unique_ptr<LanaiOperand> Op = parseRegister();
1022
1023 // Attempt to parse token as immediate
1024 if (!Op)
1025 Op = parseImmediate();
1026
1027 // If the token could not be parsed then fail
1028 if (!Op) {
1029 Error(Parser.getTok().getLoc(), "Unknown operand");
1030 Parser.eatToEndOfStatement();
1031 return ParseStatus::Failure;
1032 }
1033
1034 // Push back parsed operand into list of operands
1035 Operands->push_back(std::move(Op));
1036
1037 return ParseStatus::Success;
1038}
1039
1040// Split the mnemonic into ASM operand, conditional code and instruction
1041// qualifier (half-word, byte).
1042StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1044 size_t Next = Name.find('.');
1045
1046 StringRef Mnemonic = Name;
1047
1048 bool IsBRR = Mnemonic.consume_back(".r");
1049
1050 // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1051 if (Mnemonic[0] == 'b' ||
1052 (Mnemonic[0] == 's' && !Mnemonic.starts_with("sel") &&
1053 !Mnemonic.starts_with("st"))) {
1054 // Parse instructions with a conditional code. For example, 'bne' is
1055 // converted into two operands 'b' and 'ne'.
1058 if (CondCode != LPCC::UNKNOWN) {
1059 Mnemonic = Mnemonic.slice(0, 1);
1060 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1061 Operands->push_back(LanaiOperand::createImm(
1062 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1063 if (IsBRR) {
1064 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1065 }
1066 return Mnemonic;
1067 }
1068 }
1069
1070 // Parse other instructions with condition codes (RR instructions).
1071 // We ignore .f here and assume they are flag-setting operations, not
1072 // conditional codes (except for select instructions where flag-setting
1073 // variants are not yet implemented).
1074 if (Mnemonic.starts_with("sel") ||
1075 (!Mnemonic.ends_with(".f") && !Mnemonic.starts_with("st"))) {
1077 if (CondCode != LPCC::UNKNOWN) {
1078 size_t Next = Mnemonic.rfind('.', Name.size());
1079 // 'sel' doesn't use a predicate operand whose printer adds the period,
1080 // but instead has the period as part of the identifier (i.e., 'sel.' is
1081 // expected by the generated matcher). If the mnemonic starts with 'sel'
1082 // then include the period as part of the mnemonic, else don't include it
1083 // as part of the mnemonic.
1084 if (Mnemonic.starts_with("sel")) {
1085 Mnemonic = Mnemonic.substr(0, Next + 1);
1086 } else {
1087 Mnemonic = Mnemonic.substr(0, Next);
1088 }
1089 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1090 Operands->push_back(LanaiOperand::createImm(
1091 MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1092 return Mnemonic;
1093 }
1094 }
1095
1096 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1097 if (IsBRR) {
1098 Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1099 }
1100
1101 return Mnemonic;
1102}
1103
1105 // Detects if a memory operation has an erroneous base register modification.
1106 // Memory operations are detected by matching the types of operands.
1107 //
1108 // TODO: This test is focussed on one specific instance (ld/st).
1109 // Extend it to handle more cases or be more robust.
1110 bool Modifies = false;
1111
1112 int Offset = 0;
1113
1114 if (Operands.size() < 5)
1115 return false;
1116 else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1117 Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1118 Offset = 0;
1119 else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1120 Operands[2]->isReg() && Operands[3]->isImm() &&
1121 Operands[4]->isImm() && Operands[5]->isReg())
1122 Offset = 1;
1123 else
1124 return false;
1125
1126 int PossibleAluOpIdx = Offset + 3;
1127 int PossibleBaseIdx = Offset + 1;
1128 int PossibleDestIdx = Offset + 4;
1129 if (LanaiOperand *PossibleAluOp =
1130 static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1131 if (PossibleAluOp->isImm())
1132 if (const MCConstantExpr *ConstExpr =
1133 dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1134 Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1135 return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1136 Operands[PossibleDestIdx]->isReg() &&
1137 Operands[PossibleBaseIdx]->getReg() ==
1138 Operands[PossibleDestIdx]->getReg();
1139}
1140
1141static bool IsRegister(const MCParsedAsmOperand &op) {
1142 return static_cast<const LanaiOperand &>(op).isReg();
1143}
1144
1146 if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
1147 !IsRegister(*Operands[2]))
1148 return false;
1149 return StringSwitch<bool>(
1150 static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1151 .StartsWith("addc", true)
1152 .StartsWith("add", true)
1153 .StartsWith("and", true)
1154 .StartsWith("sh", true)
1155 .StartsWith("subb", true)
1156 .StartsWith("sub", true)
1157 .StartsWith("or", true)
1158 .StartsWith("xor", true)
1159 .Default(false);
1160}
1161
1162bool LanaiAsmParser::parseInstruction(ParseInstructionInfo & /*Info*/,
1163 StringRef Name, SMLoc NameLoc,
1165 // First operand is token for instruction
1166 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1167
1168 // If there are no more operands, then finish
1169 if (Lexer.is(AsmToken::EndOfStatement))
1170 return false;
1171
1172 // Parse first operand
1173 if (!parseOperand(&Operands, Mnemonic).isSuccess())
1174 return true;
1175
1176 // If it is a st instruction with one 1 operand then it is a "store true".
1177 // Transform <"st"> to <"s">, <LPCC:ICC_T>
1178 if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1179 Operands.size() == 2) {
1180 Operands.erase(Operands.begin(), Operands.begin() + 1);
1181 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1182 Operands.insert(Operands.begin() + 1,
1183 LanaiOperand::createImm(
1185 NameLoc, NameLoc));
1186 }
1187
1188 // If the instruction is a bt instruction with 1 operand (in assembly) then it
1189 // is an unconditional branch instruction and the first two elements of
1190 // operands need to be merged.
1191 if (Lexer.is(AsmToken::EndOfStatement) && Name.starts_with("bt") &&
1192 Operands.size() == 3) {
1193 Operands.erase(Operands.begin(), Operands.begin() + 2);
1194 Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1195 }
1196
1197 // Parse until end of statement, consuming commas between operands
1198 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1199 // Consume comma token
1200 Lex();
1201
1202 // Parse next operand
1203 if (!parseOperand(&Operands, Mnemonic).isSuccess())
1204 return true;
1205 }
1206
1208 Error(Parser.getTok().getLoc(),
1209 "the destination register can't equal the base register in an "
1210 "instruction that modifies the base register.");
1211 return true;
1212 }
1213
1214 // Insert always true operand for instruction that may be predicated but
1215 // are not. Currently the autogenerated parser always expects a predicate.
1217 Operands.insert(Operands.begin() + 1,
1218 LanaiOperand::createImm(
1220 NameLoc, NameLoc));
1221 }
1222
1223 return false;
1224}
1225
1226#define GET_REGISTER_MATCHER
1227#define GET_MATCHER_IMPLEMENTATION
1228#include "LanaiGenAsmMatcher.inc"
1229
1230extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
static MCRegister MatchRegisterName(StringRef Name)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info, bool IsDynamicVGPRChainCall=false)
Analysis containing CSE Info
Definition CSEInfo.cpp:27
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
#define op(i)
static LVOptions Options
Definition LVOptions.cpp:25
static int SizeForSuffix(StringRef T)
static bool IsMemoryAssignmentError(const OperandVector &Operands)
bool shouldBeSls(const LanaiOperand &Op)
static MCRegister MatchRegisterName(StringRef Name)
static bool MaybePredicatedInst(const OperandVector &Operands)
static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiAsmParser()
static bool IsRegister(const MCParsedAsmOperand &op)
mir Rename Register Operands
Register Reg
#define T
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
Value * RHS
SMLoc getLoc() const
Get the current source location.
Definition AsmLexer.h:115
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Definition AsmLexer.h:121
void UnLex(AsmToken const &Token)
Definition AsmLexer.h:106
AsmToken::TokenKind getKind() const
Get the kind of current token.
Definition AsmLexer.h:144
const AsmToken & getTok() const
Get the current (last) lexed token.
Definition AsmLexer.h:118
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition AsmLexer.h:147
const AsmToken & Lex()
Consume the next token from the input stream and return it.
Definition AsmLexer.h:92
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition AsmLexer.h:150
LLVM_ABI SMLoc getLoc() const
Definition AsmLexer.cpp:32
TokenKind getKind() const
Definition MCAsmMacro.h:74
LLVM_ABI SMLoc getEndLoc() const
Definition AsmLexer.cpp:34
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Definition MCAsmMacro.h:92
Base class for user error types.
Definition Error.h:354
void printExpr(raw_ostream &, const MCExpr &) const
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
Binary assembler expressions.
Definition MCExpr.h:299
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition MCExpr.h:446
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:343
int64_t getValue() const
Definition MCExpr.h:171
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
unsigned getOpcode() const
Definition MCInst.h:202
void addOperand(const MCOperand Op)
Definition MCInst.h:215
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:220
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
uint16_t getSpecifier() const
Definition MCExpr.h:233
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
Definition SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:36
constexpr const char * getPointer() const
Definition SMLoc.h:34
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition StringRef.h:665
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:581
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:269
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:694
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition StringRef.h:353
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:281
A switch()-like statement whose cases are string literals.
StringSwitch & StartsWith(StringLiteral S, T Value)
StringSwitch & EndsWith(StringLiteral S, T Value)
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
static unsigned makePostOp(unsigned AluOp)
static unsigned makePreOp(unsigned AluOp)
static AluCode stringToLanaiAluCode(StringRef S)
static bool modifiesOp(unsigned AluOp)
static CondCode suffixToLanaiCondCode(StringRef S)
Context & getContext() const
Definition BasicBlock.h:99
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
Target & getTheLanaiTarget()
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:198
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:207
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...