LLVM 20.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"
30#include "llvm/Support/SMLoc.h"
32#include <cassert>
33#include <cstddef>
34#include <cstdint>
35#include <memory>
36#include <optional>
37
38using namespace llvm;
39
40// Auto-generated by TableGen
42
43namespace {
44
45struct LanaiOperand;
46
47class LanaiAsmParser : public MCTargetAsmParser {
48 // Parse operands
49 std::unique_ptr<LanaiOperand> parseRegister(bool RestoreOnFailure = false);
50
51 std::unique_ptr<LanaiOperand> parseImmediate();
52
53 std::unique_ptr<LanaiOperand> parseIdentifier();
54
55 unsigned parseAluOperator(bool PreOp, bool PostOp);
56
57 // Split the mnemonic stripping conditional code and quantifiers
58 StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
60
61 bool parsePrePost(StringRef Type, int *OffsetValue);
62
64 SMLoc NameLoc, OperandVector &Operands) override;
65
66 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
68 SMLoc &EndLoc) override;
69
70 bool matchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
73 bool MatchingInlineAsm) override;
74
75// Auto-generated instruction matching functions
76#define GET_ASSEMBLER_HEADER
77#include "LanaiGenAsmMatcher.inc"
78
79 ParseStatus parseOperand(OperandVector *Operands, StringRef Mnemonic);
80
81 ParseStatus parseMemoryOperand(OperandVector &Operands);
82
83public:
84 LanaiAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
85 const MCInstrInfo &MII, const MCTargetOptions &Options)
86 : MCTargetAsmParser(Options, STI, MII), Parser(Parser),
87 Lexer(Parser.getLexer()), SubtargetInfo(STI) {
89 ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
90 }
91
92private:
93 MCAsmParser &Parser;
94 MCAsmLexer &Lexer;
95
96 const MCSubtargetInfo &SubtargetInfo;
97};
98
99// LanaiOperand - Instances of this class represented a parsed machine
100// instruction
101struct LanaiOperand : public MCParsedAsmOperand {
102 enum KindTy {
103 TOKEN,
104 REGISTER,
105 IMMEDIATE,
106 MEMORY_IMM,
107 MEMORY_REG_IMM,
108 MEMORY_REG_REG,
109 } Kind;
110
111 SMLoc StartLoc, EndLoc;
112
113 struct Token {
114 const char *Data;
115 unsigned Length;
116 };
117
118 struct RegOp {
119 MCRegister RegNum;
120 };
121
122 struct ImmOp {
123 const MCExpr *Value;
124 };
125
126 struct MemOp {
127 MCRegister BaseReg;
128 MCRegister OffsetReg;
129 unsigned AluOp;
130 const MCExpr *Offset;
131 };
132
133 union {
134 struct Token Tok;
135 struct RegOp Reg;
136 struct ImmOp Imm;
137 struct MemOp Mem;
138 };
139
140 explicit LanaiOperand(KindTy Kind) : Kind(Kind) {}
141
142public:
143 // The functions below are used by the autogenerated ASM matcher and hence to
144 // be of the form expected.
145
146 // getStartLoc - Gets location of the first token of this operand
147 SMLoc getStartLoc() const override { return StartLoc; }
148
149 // getEndLoc - Gets location of the last token of this operand
150 SMLoc getEndLoc() const override { return EndLoc; }
151
152 MCRegister getReg() const override {
153 assert(isReg() && "Invalid type access!");
154 return Reg.RegNum;
155 }
156
157 const MCExpr *getImm() const {
158 assert(isImm() && "Invalid type access!");
159 return Imm.Value;
160 }
161
162 StringRef getToken() const {
163 assert(isToken() && "Invalid type access!");
164 return StringRef(Tok.Data, Tok.Length);
165 }
166
167 MCRegister getMemBaseReg() const {
168 assert(isMem() && "Invalid type access!");
169 return Mem.BaseReg;
170 }
171
172 MCRegister getMemOffsetReg() const {
173 assert(isMem() && "Invalid type access!");
174 return Mem.OffsetReg;
175 }
176
177 const MCExpr *getMemOffset() const {
178 assert(isMem() && "Invalid type access!");
179 return Mem.Offset;
180 }
181
182 unsigned getMemOp() const {
183 assert(isMem() && "Invalid type access!");
184 return Mem.AluOp;
185 }
186
187 // Functions for testing operand type
188 bool isReg() const override { return Kind == REGISTER; }
189
190 bool isImm() const override { return Kind == IMMEDIATE; }
191
192 bool isMem() const override {
193 return isMemImm() || isMemRegImm() || isMemRegReg();
194 }
195
196 bool isMemImm() const { return Kind == MEMORY_IMM; }
197
198 bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }
199
200 bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }
201
202 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
203
204 bool isToken() const override { return Kind == TOKEN; }
205
206 bool isBrImm() {
207 if (!isImm())
208 return false;
209
210 // Constant case
211 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm.Value);
212 if (!MCE)
213 return true;
214 int64_t Value = MCE->getValue();
215 // Check if value fits in 25 bits with 2 least significant bits 0.
216 return isShiftedUInt<23, 2>(static_cast<int32_t>(Value));
217 }
218
219 bool isBrTarget() { return isBrImm() || isToken(); }
220
221 bool isCallTarget() { return isImm() || isToken(); }
222
223 bool isHiImm16() {
224 if (!isImm())
225 return false;
226
227 // Constant case
228 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
229 int64_t Value = ConstExpr->getValue();
230 return Value != 0 && isShiftedUInt<16, 16>(Value);
231 }
232
233 // Symbolic reference expression
234 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
235 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
236
237 // Binary expression
238 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
239 if (const LanaiMCExpr *SymbolRefExpr =
240 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
241 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
242
243 return false;
244 }
245
246 bool isHiImm16And() {
247 if (!isImm())
248 return false;
249
250 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
251 if (ConstExpr) {
252 int64_t Value = ConstExpr->getValue();
253 // Check if in the form 0xXYZWffff
254 return (Value != 0) && ((Value & ~0xffff0000) == 0xffff);
255 }
256 return false;
257 }
258
259 bool isLoImm16() {
260 if (!isImm())
261 return false;
262
263 // Constant case
264 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
265 int64_t Value = ConstExpr->getValue();
266 // Check if value fits in 16 bits
267 return isUInt<16>(static_cast<int32_t>(Value));
268 }
269
270 // Symbolic reference expression
271 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
272 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
273
274 // Binary expression
275 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
276 if (const LanaiMCExpr *SymbolRefExpr =
277 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
278 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
279
280 return false;
281 }
282
283 bool isLoImm16Signed() {
284 if (!isImm())
285 return false;
286
287 // Constant case
288 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
289 int64_t Value = ConstExpr->getValue();
290 // Check if value fits in 16 bits or value of the form 0xffffxyzw
291 return isInt<16>(static_cast<int32_t>(Value));
292 }
293
294 // Symbolic reference expression
295 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
296 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
297
298 // Binary expression
299 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
300 if (const LanaiMCExpr *SymbolRefExpr =
301 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
302 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
303
304 return false;
305 }
306
307 bool isLoImm16And() {
308 if (!isImm())
309 return false;
310
311 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
312 if (ConstExpr) {
313 int64_t Value = ConstExpr->getValue();
314 // Check if in the form 0xffffXYZW
315 return ((Value & ~0xffff) == 0xffff0000);
316 }
317 return false;
318 }
319
320 bool isImmShift() {
321 if (!isImm())
322 return false;
323
324 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
325 if (!ConstExpr)
326 return false;
327 int64_t Value = ConstExpr->getValue();
328 return (Value >= -31) && (Value <= 31);
329 }
330
331 bool isLoImm21() {
332 if (!isImm())
333 return false;
334
335 // Constant case
336 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
337 int64_t Value = ConstExpr->getValue();
338 return isUInt<21>(Value);
339 }
340
341 // Symbolic reference expression
342 if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
343 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
344 if (const MCSymbolRefExpr *SymbolRefExpr =
345 dyn_cast<MCSymbolRefExpr>(Imm.Value)) {
346 return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
347 }
348
349 // Binary expression
350 if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
351 if (const LanaiMCExpr *SymbolRefExpr =
352 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
353 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
354 if (const MCSymbolRefExpr *SymbolRefExpr =
355 dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
356 return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
357 }
358
359 return false;
360 }
361
362 bool isImm10() {
363 if (!isImm())
364 return false;
365
366 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
367 if (!ConstExpr)
368 return false;
369 int64_t Value = ConstExpr->getValue();
370 return isInt<10>(Value);
371 }
372
373 bool isCondCode() {
374 if (!isImm())
375 return false;
376
377 const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
378 if (!ConstExpr)
379 return false;
380 uint64_t Value = ConstExpr->getValue();
381 // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
382 // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
383 // value corresponds to a valid condition code.
384 return Value < LPCC::UNKNOWN;
385 }
386
387 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
388 // Add as immediates where possible. Null MCExpr = 0
389 if (Expr == nullptr)
391 else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
392 Inst.addOperand(
393 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
394 else
396 }
397
398 void addRegOperands(MCInst &Inst, unsigned N) const {
399 assert(N == 1 && "Invalid number of operands!");
401 }
402
403 void addImmOperands(MCInst &Inst, unsigned N) const {
404 assert(N == 1 && "Invalid number of operands!");
405 addExpr(Inst, getImm());
406 }
407
408 void addBrTargetOperands(MCInst &Inst, unsigned N) const {
409 assert(N == 1 && "Invalid number of operands!");
410 addExpr(Inst, getImm());
411 }
412
413 void addCallTargetOperands(MCInst &Inst, unsigned N) const {
414 assert(N == 1 && "Invalid number of operands!");
415 addExpr(Inst, getImm());
416 }
417
418 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
419 assert(N == 1 && "Invalid number of operands!");
420 addExpr(Inst, getImm());
421 }
422
423 void addMemImmOperands(MCInst &Inst, unsigned N) const {
424 assert(N == 1 && "Invalid number of operands!");
425 const MCExpr *Expr = getMemOffset();
426 addExpr(Inst, Expr);
427 }
428
429 void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
430 assert(N == 3 && "Invalid number of operands!");
431 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
432 const MCExpr *Expr = getMemOffset();
433 addExpr(Inst, Expr);
434 Inst.addOperand(MCOperand::createImm(getMemOp()));
435 }
436
437 void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
438 assert(N == 3 && "Invalid number of operands!");
439 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
440 assert(getMemOffsetReg() && "Invalid offset");
441 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
442 Inst.addOperand(MCOperand::createImm(getMemOp()));
443 }
444
445 void addMemSplsOperands(MCInst &Inst, unsigned N) const {
446 if (isMemRegImm())
447 addMemRegImmOperands(Inst, N);
448 if (isMemRegReg())
449 addMemRegRegOperands(Inst, N);
450 }
451
452 void addImmShiftOperands(MCInst &Inst, unsigned N) const {
453 assert(N == 1 && "Invalid number of operands!");
454 addExpr(Inst, getImm());
455 }
456
457 void addImm10Operands(MCInst &Inst, unsigned N) const {
458 assert(N == 1 && "Invalid number of operands!");
459 addExpr(Inst, getImm());
460 }
461
462 void addLoImm16Operands(MCInst &Inst, unsigned N) const {
463 assert(N == 1 && "Invalid number of operands!");
464 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
465 Inst.addOperand(
466 MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
467 else if (isa<LanaiMCExpr>(getImm())) {
468#ifndef NDEBUG
469 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
470 assert(SymbolRefExpr &&
471 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
472#endif
473 Inst.addOperand(MCOperand::createExpr(getImm()));
474 } else if (isa<MCBinaryExpr>(getImm())) {
475#ifndef NDEBUG
476 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
477 assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
478 cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
480#endif
481 Inst.addOperand(MCOperand::createExpr(getImm()));
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<LanaiMCExpr>(getImm())) {
499#ifndef NDEBUG
500 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
501 assert(SymbolRefExpr &&
502 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
503#endif
504 Inst.addOperand(MCOperand::createExpr(getImm()));
505 } else if (isa<MCBinaryExpr>(getImm())) {
506#ifndef NDEBUG
507 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
508 assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
509 cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
511#endif
512 Inst.addOperand(MCOperand::createExpr(getImm()));
513 } else
514 assert(false && "Operand type not supported.");
515 }
516
517 void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
518 assert(N == 1 && "Invalid number of operands!");
519 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
520 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
521 else
522 assert(false && "Operand type not supported.");
523 }
524
525 void addLoImm21Operands(MCInst &Inst, unsigned N) const {
526 assert(N == 1 && "Invalid number of operands!");
527 if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
528 Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
529 else if (isa<LanaiMCExpr>(getImm())) {
530#ifndef NDEBUG
531 const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
532 assert(SymbolRefExpr &&
533 SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
534#endif
535 Inst.addOperand(MCOperand::createExpr(getImm()));
536 } else if (isa<MCSymbolRefExpr>(getImm())) {
537#ifndef NDEBUG
538 const MCSymbolRefExpr *SymbolRefExpr =
539 dyn_cast<MCSymbolRefExpr>(getImm());
540 assert(SymbolRefExpr &&
541 SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
542#endif
543 Inst.addOperand(MCOperand::createExpr(getImm()));
544 } else if (isa<MCBinaryExpr>(getImm())) {
545#ifndef NDEBUG
546 const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
547 assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
548 cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
550#endif
551 Inst.addOperand(MCOperand::createExpr(getImm()));
552 } else
553 assert(false && "Operand type not supported.");
554 }
555
556 void print(raw_ostream &OS) const override {
557 switch (Kind) {
558 case IMMEDIATE:
559 OS << "Imm: " << getImm() << "\n";
560 break;
561 case TOKEN:
562 OS << "Token: " << getToken() << "\n";
563 break;
564 case REGISTER:
565 OS << "Reg: %r" << getReg() << "\n";
566 break;
567 case MEMORY_IMM:
568 OS << "MemImm: " << *getMemOffset() << "\n";
569 break;
570 case MEMORY_REG_IMM:
571 OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
572 break;
573 case MEMORY_REG_REG:
574 assert(getMemOffset() == nullptr);
575 OS << "MemRegReg: " << getMemBaseReg() << "+"
576 << "%r" << getMemOffsetReg() << "\n";
577 break;
578 }
579 }
580
581 static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
582 auto Op = std::make_unique<LanaiOperand>(TOKEN);
583 Op->Tok.Data = Str.data();
584 Op->Tok.Length = Str.size();
585 Op->StartLoc = Start;
586 Op->EndLoc = Start;
587 return Op;
588 }
589
590 static std::unique_ptr<LanaiOperand> createReg(MCRegister Reg, SMLoc Start,
591 SMLoc End) {
592 auto Op = std::make_unique<LanaiOperand>(REGISTER);
593 Op->Reg.RegNum = Reg;
594 Op->StartLoc = Start;
595 Op->EndLoc = End;
596 return Op;
597 }
598
599 static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
600 SMLoc Start, SMLoc End) {
601 auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
602 Op->Imm.Value = Value;
603 Op->StartLoc = Start;
604 Op->EndLoc = End;
605 return Op;
606 }
607
608 static std::unique_ptr<LanaiOperand>
609 MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
610 const MCExpr *Imm = Op->getImm();
611 Op->Kind = MEMORY_IMM;
612 Op->Mem.BaseReg = MCRegister();
613 Op->Mem.AluOp = LPAC::ADD;
614 Op->Mem.OffsetReg = 0;
615 Op->Mem.Offset = Imm;
616 return Op;
617 }
618
619 static std::unique_ptr<LanaiOperand>
620 MorphToMemRegReg(MCRegister BaseReg, std::unique_ptr<LanaiOperand> Op,
621 unsigned AluOp) {
622 MCRegister OffsetReg = Op->getReg();
623 Op->Kind = MEMORY_REG_REG;
624 Op->Mem.BaseReg = BaseReg;
625 Op->Mem.AluOp = AluOp;
626 Op->Mem.OffsetReg = OffsetReg;
627 Op->Mem.Offset = nullptr;
628 return Op;
629 }
630
631 static std::unique_ptr<LanaiOperand>
632 MorphToMemRegImm(MCRegister BaseReg, std::unique_ptr<LanaiOperand> Op,
633 unsigned AluOp) {
634 const MCExpr *Imm = Op->getImm();
635 Op->Kind = MEMORY_REG_IMM;
636 Op->Mem.BaseReg = BaseReg;
637 Op->Mem.AluOp = AluOp;
638 Op->Mem.OffsetReg = 0;
639 Op->Mem.Offset = Imm;
640 return Op;
641 }
642};
643
644} // end anonymous namespace
645
646bool LanaiAsmParser::matchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
648 MCStreamer &Out,
650 bool MatchingInlineAsm) {
651 MCInst Inst;
652 SMLoc ErrorLoc;
653
654 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
655 case Match_Success:
656 Out.emitInstruction(Inst, SubtargetInfo);
657 Opcode = Inst.getOpcode();
658 return false;
659 case Match_MissingFeature:
660 return Error(IdLoc, "Instruction use requires option to be enabled");
661 case Match_MnemonicFail:
662 return Error(IdLoc, "Unrecognized instruction mnemonic");
663 case Match_InvalidOperand: {
664 ErrorLoc = IdLoc;
665 if (ErrorInfo != ~0U) {
666 if (ErrorInfo >= Operands.size())
667 return Error(IdLoc, "Too few operands for instruction");
668
669 ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
670 if (ErrorLoc == SMLoc())
671 ErrorLoc = IdLoc;
672 }
673 return Error(ErrorLoc, "Invalid operand for instruction");
674 }
675 default:
676 break;
677 }
678
679 llvm_unreachable("Unknown match type detected!");
680}
681
682// Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
683// backwards compatible with GCC and the different ways inline assembly is
684// handled.
685// TODO: see if there isn't a better way to do this.
686std::unique_ptr<LanaiOperand>
687LanaiAsmParser::parseRegister(bool RestoreOnFailure) {
688 SMLoc Start = Parser.getTok().getLoc();
689 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
690 std::optional<AsmToken> PercentTok;
691
693 // Eat the '%'.
694 if (Lexer.getKind() == AsmToken::Percent) {
695 PercentTok = Parser.getTok();
696 Parser.Lex();
697 }
698 if (Lexer.getKind() == AsmToken::Identifier) {
699 Reg = MatchRegisterName(Lexer.getTok().getIdentifier());
700 if (!Reg) {
701 if (PercentTok && RestoreOnFailure)
702 Lexer.UnLex(*PercentTok);
703 return nullptr;
704 }
705 Parser.Lex(); // Eat identifier token
706 return LanaiOperand::createReg(Reg, Start, End);
707 }
708 if (PercentTok && RestoreOnFailure)
709 Lexer.UnLex(*PercentTok);
710 return nullptr;
711}
712
713bool LanaiAsmParser::parseRegister(MCRegister &RegNum, SMLoc &StartLoc,
714 SMLoc &EndLoc) {
715 const AsmToken &Tok = getParser().getTok();
716 StartLoc = Tok.getLoc();
717 EndLoc = Tok.getEndLoc();
718 std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/false);
719 if (Op != nullptr)
720 RegNum = Op->getReg();
721 return (Op == nullptr);
722}
723
724ParseStatus LanaiAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
725 SMLoc &EndLoc) {
726 const AsmToken &Tok = getParser().getTok();
727 StartLoc = Tok.getLoc();
728 EndLoc = Tok.getEndLoc();
729 std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/true);
730 if (Op == nullptr)
732 Reg = Op->getReg();
734}
735
736std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
737 SMLoc Start = Parser.getTok().getLoc();
738 SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
739 const MCExpr *Res, *RHS = nullptr;
741
742 if (Lexer.getKind() != AsmToken::Identifier)
743 return nullptr;
744
746 if (Parser.parseIdentifier(Identifier))
747 return nullptr;
748
749 // Check if identifier has a modifier
750 if (Identifier.equals_insensitive("hi"))
752 else if (Identifier.equals_insensitive("lo"))
754
755 // If the identifier corresponds to a variant then extract the real
756 // identifier.
757 if (Kind != LanaiMCExpr::VK_Lanai_None) {
758 if (Lexer.getKind() != AsmToken::LParen) {
759 Error(Lexer.getLoc(), "Expected '('");
760 return nullptr;
761 }
762 Lexer.Lex(); // lex '('
763
764 // Parse identifier
765 if (Parser.parseIdentifier(Identifier))
766 return nullptr;
767 }
768
769 // If addition parse the RHS.
770 if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
771 return nullptr;
772
773 // For variants parse the final ')'
774 if (Kind != LanaiMCExpr::VK_Lanai_None) {
775 if (Lexer.getKind() != AsmToken::RParen) {
776 Error(Lexer.getLoc(), "Expected ')'");
777 return nullptr;
778 }
779 Lexer.Lex(); // lex ')'
780 }
781
782 End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
783 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
784 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
785 Res = LanaiMCExpr::create(Kind, Expr, getContext());
786
787 // Nest if this was an addition
788 if (RHS)
789 Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
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 LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
869 return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_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 LanaiMCExpr *LHSSymbolRefExpr =
875 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
876 return (LHSSymbolRefExpr &&
877 LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_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
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 =
967 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
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'.
1057 LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
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(
1184 MCConstantExpr::create(LPCC::ICC_T, getContext()),
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(
1219 MCConstantExpr::create(LPCC::ICC_T, getContext()),
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
1232}
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info)
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
std::string Name
bool End
Definition: ELF_riscv.cpp:480
Symbol * Sym
Definition: ELF_riscv.cpp:479
#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)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiAsmParser()
static MCRegister MatchRegisterName(StringRef Name)
static bool MaybePredicatedInst(const OperandVector &Operands)
static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp)
static bool IsRegister(const MCParsedAsmOperand &op)
mir Rename Register Operands
unsigned Reg
static bool isReg(const MCInst &MI, unsigned OpNo)
#define TOKEN(Name)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
raw_pwrite_stream & OS
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
Kind getKind() const
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
This class represents an Operation in the Expression.
Base class for user error types.
Definition: Error.h:355
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
VariantKind getKind() const
Definition: LanaiMCExpr.h:33
static const LanaiMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: LanaiMCExpr.cpp:17
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:37
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
Binary assembler expressions.
Definition: MCExpr.h:493
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:537
int64_t getValue() const
Definition: MCExpr.h:173
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:222
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
unsigned getOpcode() const
Definition: MCInst.h:199
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:163
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:142
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Streaming machine code generation interface.
Definition: MCStreamer.h:213
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
VariantKind getKind() const
Definition: MCExpr.h:413
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
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
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition: StringRef.h:655
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:571
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:265
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:684
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition: StringRef.h:347
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:277
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:83
StringSwitch & EndsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:76
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:74
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.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1613
static unsigned makePostOp(unsigned AluOp)
Definition: LanaiAluCode.h:66
static unsigned makePreOp(unsigned AluOp)
Definition: LanaiAluCode.h:61
static AluCode stringToLanaiAluCode(StringRef S)
Definition: LanaiAluCode.h:102
static bool modifiesOp(unsigned AluOp)
Definition: LanaiAluCode.h:71
static CondCode suffixToLanaiCondCode(StringRef S)
Definition: LanaiCondCode.h:73
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
Target & getTheLanaiTarget()
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
DWARFExpression::Operation Op
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...