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
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
);
474 Inst
.addOperand(MCOperand::createExpr(getImm()));
475 } else if (isa
<MCBinaryExpr
>(getImm())) {
477 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
478 assert(isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
479 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
480 LanaiMCExpr::VK_Lanai_ABS_LO
);
482 Inst
.addOperand(MCOperand::createExpr(getImm()));
484 assert(false && "Operand type not supported.");
487 void addLoImm16AndOperands(MCInst
&Inst
, unsigned N
) const {
488 assert(N
== 1 && "Invalid number of operands!");
489 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
490 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() & 0xffff));
492 assert(false && "Operand type not supported.");
495 void addHiImm16Operands(MCInst
&Inst
, unsigned N
) const {
496 assert(N
== 1 && "Invalid number of operands!");
497 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
498 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() >> 16));
499 else if (isa
<LanaiMCExpr
>(getImm())) {
501 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
502 assert(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(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 const LanaiMCExpr
*SymbolRefExpr
=
548 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS());
549 assert(SymbolRefExpr
&&
550 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
);
552 Inst
.addOperand(MCOperand::createExpr(getImm()));
554 assert(false && "Operand type not supported.");
557 void print(raw_ostream
&OS
) const override
{
560 OS
<< "Imm: " << getImm() << "\n";
563 OS
<< "Token: " << getToken() << "\n";
566 OS
<< "Reg: %r" << getReg() << "\n";
569 OS
<< "MemImm: " << *getMemOffset() << "\n";
572 OS
<< "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
575 assert(getMemOffset() == nullptr);
576 OS
<< "MemRegReg: " << getMemBaseReg() << "+"
577 << "%r" << getMemOffsetReg() << "\n";
582 static std::unique_ptr
<LanaiOperand
> CreateToken(StringRef Str
, SMLoc Start
) {
583 auto Op
= std::make_unique
<LanaiOperand
>(TOKEN
);
584 Op
->Tok
.Data
= Str
.data();
585 Op
->Tok
.Length
= Str
.size();
586 Op
->StartLoc
= Start
;
591 static std::unique_ptr
<LanaiOperand
> createReg(unsigned RegNum
, SMLoc Start
,
593 auto Op
= std::make_unique
<LanaiOperand
>(REGISTER
);
594 Op
->Reg
.RegNum
= RegNum
;
595 Op
->StartLoc
= Start
;
600 static std::unique_ptr
<LanaiOperand
> createImm(const MCExpr
*Value
,
601 SMLoc Start
, SMLoc End
) {
602 auto Op
= std::make_unique
<LanaiOperand
>(IMMEDIATE
);
603 Op
->Imm
.Value
= Value
;
604 Op
->StartLoc
= Start
;
609 static std::unique_ptr
<LanaiOperand
>
610 MorphToMemImm(std::unique_ptr
<LanaiOperand
> Op
) {
611 const MCExpr
*Imm
= Op
->getImm();
612 Op
->Kind
= MEMORY_IMM
;
614 Op
->Mem
.AluOp
= LPAC::ADD
;
615 Op
->Mem
.OffsetReg
= 0;
616 Op
->Mem
.Offset
= Imm
;
620 static std::unique_ptr
<LanaiOperand
>
621 MorphToMemRegReg(unsigned BaseReg
, std::unique_ptr
<LanaiOperand
> Op
,
623 unsigned OffsetReg
= Op
->getReg();
624 Op
->Kind
= MEMORY_REG_REG
;
625 Op
->Mem
.BaseReg
= BaseReg
;
626 Op
->Mem
.AluOp
= AluOp
;
627 Op
->Mem
.OffsetReg
= OffsetReg
;
628 Op
->Mem
.Offset
= nullptr;
632 static std::unique_ptr
<LanaiOperand
>
633 MorphToMemRegImm(unsigned BaseReg
, std::unique_ptr
<LanaiOperand
> Op
,
635 const MCExpr
*Imm
= Op
->getImm();
636 Op
->Kind
= MEMORY_REG_IMM
;
637 Op
->Mem
.BaseReg
= BaseReg
;
638 Op
->Mem
.AluOp
= AluOp
;
639 Op
->Mem
.OffsetReg
= 0;
640 Op
->Mem
.Offset
= Imm
;
645 } // end anonymous namespace
647 bool LanaiAsmParser::ParseDirective(AsmToken
/*DirectiveId*/) { return true; }
649 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc
, unsigned &Opcode
,
650 OperandVector
&Operands
,
653 bool MatchingInlineAsm
) {
657 switch (MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
)) {
659 Out
.EmitInstruction(Inst
, SubtargetInfo
);
660 Opcode
= Inst
.getOpcode();
662 case Match_MissingFeature
:
663 return Error(IdLoc
, "Instruction use requires option to be enabled");
664 case Match_MnemonicFail
:
665 return Error(IdLoc
, "Unrecognized instruction mnemonic");
666 case Match_InvalidOperand
: {
668 if (ErrorInfo
!= ~0U) {
669 if (ErrorInfo
>= Operands
.size())
670 return Error(IdLoc
, "Too few operands for instruction");
672 ErrorLoc
= ((LanaiOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
673 if (ErrorLoc
== SMLoc())
676 return Error(ErrorLoc
, "Invalid operand for instruction");
682 llvm_unreachable("Unknown match type detected!");
685 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
686 // backwards compatible with GCC and the different ways inline assembly is
688 // TODO: see if there isn't a better way to do this.
689 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseRegister() {
690 SMLoc Start
= Parser
.getTok().getLoc();
691 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
695 if (Lexer
.getKind() == AsmToken::Percent
)
697 if (Lexer
.getKind() == AsmToken::Identifier
) {
698 RegNum
= MatchRegisterName(Lexer
.getTok().getIdentifier());
701 Parser
.Lex(); // Eat identifier token
702 return LanaiOperand::createReg(RegNum
, Start
, End
);
707 bool LanaiAsmParser::ParseRegister(unsigned &RegNum
, SMLoc
&StartLoc
,
709 const AsmToken
&Tok
= getParser().getTok();
710 StartLoc
= Tok
.getLoc();
711 EndLoc
= Tok
.getEndLoc();
712 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
714 RegNum
= Op
->getReg();
715 return (Op
== nullptr);
718 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseIdentifier() {
719 SMLoc Start
= Parser
.getTok().getLoc();
720 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
721 const MCExpr
*Res
, *RHS
= nullptr;
722 LanaiMCExpr::VariantKind Kind
= LanaiMCExpr::VK_Lanai_None
;
724 if (Lexer
.getKind() != AsmToken::Identifier
)
727 StringRef Identifier
;
728 if (Parser
.parseIdentifier(Identifier
))
731 // Check if identifier has a modifier
732 if (Identifier
.equals_lower("hi"))
733 Kind
= LanaiMCExpr::VK_Lanai_ABS_HI
;
734 else if (Identifier
.equals_lower("lo"))
735 Kind
= LanaiMCExpr::VK_Lanai_ABS_LO
;
737 // If the identifier corresponds to a variant then extract the real
739 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
740 if (Lexer
.getKind() != AsmToken::LParen
) {
741 Error(Lexer
.getLoc(), "Expected '('");
744 Lexer
.Lex(); // lex '('
747 if (Parser
.parseIdentifier(Identifier
))
751 // If addition parse the RHS.
752 if (Lexer
.getKind() == AsmToken::Plus
&& Parser
.parseExpression(RHS
))
755 // For variants parse the final ')'
756 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
757 if (Lexer
.getKind() != AsmToken::RParen
) {
758 Error(Lexer
.getLoc(), "Expected ')'");
761 Lexer
.Lex(); // lex ')'
764 End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
765 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
766 const MCExpr
*Expr
= MCSymbolRefExpr::create(Sym
, getContext());
767 Res
= LanaiMCExpr::create(Kind
, Expr
, getContext());
769 // Nest if this was an addition
771 Res
= MCBinaryExpr::createAdd(Res
, RHS
, getContext());
773 return LanaiOperand::createImm(Res
, Start
, End
);
776 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseImmediate() {
777 SMLoc Start
= Parser
.getTok().getLoc();
778 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
780 const MCExpr
*ExprVal
;
781 switch (Lexer
.getKind()) {
782 case AsmToken::Identifier
:
783 return parseIdentifier();
785 case AsmToken::Minus
:
786 case AsmToken::Integer
:
788 if (!Parser
.parseExpression(ExprVal
))
789 return LanaiOperand::createImm(ExprVal
, Start
, End
);
796 static unsigned AluWithPrePost(unsigned AluCode
, bool PreOp
, bool PostOp
) {
798 return LPAC::makePreOp(AluCode
);
800 return LPAC::makePostOp(AluCode
);
804 unsigned LanaiAsmParser::parseAluOperator(bool PreOp
, bool PostOp
) {
806 Parser
.parseIdentifier(IdString
);
807 unsigned AluCode
= LPAC::stringToLanaiAluCode(IdString
);
808 if (AluCode
== LPAC::UNKNOWN
) {
809 Error(Parser
.getTok().getLoc(), "Can't parse ALU operator");
815 static int SizeForSuffix(StringRef T
) {
816 return StringSwitch
<int>(T
).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
819 bool LanaiAsmParser::parsePrePost(StringRef Type
, int *OffsetValue
) {
820 bool PreOrPost
= false;
821 if (Lexer
.getKind() == Lexer
.peekTok(true).getKind()) {
823 if (Lexer
.is(AsmToken::Minus
))
824 *OffsetValue
= -SizeForSuffix(Type
);
825 else if (Lexer
.is(AsmToken::Plus
))
826 *OffsetValue
= SizeForSuffix(Type
);
830 // Eat the '-' '-' or '+' '+'
833 } else if (Lexer
.is(AsmToken::Star
)) {
834 Parser
.Lex(); // Eat the '*'
841 bool shouldBeSls(const LanaiOperand
&Op
) {
842 // The instruction should be encoded as an SLS if the constant is word
843 // aligned and will fit in 21 bits
844 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Op
.getImm())) {
845 int64_t Value
= ConstExpr
->getValue();
846 return (Value
% 4 == 0) && (Value
>= 0) && (Value
<= 0x1fffff);
848 // The instruction should be encoded as an SLS if the operand is a symbolic
849 // reference with no variant.
850 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Op
.getImm()))
851 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
;
852 // The instruction should be encoded as an SLS if the operand is a binary
853 // expression with the left-hand side being a symbolic reference with no
855 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Op
.getImm())) {
856 const LanaiMCExpr
*LHSSymbolRefExpr
=
857 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS());
858 return (LHSSymbolRefExpr
&&
859 LHSSymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
);
864 // Matches memory operand. Returns true if error encountered.
866 LanaiAsmParser::parseMemoryOperand(OperandVector
&Operands
) {
867 // Try to match a memory operand.
868 // The memory operands are of the form:
869 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
871 // (2) '[' '*'? Register '*'? AluOperator Register ']'
873 // (3) '[' '--'|'++' Register '--'|'++' ']'
875 // (4) '[' Immediate ']' (for SLS)
877 // Store the type for use in parsing pre/post increment/decrement operators
879 if (Operands
[0]->isToken())
880 Type
= static_cast<LanaiOperand
*>(Operands
[0].get())->getToken();
882 // Use 0 if no offset given
884 unsigned BaseReg
= 0;
885 unsigned AluOp
= LPAC::ADD
;
886 bool PostOp
= false, PreOp
= false;
888 // Try to parse the offset
889 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
891 Op
= parseImmediate();
893 // Only continue if next token is '['
894 if (Lexer
.isNot(AsmToken::LBrac
)) {
896 return MatchOperand_NoMatch
;
898 // The start of this custom parsing overlaps with register/immediate so
899 // consider this as a successful match of an operand of that type as the
900 // token stream can't be rewound to allow them to match separately.
901 Operands
.push_back(std::move(Op
));
902 return MatchOperand_Success
;
905 Parser
.Lex(); // Eat the '['.
906 std::unique_ptr
<LanaiOperand
> Offset
= nullptr;
910 // Determine if a pre operation
911 PreOp
= parsePrePost(Type
, &OffsetValue
);
913 Op
= parseRegister();
916 if ((Op
= parseImmediate()) && Lexer
.is(AsmToken::RBrac
)) {
917 Parser
.Lex(); // Eat the ']'
919 // Memory address operations aligned to word boundary are encoded as
920 // SLS, the rest as RM.
921 if (shouldBeSls(*Op
)) {
922 Operands
.push_back(LanaiOperand::MorphToMemImm(std::move(Op
)));
924 if (!Op
->isLoImm16Signed()) {
925 Error(Parser
.getTok().getLoc(),
926 "Memory address is not word "
927 "aligned and larger than class RM can handle");
928 return MatchOperand_ParseFail
;
930 Operands
.push_back(LanaiOperand::MorphToMemRegImm(
931 Lanai::R0
, std::move(Op
), LPAC::ADD
));
933 return MatchOperand_Success
;
937 Error(Parser
.getTok().getLoc(),
938 "Unknown operand, expected register or immediate");
939 return MatchOperand_ParseFail
;
941 BaseReg
= Op
->getReg();
943 // Determine if a post operation
945 PostOp
= parsePrePost(Type
, &OffsetValue
);
947 // If ] match form (1) else match form (2)
948 if (Lexer
.is(AsmToken::RBrac
)) {
949 Parser
.Lex(); // Eat the ']'.
951 SMLoc Start
= Parser
.getTok().getLoc();
953 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
954 const MCConstantExpr
*OffsetConstExpr
=
955 MCConstantExpr::create(OffsetValue
, getContext());
956 Offset
= LanaiOperand::createImm(OffsetConstExpr
, Start
, End
);
959 if (Offset
|| OffsetValue
!= 0) {
960 Error(Parser
.getTok().getLoc(), "Expected ']'");
961 return MatchOperand_ParseFail
;
965 AluOp
= parseAluOperator(PreOp
, PostOp
);
967 // Second form requires offset register
968 Offset
= parseRegister();
969 if (!BaseReg
|| Lexer
.isNot(AsmToken::RBrac
)) {
970 Error(Parser
.getTok().getLoc(), "Expected ']'");
971 return MatchOperand_ParseFail
;
973 Parser
.Lex(); // Eat the ']'.
976 // First form has addition as operator. Add pre- or post-op indicator as
978 AluOp
= AluWithPrePost(AluOp
, PreOp
, PostOp
);
980 // Ensure immediate offset is not too large
981 if (Offset
->isImm() && !Offset
->isLoImm16Signed()) {
982 Error(Parser
.getTok().getLoc(),
983 "Memory address is not word "
984 "aligned and larger than class RM can handle");
985 return MatchOperand_ParseFail
;
990 ? LanaiOperand::MorphToMemRegImm(BaseReg
, std::move(Offset
), AluOp
)
991 : LanaiOperand::MorphToMemRegReg(BaseReg
, std::move(Offset
), AluOp
));
993 return MatchOperand_Success
;
996 // Looks at a token type and creates the relevant operand from this
997 // information, adding to operands.
998 // If operand was parsed, returns false, else true.
1000 LanaiAsmParser::parseOperand(OperandVector
*Operands
, StringRef Mnemonic
) {
1001 // Check if the current operand has a custom associated parser, if so, try to
1002 // custom parse the operand, or fallback to the general approach.
1003 OperandMatchResultTy Result
= MatchOperandParserImpl(*Operands
, Mnemonic
);
1005 if (Result
== MatchOperand_Success
)
1007 if (Result
== MatchOperand_ParseFail
) {
1008 Parser
.eatToEndOfStatement();
1012 // Attempt to parse token as register
1013 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
1015 // Attempt to parse token as immediate
1017 Op
= parseImmediate();
1019 // If the token could not be parsed then fail
1021 Error(Parser
.getTok().getLoc(), "Unknown operand");
1022 Parser
.eatToEndOfStatement();
1023 return MatchOperand_ParseFail
;
1026 // Push back parsed operand into list of operands
1027 Operands
->push_back(std::move(Op
));
1029 return MatchOperand_Success
;
1032 // Split the mnemonic into ASM operand, conditional code and instruction
1033 // qualifier (half-word, byte).
1034 StringRef
LanaiAsmParser::splitMnemonic(StringRef Name
, SMLoc NameLoc
,
1035 OperandVector
*Operands
) {
1036 size_t Next
= Name
.find('.');
1038 StringRef Mnemonic
= Name
;
1041 if (Name
.endswith(".r")) {
1042 Mnemonic
= Name
.substr(0, Name
.size() - 2);
1046 // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1047 if (Mnemonic
[0] == 'b' ||
1048 (Mnemonic
[0] == 's' && !Mnemonic
.startswith("sel") &&
1049 !Mnemonic
.startswith("st"))) {
1050 // Parse instructions with a conditional code. For example, 'bne' is
1051 // converted into two operands 'b' and 'ne'.
1052 LPCC::CondCode CondCode
=
1053 LPCC::suffixToLanaiCondCode(Mnemonic
.substr(1, Next
));
1054 if (CondCode
!= LPCC::UNKNOWN
) {
1055 Mnemonic
= Mnemonic
.slice(0, 1);
1056 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1057 Operands
->push_back(LanaiOperand::createImm(
1058 MCConstantExpr::create(CondCode
, getContext()), NameLoc
, NameLoc
));
1060 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
1066 // Parse other instructions with condition codes (RR instructions).
1067 // We ignore .f here and assume they are flag-setting operations, not
1068 // conditional codes (except for select instructions where flag-setting
1069 // variants are not yet implemented).
1070 if (Mnemonic
.startswith("sel") ||
1071 (!Mnemonic
.endswith(".f") && !Mnemonic
.startswith("st"))) {
1072 LPCC::CondCode CondCode
= LPCC::suffixToLanaiCondCode(Mnemonic
);
1073 if (CondCode
!= LPCC::UNKNOWN
) {
1074 size_t Next
= Mnemonic
.rfind('.', Name
.size());
1075 // 'sel' doesn't use a predicate operand whose printer adds the period,
1076 // but instead has the period as part of the identifier (i.e., 'sel.' is
1077 // expected by the generated matcher). If the mnemonic starts with 'sel'
1078 // then include the period as part of the mnemonic, else don't include it
1079 // as part of the mnemonic.
1080 if (Mnemonic
.startswith("sel")) {
1081 Mnemonic
= Mnemonic
.substr(0, Next
+ 1);
1083 Mnemonic
= Mnemonic
.substr(0, Next
);
1085 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1086 Operands
->push_back(LanaiOperand::createImm(
1087 MCConstantExpr::create(CondCode
, getContext()), NameLoc
, NameLoc
));
1092 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1094 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
1100 static bool IsMemoryAssignmentError(const OperandVector
&Operands
) {
1101 // Detects if a memory operation has an erroneous base register modification.
1102 // Memory operations are detected by matching the types of operands.
1104 // TODO: This test is focussed on one specific instance (ld/st).
1105 // Extend it to handle more cases or be more robust.
1106 bool Modifies
= false;
1110 if (Operands
.size() < 5)
1112 else if (Operands
[0]->isToken() && Operands
[1]->isReg() &&
1113 Operands
[2]->isImm() && Operands
[3]->isImm() && Operands
[4]->isReg())
1115 else if (Operands
[0]->isToken() && Operands
[1]->isToken() &&
1116 Operands
[2]->isReg() && Operands
[3]->isImm() &&
1117 Operands
[4]->isImm() && Operands
[5]->isReg())
1122 int PossibleAluOpIdx
= Offset
+ 3;
1123 int PossibleBaseIdx
= Offset
+ 1;
1124 int PossibleDestIdx
= Offset
+ 4;
1125 if (LanaiOperand
*PossibleAluOp
=
1126 static_cast<LanaiOperand
*>(Operands
[PossibleAluOpIdx
].get()))
1127 if (PossibleAluOp
->isImm())
1128 if (const MCConstantExpr
*ConstExpr
=
1129 dyn_cast
<MCConstantExpr
>(PossibleAluOp
->getImm()))
1130 Modifies
= LPAC::modifiesOp(ConstExpr
->getValue());
1131 return Modifies
&& Operands
[PossibleBaseIdx
]->isReg() &&
1132 Operands
[PossibleDestIdx
]->isReg() &&
1133 Operands
[PossibleBaseIdx
]->getReg() ==
1134 Operands
[PossibleDestIdx
]->getReg();
1137 static bool IsRegister(const MCParsedAsmOperand
&op
) {
1138 return static_cast<const LanaiOperand
&>(op
).isReg();
1141 static bool MaybePredicatedInst(const OperandVector
&Operands
) {
1142 if (Operands
.size() < 4 || !IsRegister(*Operands
[1]) ||
1143 !IsRegister(*Operands
[2]))
1145 return StringSwitch
<bool>(
1146 static_cast<const LanaiOperand
&>(*Operands
[0]).getToken())
1147 .StartsWith("addc", true)
1148 .StartsWith("add", true)
1149 .StartsWith("and", true)
1150 .StartsWith("sh", true)
1151 .StartsWith("subb", true)
1152 .StartsWith("sub", true)
1153 .StartsWith("or", true)
1154 .StartsWith("xor", true)
1158 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo
& /*Info*/,
1159 StringRef Name
, SMLoc NameLoc
,
1160 OperandVector
&Operands
) {
1161 // First operand is token for instruction
1162 StringRef Mnemonic
= splitMnemonic(Name
, NameLoc
, &Operands
);
1164 // If there are no more operands, then finish
1165 if (Lexer
.is(AsmToken::EndOfStatement
))
1168 // Parse first operand
1169 if (parseOperand(&Operands
, Mnemonic
) != MatchOperand_Success
)
1172 // If it is a st instruction with one 1 operand then it is a "store true".
1173 // Transform <"st"> to <"s">, <LPCC:ICC_T>
1174 if (Lexer
.is(AsmToken::EndOfStatement
) && Name
== "st" &&
1175 Operands
.size() == 2) {
1176 Operands
.erase(Operands
.begin(), Operands
.begin() + 1);
1177 Operands
.insert(Operands
.begin(), LanaiOperand::CreateToken("s", NameLoc
));
1178 Operands
.insert(Operands
.begin() + 1,
1179 LanaiOperand::createImm(
1180 MCConstantExpr::create(LPCC::ICC_T
, getContext()),
1184 // If the instruction is a bt instruction with 1 operand (in assembly) then it
1185 // is an unconditional branch instruction and the first two elements of
1186 // operands need to be merged.
1187 if (Lexer
.is(AsmToken::EndOfStatement
) && Name
.startswith("bt") &&
1188 Operands
.size() == 3) {
1189 Operands
.erase(Operands
.begin(), Operands
.begin() + 2);
1190 Operands
.insert(Operands
.begin(), LanaiOperand::CreateToken("bt", NameLoc
));
1193 // Parse until end of statement, consuming commas between operands
1194 while (Lexer
.isNot(AsmToken::EndOfStatement
) && Lexer
.is(AsmToken::Comma
)) {
1195 // Consume comma token
1198 // Parse next operand
1199 if (parseOperand(&Operands
, Mnemonic
) != MatchOperand_Success
)
1203 if (IsMemoryAssignmentError(Operands
)) {
1204 Error(Parser
.getTok().getLoc(),
1205 "the destination register can't equal the base register in an "
1206 "instruction that modifies the base register.");
1210 // Insert always true operand for instruction that may be predicated but
1211 // are not. Currently the autogenerated parser always expects a predicate.
1212 if (MaybePredicatedInst(Operands
)) {
1213 Operands
.insert(Operands
.begin() + 1,
1214 LanaiOperand::createImm(
1215 MCConstantExpr::create(LPCC::ICC_T
, getContext()),
1222 #define GET_REGISTER_MATCHER
1223 #define GET_MATCHER_IMPLEMENTATION
1224 #include "LanaiGenAsmMatcher.inc"
1226 extern "C" void LLVMInitializeLanaiAsmParser() {
1227 RegisterMCAsmParser
<LanaiAsmParser
> x(getTheLanaiTarget());