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/STLExtras.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCParser/MCAsmLexer.h"
21 #include "llvm/MC/MCParser/MCAsmParser.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.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/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
41 // Auto-generated by TableGen
42 static unsigned MatchRegisterName(StringRef Name
);
48 class LanaiAsmParser
: public MCTargetAsmParser
{
50 std::unique_ptr
<LanaiOperand
> parseRegister();
52 std::unique_ptr
<LanaiOperand
> parseImmediate();
54 std::unique_ptr
<LanaiOperand
> parseIdentifier();
56 unsigned parseAluOperator(bool PreOp
, bool PostOp
);
58 // Split the mnemonic stripping conditional code and quantifiers
59 StringRef
splitMnemonic(StringRef Name
, SMLoc NameLoc
,
60 OperandVector
*Operands
);
62 bool parsePrePost(StringRef Type
, int *OffsetValue
);
64 bool ParseDirective(AsmToken DirectiveID
) override
;
66 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
67 SMLoc NameLoc
, OperandVector
&Operands
) override
;
69 bool ParseRegister(unsigned &RegNum
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
71 bool MatchAndEmitInstruction(SMLoc IdLoc
, unsigned &Opcode
,
72 OperandVector
&Operands
, MCStreamer
&Out
,
74 bool MatchingInlineAsm
) override
;
76 // Auto-generated instruction matching functions
77 #define GET_ASSEMBLER_HEADER
78 #include "LanaiGenAsmMatcher.inc"
80 OperandMatchResultTy
parseOperand(OperandVector
*Operands
,
83 OperandMatchResultTy
parseMemoryOperand(OperandVector
&Operands
);
86 LanaiAsmParser(const MCSubtargetInfo
&STI
, MCAsmParser
&Parser
,
87 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
88 : MCTargetAsmParser(Options
, STI
, MII
), Parser(Parser
),
89 Lexer(Parser
.getLexer()), SubtargetInfo(STI
) {
91 ComputeAvailableFeatures(SubtargetInfo
.getFeatureBits()));
98 const MCSubtargetInfo
&SubtargetInfo
;
101 // LanaiOperand - Instances of this class represented a parsed machine
103 struct LanaiOperand
: public MCParsedAsmOperand
{
113 SMLoc StartLoc
, EndLoc
;
132 const MCExpr
*Offset
;
142 explicit LanaiOperand(KindTy Kind
) : MCParsedAsmOperand(), Kind(Kind
) {}
145 // The functions below are used by the autogenerated ASM matcher and hence to
146 // be of the form expected.
148 // getStartLoc - Gets location of the first token of this operand
149 SMLoc
getStartLoc() const override
{ return StartLoc
; }
151 // getEndLoc - Gets location of the last token of this operand
152 SMLoc
getEndLoc() const override
{ return EndLoc
; }
154 unsigned getReg() const override
{
155 assert(isReg() && "Invalid type access!");
159 const MCExpr
*getImm() const {
160 assert(isImm() && "Invalid type access!");
164 StringRef
getToken() const {
165 assert(isToken() && "Invalid type access!");
166 return StringRef(Tok
.Data
, Tok
.Length
);
169 unsigned getMemBaseReg() const {
170 assert(isMem() && "Invalid type access!");
174 unsigned getMemOffsetReg() const {
175 assert(isMem() && "Invalid type access!");
176 return Mem
.OffsetReg
;
179 const MCExpr
*getMemOffset() const {
180 assert(isMem() && "Invalid type access!");
184 unsigned getMemOp() const {
185 assert(isMem() && "Invalid type access!");
189 // Functions for testing operand type
190 bool isReg() const override
{ return Kind
== REGISTER
; }
192 bool isImm() const override
{ return Kind
== IMMEDIATE
; }
194 bool isMem() const override
{
195 return isMemImm() || isMemRegImm() || isMemRegReg();
198 bool isMemImm() const { return Kind
== MEMORY_IMM
; }
200 bool isMemRegImm() const { return Kind
== MEMORY_REG_IMM
; }
202 bool isMemRegReg() const { return Kind
== MEMORY_REG_REG
; }
204 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
206 bool isToken() const override
{ return Kind
== TOKEN
; }
213 const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
216 int64_t Value
= MCE
->getValue();
217 // Check if value fits in 25 bits with 2 least significant bits 0.
218 return isShiftedUInt
<23, 2>(static_cast<int32_t>(Value
));
221 bool isBrTarget() { return isBrImm() || isToken(); }
223 bool isCallTarget() { return isImm() || isToken(); }
230 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
231 int64_t Value
= ConstExpr
->getValue();
232 return Value
!= 0 && isShiftedUInt
<16, 16>(Value
);
235 // Symbolic reference expression
236 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
237 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
;
240 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
))
241 if (const LanaiMCExpr
*SymbolRefExpr
=
242 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
243 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
;
248 bool isHiImm16And() {
252 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
254 int64_t Value
= ConstExpr
->getValue();
255 // Check if in the form 0xXYZWffff
256 return (Value
!= 0) && ((Value
& ~0xffff0000) == 0xffff);
266 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
267 int64_t Value
= ConstExpr
->getValue();
268 // Check if value fits in 16 bits
269 return isUInt
<16>(static_cast<int32_t>(Value
));
272 // Symbolic reference expression
273 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
274 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
277 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
))
278 if (const LanaiMCExpr
*SymbolRefExpr
=
279 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
280 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
285 bool isLoImm16Signed() {
290 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
291 int64_t Value
= ConstExpr
->getValue();
292 // Check if value fits in 16 bits or value of the form 0xffffxyzw
293 return isInt
<16>(static_cast<int32_t>(Value
));
296 // Symbolic reference expression
297 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
298 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
301 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
))
302 if (const LanaiMCExpr
*SymbolRefExpr
=
303 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
304 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
309 bool isLoImm16And() {
313 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
315 int64_t Value
= ConstExpr
->getValue();
316 // Check if in the form 0xffffXYZW
317 return ((Value
& ~0xffff) == 0xffff0000);
326 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
329 int64_t Value
= ConstExpr
->getValue();
330 return (Value
>= -31) && (Value
<= 31);
338 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
339 int64_t Value
= ConstExpr
->getValue();
340 return isUInt
<21>(Value
);
343 // Symbolic reference expression
344 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
345 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
;
346 if (const MCSymbolRefExpr
*SymbolRefExpr
=
347 dyn_cast
<MCSymbolRefExpr
>(Imm
.Value
)) {
348 return SymbolRefExpr
->getKind() == MCSymbolRefExpr::VK_None
;
352 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
)) {
353 if (const LanaiMCExpr
*SymbolRefExpr
=
354 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
355 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
;
356 if (const MCSymbolRefExpr
*SymbolRefExpr
=
357 dyn_cast
<MCSymbolRefExpr
>(BinaryExpr
->getLHS()))
358 return SymbolRefExpr
->getKind() == MCSymbolRefExpr::VK_None
;
368 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
371 int64_t Value
= ConstExpr
->getValue();
372 return isInt
<10>(Value
);
379 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
382 uint64_t Value
= ConstExpr
->getValue();
383 // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
384 // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
385 // value corresponds to a valid condition code.
386 return Value
< LPCC::UNKNOWN
;
389 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
390 // Add as immediates where possible. Null MCExpr = 0
392 Inst
.addOperand(MCOperand::createImm(0));
393 else if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Expr
))
395 MCOperand::createImm(static_cast<int32_t>(ConstExpr
->getValue())));
397 Inst
.addOperand(MCOperand::createExpr(Expr
));
400 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
401 assert(N
== 1 && "Invalid number of operands!");
402 Inst
.addOperand(MCOperand::createReg(getReg()));
405 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
406 assert(N
== 1 && "Invalid number of operands!");
407 addExpr(Inst
, getImm());
410 void addBrTargetOperands(MCInst
&Inst
, unsigned N
) const {
411 assert(N
== 1 && "Invalid number of operands!");
412 addExpr(Inst
, getImm());
415 void addCallTargetOperands(MCInst
&Inst
, unsigned N
) const {
416 assert(N
== 1 && "Invalid number of operands!");
417 addExpr(Inst
, getImm());
420 void addCondCodeOperands(MCInst
&Inst
, unsigned N
) const {
421 assert(N
== 1 && "Invalid number of operands!");
422 addExpr(Inst
, getImm());
425 void addMemImmOperands(MCInst
&Inst
, unsigned N
) const {
426 assert(N
== 1 && "Invalid number of operands!");
427 const MCExpr
*Expr
= getMemOffset();
431 void addMemRegImmOperands(MCInst
&Inst
, unsigned N
) const {
432 assert(N
== 3 && "Invalid number of operands!");
433 Inst
.addOperand(MCOperand::createReg(getMemBaseReg()));
434 const MCExpr
*Expr
= getMemOffset();
436 Inst
.addOperand(MCOperand::createImm(getMemOp()));
439 void addMemRegRegOperands(MCInst
&Inst
, unsigned N
) const {
440 assert(N
== 3 && "Invalid number of operands!");
441 Inst
.addOperand(MCOperand::createReg(getMemBaseReg()));
442 assert(getMemOffsetReg() != 0 && "Invalid offset");
443 Inst
.addOperand(MCOperand::createReg(getMemOffsetReg()));
444 Inst
.addOperand(MCOperand::createImm(getMemOp()));
447 void addMemSplsOperands(MCInst
&Inst
, unsigned N
) const {
449 addMemRegImmOperands(Inst
, N
);
451 addMemRegRegOperands(Inst
, N
);
454 void addImmShiftOperands(MCInst
&Inst
, unsigned N
) const {
455 assert(N
== 1 && "Invalid number of operands!");
456 addExpr(Inst
, getImm());
459 void addImm10Operands(MCInst
&Inst
, unsigned N
) const {
460 assert(N
== 1 && "Invalid number of operands!");
461 addExpr(Inst
, getImm());
464 void addLoImm16Operands(MCInst
&Inst
, unsigned N
) const {
465 assert(N
== 1 && "Invalid number of operands!");
466 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
468 MCOperand::createImm(static_cast<int32_t>(ConstExpr
->getValue())));
469 else if (isa
<LanaiMCExpr
>(getImm())) {
471 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
472 assert(SymbolRefExpr
&&
473 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
);
475 Inst
.addOperand(MCOperand::createExpr(getImm()));
476 } else if (isa
<MCBinaryExpr
>(getImm())) {
478 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
479 assert(BinaryExpr
&& isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
480 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
481 LanaiMCExpr::VK_Lanai_ABS_LO
);
483 Inst
.addOperand(MCOperand::createExpr(getImm()));
485 assert(false && "Operand type not supported.");
488 void addLoImm16AndOperands(MCInst
&Inst
, unsigned N
) const {
489 assert(N
== 1 && "Invalid number of operands!");
490 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
491 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() & 0xffff));
493 assert(false && "Operand type not supported.");
496 void addHiImm16Operands(MCInst
&Inst
, unsigned N
) const {
497 assert(N
== 1 && "Invalid number of operands!");
498 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
499 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() >> 16));
500 else if (isa
<LanaiMCExpr
>(getImm())) {
502 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
503 assert(SymbolRefExpr
&&
504 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
);
506 Inst
.addOperand(MCOperand::createExpr(getImm()));
507 } else if (isa
<MCBinaryExpr
>(getImm())) {
509 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
510 assert(BinaryExpr
&& isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
511 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
512 LanaiMCExpr::VK_Lanai_ABS_HI
);
514 Inst
.addOperand(MCOperand::createExpr(getImm()));
516 assert(false && "Operand type not supported.");
519 void addHiImm16AndOperands(MCInst
&Inst
, unsigned N
) const {
520 assert(N
== 1 && "Invalid number of operands!");
521 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
522 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() >> 16));
524 assert(false && "Operand type not supported.");
527 void addLoImm21Operands(MCInst
&Inst
, unsigned N
) const {
528 assert(N
== 1 && "Invalid number of operands!");
529 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
530 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() & 0x1fffff));
531 else if (isa
<LanaiMCExpr
>(getImm())) {
533 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
534 assert(SymbolRefExpr
&&
535 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
);
537 Inst
.addOperand(MCOperand::createExpr(getImm()));
538 } else if (isa
<MCSymbolRefExpr
>(getImm())) {
540 const MCSymbolRefExpr
*SymbolRefExpr
=
541 dyn_cast
<MCSymbolRefExpr
>(getImm());
542 assert(SymbolRefExpr
&&
543 SymbolRefExpr
->getKind() == MCSymbolRefExpr::VK_None
);
545 Inst
.addOperand(MCOperand::createExpr(getImm()));
546 } else if (isa
<MCBinaryExpr
>(getImm())) {
548 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
549 assert(BinaryExpr
&& isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
550 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
551 LanaiMCExpr::VK_Lanai_None
);
553 Inst
.addOperand(MCOperand::createExpr(getImm()));
555 assert(false && "Operand type not supported.");
558 void print(raw_ostream
&OS
) const override
{
561 OS
<< "Imm: " << getImm() << "\n";
564 OS
<< "Token: " << getToken() << "\n";
567 OS
<< "Reg: %r" << getReg() << "\n";
570 OS
<< "MemImm: " << *getMemOffset() << "\n";
573 OS
<< "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
576 assert(getMemOffset() == nullptr);
577 OS
<< "MemRegReg: " << getMemBaseReg() << "+"
578 << "%r" << getMemOffsetReg() << "\n";
583 static std::unique_ptr
<LanaiOperand
> CreateToken(StringRef Str
, SMLoc Start
) {
584 auto Op
= std::make_unique
<LanaiOperand
>(TOKEN
);
585 Op
->Tok
.Data
= Str
.data();
586 Op
->Tok
.Length
= Str
.size();
587 Op
->StartLoc
= Start
;
592 static std::unique_ptr
<LanaiOperand
> createReg(unsigned RegNum
, SMLoc Start
,
594 auto Op
= std::make_unique
<LanaiOperand
>(REGISTER
);
595 Op
->Reg
.RegNum
= RegNum
;
596 Op
->StartLoc
= Start
;
601 static std::unique_ptr
<LanaiOperand
> createImm(const MCExpr
*Value
,
602 SMLoc Start
, SMLoc End
) {
603 auto Op
= std::make_unique
<LanaiOperand
>(IMMEDIATE
);
604 Op
->Imm
.Value
= Value
;
605 Op
->StartLoc
= Start
;
610 static std::unique_ptr
<LanaiOperand
>
611 MorphToMemImm(std::unique_ptr
<LanaiOperand
> Op
) {
612 const MCExpr
*Imm
= Op
->getImm();
613 Op
->Kind
= MEMORY_IMM
;
615 Op
->Mem
.AluOp
= LPAC::ADD
;
616 Op
->Mem
.OffsetReg
= 0;
617 Op
->Mem
.Offset
= Imm
;
621 static std::unique_ptr
<LanaiOperand
>
622 MorphToMemRegReg(unsigned BaseReg
, std::unique_ptr
<LanaiOperand
> Op
,
624 unsigned OffsetReg
= Op
->getReg();
625 Op
->Kind
= MEMORY_REG_REG
;
626 Op
->Mem
.BaseReg
= BaseReg
;
627 Op
->Mem
.AluOp
= AluOp
;
628 Op
->Mem
.OffsetReg
= OffsetReg
;
629 Op
->Mem
.Offset
= nullptr;
633 static std::unique_ptr
<LanaiOperand
>
634 MorphToMemRegImm(unsigned BaseReg
, std::unique_ptr
<LanaiOperand
> Op
,
636 const MCExpr
*Imm
= Op
->getImm();
637 Op
->Kind
= MEMORY_REG_IMM
;
638 Op
->Mem
.BaseReg
= BaseReg
;
639 Op
->Mem
.AluOp
= AluOp
;
640 Op
->Mem
.OffsetReg
= 0;
641 Op
->Mem
.Offset
= Imm
;
646 } // end anonymous namespace
648 bool LanaiAsmParser::ParseDirective(AsmToken
/*DirectiveId*/) { return true; }
650 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc
, unsigned &Opcode
,
651 OperandVector
&Operands
,
654 bool MatchingInlineAsm
) {
658 switch (MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
)) {
660 Out
.EmitInstruction(Inst
, SubtargetInfo
);
661 Opcode
= Inst
.getOpcode();
663 case Match_MissingFeature
:
664 return Error(IdLoc
, "Instruction use requires option to be enabled");
665 case Match_MnemonicFail
:
666 return Error(IdLoc
, "Unrecognized instruction mnemonic");
667 case Match_InvalidOperand
: {
669 if (ErrorInfo
!= ~0U) {
670 if (ErrorInfo
>= Operands
.size())
671 return Error(IdLoc
, "Too few operands for instruction");
673 ErrorLoc
= ((LanaiOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
674 if (ErrorLoc
== SMLoc())
677 return Error(ErrorLoc
, "Invalid operand for instruction");
683 llvm_unreachable("Unknown match type detected!");
686 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
687 // backwards compatible with GCC and the different ways inline assembly is
689 // TODO: see if there isn't a better way to do this.
690 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseRegister() {
691 SMLoc Start
= Parser
.getTok().getLoc();
692 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
696 if (Lexer
.getKind() == AsmToken::Percent
)
698 if (Lexer
.getKind() == AsmToken::Identifier
) {
699 RegNum
= MatchRegisterName(Lexer
.getTok().getIdentifier());
702 Parser
.Lex(); // Eat identifier token
703 return LanaiOperand::createReg(RegNum
, Start
, End
);
708 bool LanaiAsmParser::ParseRegister(unsigned &RegNum
, SMLoc
&StartLoc
,
710 const AsmToken
&Tok
= getParser().getTok();
711 StartLoc
= Tok
.getLoc();
712 EndLoc
= Tok
.getEndLoc();
713 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
715 RegNum
= Op
->getReg();
716 return (Op
== nullptr);
719 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseIdentifier() {
720 SMLoc Start
= Parser
.getTok().getLoc();
721 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
722 const MCExpr
*Res
, *RHS
= nullptr;
723 LanaiMCExpr::VariantKind Kind
= LanaiMCExpr::VK_Lanai_None
;
725 if (Lexer
.getKind() != AsmToken::Identifier
)
728 StringRef Identifier
;
729 if (Parser
.parseIdentifier(Identifier
))
732 // Check if identifier has a modifier
733 if (Identifier
.equals_lower("hi"))
734 Kind
= LanaiMCExpr::VK_Lanai_ABS_HI
;
735 else if (Identifier
.equals_lower("lo"))
736 Kind
= LanaiMCExpr::VK_Lanai_ABS_LO
;
738 // If the identifier corresponds to a variant then extract the real
740 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
741 if (Lexer
.getKind() != AsmToken::LParen
) {
742 Error(Lexer
.getLoc(), "Expected '('");
745 Lexer
.Lex(); // lex '('
748 if (Parser
.parseIdentifier(Identifier
))
752 // If addition parse the RHS.
753 if (Lexer
.getKind() == AsmToken::Plus
&& Parser
.parseExpression(RHS
))
756 // For variants parse the final ')'
757 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
758 if (Lexer
.getKind() != AsmToken::RParen
) {
759 Error(Lexer
.getLoc(), "Expected ')'");
762 Lexer
.Lex(); // lex ')'
765 End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
766 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
767 const MCExpr
*Expr
= MCSymbolRefExpr::create(Sym
, getContext());
768 Res
= LanaiMCExpr::create(Kind
, Expr
, getContext());
770 // Nest if this was an addition
772 Res
= MCBinaryExpr::createAdd(Res
, RHS
, getContext());
774 return LanaiOperand::createImm(Res
, Start
, End
);
777 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseImmediate() {
778 SMLoc Start
= Parser
.getTok().getLoc();
779 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
781 const MCExpr
*ExprVal
;
782 switch (Lexer
.getKind()) {
783 case AsmToken::Identifier
:
784 return parseIdentifier();
786 case AsmToken::Minus
:
787 case AsmToken::Integer
:
789 if (!Parser
.parseExpression(ExprVal
))
790 return LanaiOperand::createImm(ExprVal
, Start
, End
);
797 static unsigned AluWithPrePost(unsigned AluCode
, bool PreOp
, bool PostOp
) {
799 return LPAC::makePreOp(AluCode
);
801 return LPAC::makePostOp(AluCode
);
805 unsigned LanaiAsmParser::parseAluOperator(bool PreOp
, bool PostOp
) {
807 Parser
.parseIdentifier(IdString
);
808 unsigned AluCode
= LPAC::stringToLanaiAluCode(IdString
);
809 if (AluCode
== LPAC::UNKNOWN
) {
810 Error(Parser
.getTok().getLoc(), "Can't parse ALU operator");
816 static int SizeForSuffix(StringRef T
) {
817 return StringSwitch
<int>(T
).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
820 bool LanaiAsmParser::parsePrePost(StringRef Type
, int *OffsetValue
) {
821 bool PreOrPost
= false;
822 if (Lexer
.getKind() == Lexer
.peekTok(true).getKind()) {
824 if (Lexer
.is(AsmToken::Minus
))
825 *OffsetValue
= -SizeForSuffix(Type
);
826 else if (Lexer
.is(AsmToken::Plus
))
827 *OffsetValue
= SizeForSuffix(Type
);
831 // Eat the '-' '-' or '+' '+'
834 } else if (Lexer
.is(AsmToken::Star
)) {
835 Parser
.Lex(); // Eat the '*'
842 bool shouldBeSls(const LanaiOperand
&Op
) {
843 // The instruction should be encoded as an SLS if the constant is word
844 // aligned and will fit in 21 bits
845 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Op
.getImm())) {
846 int64_t Value
= ConstExpr
->getValue();
847 return (Value
% 4 == 0) && (Value
>= 0) && (Value
<= 0x1fffff);
849 // The instruction should be encoded as an SLS if the operand is a symbolic
850 // reference with no variant.
851 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Op
.getImm()))
852 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
;
853 // The instruction should be encoded as an SLS if the operand is a binary
854 // expression with the left-hand side being a symbolic reference with no
856 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Op
.getImm())) {
857 const LanaiMCExpr
*LHSSymbolRefExpr
=
858 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS());
859 return (LHSSymbolRefExpr
&&
860 LHSSymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
);
865 // Matches memory operand. Returns true if error encountered.
867 LanaiAsmParser::parseMemoryOperand(OperandVector
&Operands
) {
868 // Try to match a memory operand.
869 // The memory operands are of the form:
870 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
872 // (2) '[' '*'? Register '*'? AluOperator Register ']'
874 // (3) '[' '--'|'++' Register '--'|'++' ']'
876 // (4) '[' Immediate ']' (for SLS)
878 // Store the type for use in parsing pre/post increment/decrement operators
880 if (Operands
[0]->isToken())
881 Type
= static_cast<LanaiOperand
*>(Operands
[0].get())->getToken();
883 // Use 0 if no offset given
885 unsigned BaseReg
= 0;
886 unsigned AluOp
= LPAC::ADD
;
887 bool PostOp
= false, PreOp
= false;
889 // Try to parse the offset
890 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
892 Op
= parseImmediate();
894 // Only continue if next token is '['
895 if (Lexer
.isNot(AsmToken::LBrac
)) {
897 return MatchOperand_NoMatch
;
899 // The start of this custom parsing overlaps with register/immediate so
900 // consider this as a successful match of an operand of that type as the
901 // token stream can't be rewound to allow them to match separately.
902 Operands
.push_back(std::move(Op
));
903 return MatchOperand_Success
;
906 Parser
.Lex(); // Eat the '['.
907 std::unique_ptr
<LanaiOperand
> Offset
= nullptr;
911 // Determine if a pre operation
912 PreOp
= parsePrePost(Type
, &OffsetValue
);
914 Op
= parseRegister();
917 if ((Op
= parseImmediate()) && Lexer
.is(AsmToken::RBrac
)) {
918 Parser
.Lex(); // Eat the ']'
920 // Memory address operations aligned to word boundary are encoded as
921 // SLS, the rest as RM.
922 if (shouldBeSls(*Op
)) {
923 Operands
.push_back(LanaiOperand::MorphToMemImm(std::move(Op
)));
925 if (!Op
->isLoImm16Signed()) {
926 Error(Parser
.getTok().getLoc(),
927 "Memory address is not word "
928 "aligned and larger than class RM can handle");
929 return MatchOperand_ParseFail
;
931 Operands
.push_back(LanaiOperand::MorphToMemRegImm(
932 Lanai::R0
, std::move(Op
), LPAC::ADD
));
934 return MatchOperand_Success
;
938 Error(Parser
.getTok().getLoc(),
939 "Unknown operand, expected register or immediate");
940 return MatchOperand_ParseFail
;
942 BaseReg
= Op
->getReg();
944 // Determine if a post operation
946 PostOp
= parsePrePost(Type
, &OffsetValue
);
948 // If ] match form (1) else match form (2)
949 if (Lexer
.is(AsmToken::RBrac
)) {
950 Parser
.Lex(); // Eat the ']'.
952 SMLoc Start
= Parser
.getTok().getLoc();
954 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
955 const MCConstantExpr
*OffsetConstExpr
=
956 MCConstantExpr::create(OffsetValue
, getContext());
957 Offset
= LanaiOperand::createImm(OffsetConstExpr
, Start
, End
);
960 if (Offset
|| OffsetValue
!= 0) {
961 Error(Parser
.getTok().getLoc(), "Expected ']'");
962 return MatchOperand_ParseFail
;
966 AluOp
= parseAluOperator(PreOp
, PostOp
);
968 // Second form requires offset register
969 Offset
= parseRegister();
970 if (!BaseReg
|| Lexer
.isNot(AsmToken::RBrac
)) {
971 Error(Parser
.getTok().getLoc(), "Expected ']'");
972 return MatchOperand_ParseFail
;
974 Parser
.Lex(); // Eat the ']'.
977 // First form has addition as operator. Add pre- or post-op indicator as
979 AluOp
= AluWithPrePost(AluOp
, PreOp
, PostOp
);
981 // Ensure immediate offset is not too large
982 if (Offset
->isImm() && !Offset
->isLoImm16Signed()) {
983 Error(Parser
.getTok().getLoc(),
984 "Memory address is not word "
985 "aligned and larger than class RM can handle");
986 return MatchOperand_ParseFail
;
991 ? LanaiOperand::MorphToMemRegImm(BaseReg
, std::move(Offset
), AluOp
)
992 : LanaiOperand::MorphToMemRegReg(BaseReg
, std::move(Offset
), AluOp
));
994 return MatchOperand_Success
;
997 // Looks at a token type and creates the relevant operand from this
998 // information, adding to operands.
999 // If operand was parsed, returns false, else true.
1000 OperandMatchResultTy
1001 LanaiAsmParser::parseOperand(OperandVector
*Operands
, StringRef Mnemonic
) {
1002 // Check if the current operand has a custom associated parser, if so, try to
1003 // custom parse the operand, or fallback to the general approach.
1004 OperandMatchResultTy Result
= MatchOperandParserImpl(*Operands
, Mnemonic
);
1006 if (Result
== MatchOperand_Success
)
1008 if (Result
== MatchOperand_ParseFail
) {
1009 Parser
.eatToEndOfStatement();
1013 // Attempt to parse token as register
1014 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
1016 // Attempt to parse token as immediate
1018 Op
= parseImmediate();
1020 // If the token could not be parsed then fail
1022 Error(Parser
.getTok().getLoc(), "Unknown operand");
1023 Parser
.eatToEndOfStatement();
1024 return MatchOperand_ParseFail
;
1027 // Push back parsed operand into list of operands
1028 Operands
->push_back(std::move(Op
));
1030 return MatchOperand_Success
;
1033 // Split the mnemonic into ASM operand, conditional code and instruction
1034 // qualifier (half-word, byte).
1035 StringRef
LanaiAsmParser::splitMnemonic(StringRef Name
, SMLoc NameLoc
,
1036 OperandVector
*Operands
) {
1037 size_t Next
= Name
.find('.');
1039 StringRef Mnemonic
= Name
;
1042 if (Name
.endswith(".r")) {
1043 Mnemonic
= Name
.substr(0, Name
.size() - 2);
1047 // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1048 if (Mnemonic
[0] == 'b' ||
1049 (Mnemonic
[0] == 's' && !Mnemonic
.startswith("sel") &&
1050 !Mnemonic
.startswith("st"))) {
1051 // Parse instructions with a conditional code. For example, 'bne' is
1052 // converted into two operands 'b' and 'ne'.
1053 LPCC::CondCode CondCode
=
1054 LPCC::suffixToLanaiCondCode(Mnemonic
.substr(1, Next
));
1055 if (CondCode
!= LPCC::UNKNOWN
) {
1056 Mnemonic
= Mnemonic
.slice(0, 1);
1057 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1058 Operands
->push_back(LanaiOperand::createImm(
1059 MCConstantExpr::create(CondCode
, getContext()), NameLoc
, NameLoc
));
1061 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
1067 // Parse other instructions with condition codes (RR instructions).
1068 // We ignore .f here and assume they are flag-setting operations, not
1069 // conditional codes (except for select instructions where flag-setting
1070 // variants are not yet implemented).
1071 if (Mnemonic
.startswith("sel") ||
1072 (!Mnemonic
.endswith(".f") && !Mnemonic
.startswith("st"))) {
1073 LPCC::CondCode CondCode
= LPCC::suffixToLanaiCondCode(Mnemonic
);
1074 if (CondCode
!= LPCC::UNKNOWN
) {
1075 size_t Next
= Mnemonic
.rfind('.', Name
.size());
1076 // 'sel' doesn't use a predicate operand whose printer adds the period,
1077 // but instead has the period as part of the identifier (i.e., 'sel.' is
1078 // expected by the generated matcher). If the mnemonic starts with 'sel'
1079 // then include the period as part of the mnemonic, else don't include it
1080 // as part of the mnemonic.
1081 if (Mnemonic
.startswith("sel")) {
1082 Mnemonic
= Mnemonic
.substr(0, Next
+ 1);
1084 Mnemonic
= Mnemonic
.substr(0, Next
);
1086 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1087 Operands
->push_back(LanaiOperand::createImm(
1088 MCConstantExpr::create(CondCode
, getContext()), NameLoc
, NameLoc
));
1093 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1095 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
1101 static bool IsMemoryAssignmentError(const OperandVector
&Operands
) {
1102 // Detects if a memory operation has an erroneous base register modification.
1103 // Memory operations are detected by matching the types of operands.
1105 // TODO: This test is focussed on one specific instance (ld/st).
1106 // Extend it to handle more cases or be more robust.
1107 bool Modifies
= false;
1111 if (Operands
.size() < 5)
1113 else if (Operands
[0]->isToken() && Operands
[1]->isReg() &&
1114 Operands
[2]->isImm() && Operands
[3]->isImm() && Operands
[4]->isReg())
1116 else if (Operands
[0]->isToken() && Operands
[1]->isToken() &&
1117 Operands
[2]->isReg() && Operands
[3]->isImm() &&
1118 Operands
[4]->isImm() && Operands
[5]->isReg())
1123 int PossibleAluOpIdx
= Offset
+ 3;
1124 int PossibleBaseIdx
= Offset
+ 1;
1125 int PossibleDestIdx
= Offset
+ 4;
1126 if (LanaiOperand
*PossibleAluOp
=
1127 static_cast<LanaiOperand
*>(Operands
[PossibleAluOpIdx
].get()))
1128 if (PossibleAluOp
->isImm())
1129 if (const MCConstantExpr
*ConstExpr
=
1130 dyn_cast
<MCConstantExpr
>(PossibleAluOp
->getImm()))
1131 Modifies
= LPAC::modifiesOp(ConstExpr
->getValue());
1132 return Modifies
&& Operands
[PossibleBaseIdx
]->isReg() &&
1133 Operands
[PossibleDestIdx
]->isReg() &&
1134 Operands
[PossibleBaseIdx
]->getReg() ==
1135 Operands
[PossibleDestIdx
]->getReg();
1138 static bool IsRegister(const MCParsedAsmOperand
&op
) {
1139 return static_cast<const LanaiOperand
&>(op
).isReg();
1142 static bool MaybePredicatedInst(const OperandVector
&Operands
) {
1143 if (Operands
.size() < 4 || !IsRegister(*Operands
[1]) ||
1144 !IsRegister(*Operands
[2]))
1146 return StringSwitch
<bool>(
1147 static_cast<const LanaiOperand
&>(*Operands
[0]).getToken())
1148 .StartsWith("addc", true)
1149 .StartsWith("add", true)
1150 .StartsWith("and", true)
1151 .StartsWith("sh", true)
1152 .StartsWith("subb", true)
1153 .StartsWith("sub", true)
1154 .StartsWith("or", true)
1155 .StartsWith("xor", true)
1159 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo
& /*Info*/,
1160 StringRef Name
, SMLoc NameLoc
,
1161 OperandVector
&Operands
) {
1162 // First operand is token for instruction
1163 StringRef Mnemonic
= splitMnemonic(Name
, NameLoc
, &Operands
);
1165 // If there are no more operands, then finish
1166 if (Lexer
.is(AsmToken::EndOfStatement
))
1169 // Parse first operand
1170 if (parseOperand(&Operands
, Mnemonic
) != MatchOperand_Success
)
1173 // If it is a st instruction with one 1 operand then it is a "store true".
1174 // Transform <"st"> to <"s">, <LPCC:ICC_T>
1175 if (Lexer
.is(AsmToken::EndOfStatement
) && Name
== "st" &&
1176 Operands
.size() == 2) {
1177 Operands
.erase(Operands
.begin(), Operands
.begin() + 1);
1178 Operands
.insert(Operands
.begin(), LanaiOperand::CreateToken("s", NameLoc
));
1179 Operands
.insert(Operands
.begin() + 1,
1180 LanaiOperand::createImm(
1181 MCConstantExpr::create(LPCC::ICC_T
, getContext()),
1185 // If the instruction is a bt instruction with 1 operand (in assembly) then it
1186 // is an unconditional branch instruction and the first two elements of
1187 // operands need to be merged.
1188 if (Lexer
.is(AsmToken::EndOfStatement
) && Name
.startswith("bt") &&
1189 Operands
.size() == 3) {
1190 Operands
.erase(Operands
.begin(), Operands
.begin() + 2);
1191 Operands
.insert(Operands
.begin(), LanaiOperand::CreateToken("bt", NameLoc
));
1194 // Parse until end of statement, consuming commas between operands
1195 while (Lexer
.isNot(AsmToken::EndOfStatement
) && Lexer
.is(AsmToken::Comma
)) {
1196 // Consume comma token
1199 // Parse next operand
1200 if (parseOperand(&Operands
, Mnemonic
) != MatchOperand_Success
)
1204 if (IsMemoryAssignmentError(Operands
)) {
1205 Error(Parser
.getTok().getLoc(),
1206 "the destination register can't equal the base register in an "
1207 "instruction that modifies the base register.");
1211 // Insert always true operand for instruction that may be predicated but
1212 // are not. Currently the autogenerated parser always expects a predicate.
1213 if (MaybePredicatedInst(Operands
)) {
1214 Operands
.insert(Operands
.begin() + 1,
1215 LanaiOperand::createImm(
1216 MCConstantExpr::create(LPCC::ICC_T
, getContext()),
1223 #define GET_REGISTER_MATCHER
1224 #define GET_MATCHER_IMPLEMENTATION
1225 #include "LanaiGenAsmMatcher.inc"
1227 extern "C" void LLVMInitializeLanaiAsmParser() {
1228 RegisterMCAsmParser
<LanaiAsmParser
> x(getTheLanaiTarget());