1 //===-- LanaiAsmParser.cpp - Parse Lanai assembly to MCInst instructions --===//
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
7 //===----------------------------------------------------------------------===//
9 #include "LanaiAluCode.h"
10 #include "LanaiCondCode.h"
11 #include "LanaiInstrInfo.h"
12 #include "MCTargetDesc/LanaiMCExpr.h"
13 #include "TargetInfo/LanaiTargetInfo.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCAsmParser.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/TargetRegistry.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SMLoc.h"
31 #include "llvm/Support/raw_ostream.h"
40 // Auto-generated by TableGen
41 static MCRegister
MatchRegisterName(StringRef Name
);
47 class LanaiAsmParser
: public MCTargetAsmParser
{
49 std::unique_ptr
<LanaiOperand
> parseRegister(bool RestoreOnFailure
= false);
51 std::unique_ptr
<LanaiOperand
> parseImmediate();
53 std::unique_ptr
<LanaiOperand
> parseIdentifier();
55 unsigned parseAluOperator(bool PreOp
, bool PostOp
);
57 // Split the mnemonic stripping conditional code and quantifiers
58 StringRef
splitMnemonic(StringRef Name
, SMLoc NameLoc
,
59 OperandVector
*Operands
);
61 bool parsePrePost(StringRef Type
, int *OffsetValue
);
63 bool parseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
64 SMLoc NameLoc
, OperandVector
&Operands
) override
;
66 bool parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
67 ParseStatus
tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
68 SMLoc
&EndLoc
) override
;
70 bool matchAndEmitInstruction(SMLoc IdLoc
, unsigned &Opcode
,
71 OperandVector
&Operands
, MCStreamer
&Out
,
73 bool MatchingInlineAsm
) override
;
75 // Auto-generated instruction matching functions
76 #define GET_ASSEMBLER_HEADER
77 #include "LanaiGenAsmMatcher.inc"
79 ParseStatus
parseOperand(OperandVector
*Operands
, StringRef Mnemonic
);
81 ParseStatus
parseMemoryOperand(OperandVector
&Operands
);
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()));
96 const MCSubtargetInfo
&SubtargetInfo
;
99 // LanaiOperand - Instances of this class represented a parsed machine
101 struct LanaiOperand
: public MCParsedAsmOperand
{
111 SMLoc StartLoc
, EndLoc
;
128 MCRegister OffsetReg
;
130 const MCExpr
*Offset
;
140 explicit LanaiOperand(KindTy Kind
) : Kind(Kind
) {}
143 // The functions below are used by the autogenerated ASM matcher and hence to
144 // be of the form expected.
146 // getStartLoc - Gets location of the first token of this operand
147 SMLoc
getStartLoc() const override
{ return StartLoc
; }
149 // getEndLoc - Gets location of the last token of this operand
150 SMLoc
getEndLoc() const override
{ return EndLoc
; }
152 MCRegister
getReg() const override
{
153 assert(isReg() && "Invalid type access!");
157 const MCExpr
*getImm() const {
158 assert(isImm() && "Invalid type access!");
162 StringRef
getToken() const {
163 assert(isToken() && "Invalid type access!");
164 return StringRef(Tok
.Data
, Tok
.Length
);
167 MCRegister
getMemBaseReg() const {
168 assert(isMem() && "Invalid type access!");
172 MCRegister
getMemOffsetReg() const {
173 assert(isMem() && "Invalid type access!");
174 return Mem
.OffsetReg
;
177 const MCExpr
*getMemOffset() const {
178 assert(isMem() && "Invalid type access!");
182 unsigned getMemOp() const {
183 assert(isMem() && "Invalid type access!");
187 // Functions for testing operand type
188 bool isReg() const override
{ return Kind
== REGISTER
; }
190 bool isImm() const override
{ return Kind
== IMMEDIATE
; }
192 bool isMem() const override
{
193 return isMemImm() || isMemRegImm() || isMemRegReg();
196 bool isMemImm() const { return Kind
== MEMORY_IMM
; }
198 bool isMemRegImm() const { return Kind
== MEMORY_REG_IMM
; }
200 bool isMemRegReg() const { return Kind
== MEMORY_REG_REG
; }
202 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
204 bool isToken() const override
{ return Kind
== TOKEN
; }
211 const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
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
));
219 bool isBrTarget() { return isBrImm() || isToken(); }
221 bool isCallTarget() { return isImm() || isToken(); }
228 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
229 int64_t Value
= ConstExpr
->getValue();
230 return Value
!= 0 && isShiftedUInt
<16, 16>(Value
);
233 // Symbolic reference expression
234 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
235 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
;
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
;
246 bool isHiImm16And() {
250 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
252 int64_t Value
= ConstExpr
->getValue();
253 // Check if in the form 0xXYZWffff
254 return (Value
!= 0) && ((Value
& ~0xffff0000) == 0xffff);
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
));
270 // Symbolic reference expression
271 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
272 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
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
;
283 bool isLoImm16Signed() {
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
));
294 // Symbolic reference expression
295 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
296 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
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
;
307 bool isLoImm16And() {
311 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
313 int64_t Value
= ConstExpr
->getValue();
314 // Check if in the form 0xffffXYZW
315 return ((Value
& ~0xffff) == 0xffff0000);
324 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
327 int64_t Value
= ConstExpr
->getValue();
328 return (Value
>= -31) && (Value
<= 31);
336 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
337 int64_t Value
= ConstExpr
->getValue();
338 return isUInt
<21>(Value
);
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
;
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
;
366 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
369 int64_t Value
= ConstExpr
->getValue();
370 return isInt
<10>(Value
);
377 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
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
;
387 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
388 // Add as immediates where possible. Null MCExpr = 0
390 Inst
.addOperand(MCOperand::createImm(0));
391 else if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Expr
))
393 MCOperand::createImm(static_cast<int32_t>(ConstExpr
->getValue())));
395 Inst
.addOperand(MCOperand::createExpr(Expr
));
398 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
399 assert(N
== 1 && "Invalid number of operands!");
400 Inst
.addOperand(MCOperand::createReg(getReg()));
403 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
404 assert(N
== 1 && "Invalid number of operands!");
405 addExpr(Inst
, getImm());
408 void addBrTargetOperands(MCInst
&Inst
, unsigned N
) const {
409 assert(N
== 1 && "Invalid number of operands!");
410 addExpr(Inst
, getImm());
413 void addCallTargetOperands(MCInst
&Inst
, unsigned N
) const {
414 assert(N
== 1 && "Invalid number of operands!");
415 addExpr(Inst
, getImm());
418 void addCondCodeOperands(MCInst
&Inst
, unsigned N
) const {
419 assert(N
== 1 && "Invalid number of operands!");
420 addExpr(Inst
, getImm());
423 void addMemImmOperands(MCInst
&Inst
, unsigned N
) const {
424 assert(N
== 1 && "Invalid number of operands!");
425 const MCExpr
*Expr
= getMemOffset();
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();
434 Inst
.addOperand(MCOperand::createImm(getMemOp()));
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()));
445 void addMemSplsOperands(MCInst
&Inst
, unsigned N
) const {
447 addMemRegImmOperands(Inst
, N
);
449 addMemRegRegOperands(Inst
, N
);
452 void addImmShiftOperands(MCInst
&Inst
, unsigned N
) const {
453 assert(N
== 1 && "Invalid number of operands!");
454 addExpr(Inst
, getImm());
457 void addImm10Operands(MCInst
&Inst
, unsigned N
) const {
458 assert(N
== 1 && "Invalid number of operands!");
459 addExpr(Inst
, getImm());
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()))
466 MCOperand::createImm(static_cast<int32_t>(ConstExpr
->getValue())));
467 else if (isa
<LanaiMCExpr
>(getImm())) {
469 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
470 assert(SymbolRefExpr
&&
471 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
);
473 Inst
.addOperand(MCOperand::createExpr(getImm()));
474 } else if (isa
<MCBinaryExpr
>(getImm())) {
476 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
477 assert(BinaryExpr
&& isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
478 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
479 LanaiMCExpr::VK_Lanai_ABS_LO
);
481 Inst
.addOperand(MCOperand::createExpr(getImm()));
483 assert(false && "Operand type not supported.");
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));
491 assert(false && "Operand type not supported.");
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())) {
500 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
501 assert(SymbolRefExpr
&&
502 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
);
504 Inst
.addOperand(MCOperand::createExpr(getImm()));
505 } else if (isa
<MCBinaryExpr
>(getImm())) {
507 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
508 assert(BinaryExpr
&& isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
509 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
510 LanaiMCExpr::VK_Lanai_ABS_HI
);
512 Inst
.addOperand(MCOperand::createExpr(getImm()));
514 assert(false && "Operand type not supported.");
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));
522 assert(false && "Operand type not supported.");
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())) {
531 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
532 assert(SymbolRefExpr
&&
533 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
);
535 Inst
.addOperand(MCOperand::createExpr(getImm()));
536 } else if (isa
<MCSymbolRefExpr
>(getImm())) {
538 const MCSymbolRefExpr
*SymbolRefExpr
=
539 dyn_cast
<MCSymbolRefExpr
>(getImm());
540 assert(SymbolRefExpr
&&
541 SymbolRefExpr
->getKind() == MCSymbolRefExpr::VK_None
);
543 Inst
.addOperand(MCOperand::createExpr(getImm()));
544 } else if (isa
<MCBinaryExpr
>(getImm())) {
546 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
547 assert(BinaryExpr
&& isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
548 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
549 LanaiMCExpr::VK_Lanai_None
);
551 Inst
.addOperand(MCOperand::createExpr(getImm()));
553 assert(false && "Operand type not supported.");
556 void print(raw_ostream
&OS
) const override
{
559 OS
<< "Imm: " << getImm() << "\n";
562 OS
<< "Token: " << getToken() << "\n";
565 OS
<< "Reg: %r" << getReg() << "\n";
568 OS
<< "MemImm: " << *getMemOffset() << "\n";
571 OS
<< "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
574 assert(getMemOffset() == nullptr);
575 OS
<< "MemRegReg: " << getMemBaseReg() << "+"
576 << "%r" << getMemOffsetReg() << "\n";
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
;
590 static std::unique_ptr
<LanaiOperand
> createReg(MCRegister Reg
, SMLoc Start
,
592 auto Op
= std::make_unique
<LanaiOperand
>(REGISTER
);
593 Op
->Reg
.RegNum
= Reg
;
594 Op
->StartLoc
= Start
;
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
;
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
;
619 static std::unique_ptr
<LanaiOperand
>
620 MorphToMemRegReg(MCRegister BaseReg
, std::unique_ptr
<LanaiOperand
> Op
,
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;
631 static std::unique_ptr
<LanaiOperand
>
632 MorphToMemRegImm(MCRegister BaseReg
, std::unique_ptr
<LanaiOperand
> Op
,
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
;
644 } // end anonymous namespace
646 bool LanaiAsmParser::matchAndEmitInstruction(SMLoc IdLoc
, unsigned &Opcode
,
647 OperandVector
&Operands
,
650 bool MatchingInlineAsm
) {
654 switch (MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
)) {
656 Out
.emitInstruction(Inst
, SubtargetInfo
);
657 Opcode
= Inst
.getOpcode();
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
: {
665 if (ErrorInfo
!= ~0U) {
666 if (ErrorInfo
>= Operands
.size())
667 return Error(IdLoc
, "Too few operands for instruction");
669 ErrorLoc
= ((LanaiOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
670 if (ErrorLoc
== SMLoc())
673 return Error(ErrorLoc
, "Invalid operand for instruction");
679 llvm_unreachable("Unknown match type detected!");
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
685 // TODO: see if there isn't a better way to do this.
686 std::unique_ptr
<LanaiOperand
>
687 LanaiAsmParser::parseRegister(bool RestoreOnFailure
) {
688 SMLoc Start
= Parser
.getTok().getLoc();
689 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
690 std::optional
<AsmToken
> PercentTok
;
694 if (Lexer
.getKind() == AsmToken::Percent
) {
695 PercentTok
= Parser
.getTok();
698 if (Lexer
.getKind() == AsmToken::Identifier
) {
699 Reg
= MatchRegisterName(Lexer
.getTok().getIdentifier());
701 if (PercentTok
&& RestoreOnFailure
)
702 Lexer
.UnLex(*PercentTok
);
705 Parser
.Lex(); // Eat identifier token
706 return LanaiOperand::createReg(Reg
, Start
, End
);
708 if (PercentTok
&& RestoreOnFailure
)
709 Lexer
.UnLex(*PercentTok
);
713 bool LanaiAsmParser::parseRegister(MCRegister
&RegNum
, SMLoc
&StartLoc
,
715 const AsmToken
&Tok
= getParser().getTok();
716 StartLoc
= Tok
.getLoc();
717 EndLoc
= Tok
.getEndLoc();
718 std::unique_ptr
<LanaiOperand
> Op
= parseRegister(/*RestoreOnFailure=*/false);
720 RegNum
= Op
->getReg();
721 return (Op
== nullptr);
724 ParseStatus
LanaiAsmParser::tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
726 const AsmToken
&Tok
= getParser().getTok();
727 StartLoc
= Tok
.getLoc();
728 EndLoc
= Tok
.getEndLoc();
729 std::unique_ptr
<LanaiOperand
> Op
= parseRegister(/*RestoreOnFailure=*/true);
731 return ParseStatus::NoMatch
;
733 return ParseStatus::Success
;
736 std::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;
740 LanaiMCExpr::VariantKind Kind
= LanaiMCExpr::VK_Lanai_None
;
742 if (Lexer
.getKind() != AsmToken::Identifier
)
745 StringRef Identifier
;
746 if (Parser
.parseIdentifier(Identifier
))
749 // Check if identifier has a modifier
750 if (Identifier
.equals_insensitive("hi"))
751 Kind
= LanaiMCExpr::VK_Lanai_ABS_HI
;
752 else if (Identifier
.equals_insensitive("lo"))
753 Kind
= LanaiMCExpr::VK_Lanai_ABS_LO
;
755 // If the identifier corresponds to a variant then extract the real
757 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
758 if (Lexer
.getKind() != AsmToken::LParen
) {
759 Error(Lexer
.getLoc(), "Expected '('");
762 Lexer
.Lex(); // lex '('
765 if (Parser
.parseIdentifier(Identifier
))
769 // If addition parse the RHS.
770 if (Lexer
.getKind() == AsmToken::Plus
&& Parser
.parseExpression(RHS
))
773 // For variants parse the final ')'
774 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
775 if (Lexer
.getKind() != AsmToken::RParen
) {
776 Error(Lexer
.getLoc(), "Expected ')'");
779 Lexer
.Lex(); // lex ')'
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());
787 // Nest if this was an addition
789 Res
= MCBinaryExpr::createAdd(Res
, RHS
, getContext());
791 return LanaiOperand::createImm(Res
, Start
, End
);
794 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseImmediate() {
795 SMLoc Start
= Parser
.getTok().getLoc();
796 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
798 const MCExpr
*ExprVal
;
799 switch (Lexer
.getKind()) {
800 case AsmToken::Identifier
:
801 return parseIdentifier();
803 case AsmToken::Minus
:
804 case AsmToken::Integer
:
806 if (!Parser
.parseExpression(ExprVal
))
807 return LanaiOperand::createImm(ExprVal
, Start
, End
);
814 static unsigned AluWithPrePost(unsigned AluCode
, bool PreOp
, bool PostOp
) {
816 return LPAC::makePreOp(AluCode
);
818 return LPAC::makePostOp(AluCode
);
822 unsigned LanaiAsmParser::parseAluOperator(bool PreOp
, bool PostOp
) {
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");
833 static int SizeForSuffix(StringRef T
) {
834 return StringSwitch
<int>(T
).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
837 bool LanaiAsmParser::parsePrePost(StringRef Type
, int *OffsetValue
) {
838 bool PreOrPost
= false;
839 if (Lexer
.getKind() == Lexer
.peekTok(true).getKind()) {
841 if (Lexer
.is(AsmToken::Minus
))
842 *OffsetValue
= -SizeForSuffix(Type
);
843 else if (Lexer
.is(AsmToken::Plus
))
844 *OffsetValue
= SizeForSuffix(Type
);
848 // Eat the '-' '-' or '+' '+'
851 } else if (Lexer
.is(AsmToken::Star
)) {
852 Parser
.Lex(); // Eat the '*'
859 bool 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);
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
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
);
882 // Matches memory operand. Returns true if error encountered.
883 ParseStatus
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
888 // (2) '[' '*'? Register '*'? AluOperator Register ']'
890 // (3) '[' '--'|'++' Register '--'|'++' ']'
892 // (4) '[' Immediate ']' (for SLS)
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();
899 // Use 0 if no offset given
902 unsigned AluOp
= LPAC::ADD
;
903 bool PostOp
= false, PreOp
= false;
905 // Try to parse the offset
906 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
908 Op
= parseImmediate();
910 // Only continue if next token is '['
911 if (Lexer
.isNot(AsmToken::LBrac
)) {
913 return ParseStatus::NoMatch
;
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
));
919 return ParseStatus::Success
;
922 Parser
.Lex(); // Eat the '['.
923 std::unique_ptr
<LanaiOperand
> Offset
= nullptr;
927 // Determine if a pre operation
928 PreOp
= parsePrePost(Type
, &OffsetValue
);
930 Op
= parseRegister();
933 if ((Op
= parseImmediate()) && Lexer
.is(AsmToken::RBrac
)) {
934 Parser
.Lex(); // Eat the ']'
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
)));
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
));
948 return ParseStatus::Success
;
952 return Error(Parser
.getTok().getLoc(),
953 "Unknown operand, expected register or immediate");
955 BaseReg
= Op
->getReg();
957 // Determine if a post operation
959 PostOp
= parsePrePost(Type
, &OffsetValue
);
961 // If ] match form (1) else match form (2)
962 if (Lexer
.is(AsmToken::RBrac
)) {
963 Parser
.Lex(); // Eat the ']'.
965 SMLoc Start
= Parser
.getTok().getLoc();
967 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
968 const MCConstantExpr
*OffsetConstExpr
=
969 MCConstantExpr::create(OffsetValue
, getContext());
970 Offset
= LanaiOperand::createImm(OffsetConstExpr
, Start
, End
);
973 if (Offset
|| OffsetValue
!= 0)
974 return Error(Parser
.getTok().getLoc(), "Expected ']'");
977 AluOp
= parseAluOperator(PreOp
, PostOp
);
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 ']'.
986 // First form has addition as operator. Add pre- or post-op indicator as
988 AluOp
= AluWithPrePost(AluOp
, PreOp
, PostOp
);
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 "
998 ? LanaiOperand::MorphToMemRegImm(BaseReg
, std::move(Offset
), AluOp
)
999 : LanaiOperand::MorphToMemRegReg(BaseReg
, std::move(Offset
), AluOp
));
1001 return ParseStatus::Success
;
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.
1007 ParseStatus
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
);
1013 if (Result
.isSuccess())
1015 if (Result
.isFailure()) {
1016 Parser
.eatToEndOfStatement();
1020 // Attempt to parse token as register
1021 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
1023 // Attempt to parse token as immediate
1025 Op
= parseImmediate();
1027 // If the token could not be parsed then fail
1029 Error(Parser
.getTok().getLoc(), "Unknown operand");
1030 Parser
.eatToEndOfStatement();
1031 return ParseStatus::Failure
;
1034 // Push back parsed operand into list of operands
1035 Operands
->push_back(std::move(Op
));
1037 return ParseStatus::Success
;
1040 // Split the mnemonic into ASM operand, conditional code and instruction
1041 // qualifier (half-word, byte).
1042 StringRef
LanaiAsmParser::splitMnemonic(StringRef Name
, SMLoc NameLoc
,
1043 OperandVector
*Operands
) {
1044 size_t Next
= Name
.find('.');
1046 StringRef Mnemonic
= Name
;
1048 bool IsBRR
= Mnemonic
.consume_back(".r");
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'.
1056 LPCC::CondCode CondCode
=
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
));
1064 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
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"))) {
1076 LPCC::CondCode CondCode
= LPCC::suffixToLanaiCondCode(Mnemonic
);
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);
1087 Mnemonic
= Mnemonic
.substr(0, Next
);
1089 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1090 Operands
->push_back(LanaiOperand::createImm(
1091 MCConstantExpr::create(CondCode
, getContext()), NameLoc
, NameLoc
));
1096 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1098 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
1104 static bool IsMemoryAssignmentError(const OperandVector
&Operands
) {
1105 // Detects if a memory operation has an erroneous base register modification.
1106 // Memory operations are detected by matching the types of operands.
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;
1114 if (Operands
.size() < 5)
1116 else if (Operands
[0]->isToken() && Operands
[1]->isReg() &&
1117 Operands
[2]->isImm() && Operands
[3]->isImm() && Operands
[4]->isReg())
1119 else if (Operands
[0]->isToken() && Operands
[1]->isToken() &&
1120 Operands
[2]->isReg() && Operands
[3]->isImm() &&
1121 Operands
[4]->isImm() && Operands
[5]->isReg())
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();
1141 static bool IsRegister(const MCParsedAsmOperand
&op
) {
1142 return static_cast<const LanaiOperand
&>(op
).isReg();
1145 static bool MaybePredicatedInst(const OperandVector
&Operands
) {
1146 if (Operands
.size() < 4 || !IsRegister(*Operands
[1]) ||
1147 !IsRegister(*Operands
[2]))
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)
1162 bool LanaiAsmParser::parseInstruction(ParseInstructionInfo
& /*Info*/,
1163 StringRef Name
, SMLoc NameLoc
,
1164 OperandVector
&Operands
) {
1165 // First operand is token for instruction
1166 StringRef Mnemonic
= splitMnemonic(Name
, NameLoc
, &Operands
);
1168 // If there are no more operands, then finish
1169 if (Lexer
.is(AsmToken::EndOfStatement
))
1172 // Parse first operand
1173 if (!parseOperand(&Operands
, Mnemonic
).isSuccess())
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()),
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
));
1197 // Parse until end of statement, consuming commas between operands
1198 while (Lexer
.isNot(AsmToken::EndOfStatement
) && Lexer
.is(AsmToken::Comma
)) {
1199 // Consume comma token
1202 // Parse next operand
1203 if (!parseOperand(&Operands
, Mnemonic
).isSuccess())
1207 if (IsMemoryAssignmentError(Operands
)) {
1208 Error(Parser
.getTok().getLoc(),
1209 "the destination register can't equal the base register in an "
1210 "instruction that modifies the base register.");
1214 // Insert always true operand for instruction that may be predicated but
1215 // are not. Currently the autogenerated parser always expects a predicate.
1216 if (MaybePredicatedInst(Operands
)) {
1217 Operands
.insert(Operands
.begin() + 1,
1218 LanaiOperand::createImm(
1219 MCConstantExpr::create(LPCC::ICC_T
, getContext()),
1226 #define GET_REGISTER_MATCHER
1227 #define GET_MATCHER_IMPLEMENTATION
1228 #include "LanaiGenAsmMatcher.inc"
1230 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeLanaiAsmParser() {
1231 RegisterMCAsmParser
<LanaiAsmParser
> x(getTheLanaiTarget());