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 //===----------------------------------------------------------------------===//
10 #include "LanaiAluCode.h"
11 #include "LanaiCondCode.h"
12 #include "MCTargetDesc/LanaiMCExpr.h"
13 #include "llvm/ADT/STLExtras.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/Support/Casting.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/SMLoc.h"
30 #include "llvm/Support/TargetRegistry.h"
31 #include "llvm/Support/raw_ostream.h"
40 // Auto-generated by TableGen
41 static unsigned MatchRegisterName(StringRef Name
);
47 class LanaiAsmParser
: public MCTargetAsmParser
{
49 std::unique_ptr
<LanaiOperand
> parseRegister();
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 ParseDirective(AsmToken DirectiveID
) override
;
65 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
66 SMLoc NameLoc
, OperandVector
&Operands
) override
;
68 bool ParseRegister(unsigned &RegNum
, SMLoc
&StartLoc
, 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 OperandMatchResultTy
parseOperand(OperandVector
*Operands
,
82 OperandMatchResultTy
parseMemoryOperand(OperandVector
&Operands
);
85 LanaiAsmParser(const MCSubtargetInfo
&STI
, MCAsmParser
&Parser
,
86 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
87 : MCTargetAsmParser(Options
, STI
, MII
), Parser(Parser
),
88 Lexer(Parser
.getLexer()), SubtargetInfo(STI
) {
90 ComputeAvailableFeatures(SubtargetInfo
.getFeatureBits()));
97 const MCSubtargetInfo
&SubtargetInfo
;
100 // LanaiOperand - Instances of this class represented a parsed machine
102 struct LanaiOperand
: public MCParsedAsmOperand
{
112 SMLoc StartLoc
, EndLoc
;
131 const MCExpr
*Offset
;
141 explicit LanaiOperand(KindTy Kind
) : MCParsedAsmOperand(), Kind(Kind
) {}
144 // The functions below are used by the autogenerated ASM matcher and hence to
145 // be of the form expected.
147 // getStartLoc - Gets location of the first token of this operand
148 SMLoc
getStartLoc() const override
{ return StartLoc
; }
150 // getEndLoc - Gets location of the last token of this operand
151 SMLoc
getEndLoc() const override
{ return EndLoc
; }
153 unsigned getReg() const override
{
154 assert(isReg() && "Invalid type access!");
158 const MCExpr
*getImm() const {
159 assert(isImm() && "Invalid type access!");
163 StringRef
getToken() const {
164 assert(isToken() && "Invalid type access!");
165 return StringRef(Tok
.Data
, Tok
.Length
);
168 unsigned getMemBaseReg() const {
169 assert(isMem() && "Invalid type access!");
173 unsigned getMemOffsetReg() const {
174 assert(isMem() && "Invalid type access!");
175 return Mem
.OffsetReg
;
178 const MCExpr
*getMemOffset() const {
179 assert(isMem() && "Invalid type access!");
183 unsigned getMemOp() const {
184 assert(isMem() && "Invalid type access!");
188 // Functions for testing operand type
189 bool isReg() const override
{ return Kind
== REGISTER
; }
191 bool isImm() const override
{ return Kind
== IMMEDIATE
; }
193 bool isMem() const override
{
194 return isMemImm() || isMemRegImm() || isMemRegReg();
197 bool isMemImm() const { return Kind
== MEMORY_IMM
; }
199 bool isMemRegImm() const { return Kind
== MEMORY_REG_IMM
; }
201 bool isMemRegReg() const { return Kind
== MEMORY_REG_REG
; }
203 bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
205 bool isToken() const override
{ return Kind
== TOKEN
; }
212 const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
215 int64_t Value
= MCE
->getValue();
216 // Check if value fits in 25 bits with 2 least significant bits 0.
217 return isShiftedUInt
<23, 2>(static_cast<int32_t>(Value
));
220 bool isBrTarget() { return isBrImm() || isToken(); }
222 bool isCallTarget() { return isImm() || isToken(); }
229 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
230 int64_t Value
= ConstExpr
->getValue();
231 return Value
!= 0 && isShiftedUInt
<16, 16>(Value
);
234 // Symbolic reference expression
235 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
236 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
;
239 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
))
240 if (const LanaiMCExpr
*SymbolRefExpr
=
241 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
242 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
;
247 bool isHiImm16And() {
251 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
253 int64_t Value
= ConstExpr
->getValue();
254 // Check if in the form 0xXYZWffff
255 return (Value
!= 0) && ((Value
& ~0xffff0000) == 0xffff);
265 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
266 int64_t Value
= ConstExpr
->getValue();
267 // Check if value fits in 16 bits
268 return isUInt
<16>(static_cast<int32_t>(Value
));
271 // Symbolic reference expression
272 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
273 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
276 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
))
277 if (const LanaiMCExpr
*SymbolRefExpr
=
278 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
279 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
284 bool isLoImm16Signed() {
289 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
290 int64_t Value
= ConstExpr
->getValue();
291 // Check if value fits in 16 bits or value of the form 0xffffxyzw
292 return isInt
<16>(static_cast<int32_t>(Value
));
295 // Symbolic reference expression
296 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
297 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
300 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
))
301 if (const LanaiMCExpr
*SymbolRefExpr
=
302 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
303 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO
;
308 bool isLoImm16And() {
312 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
314 int64_t Value
= ConstExpr
->getValue();
315 // Check if in the form 0xffffXYZW
316 return ((Value
& ~0xffff) == 0xffff0000);
325 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
328 int64_t Value
= ConstExpr
->getValue();
329 return (Value
>= -31) && (Value
<= 31);
337 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
)) {
338 int64_t Value
= ConstExpr
->getValue();
339 return isUInt
<21>(Value
);
342 // Symbolic reference expression
343 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Imm
.Value
))
344 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
;
345 if (const MCSymbolRefExpr
*SymbolRefExpr
=
346 dyn_cast
<MCSymbolRefExpr
>(Imm
.Value
)) {
347 return SymbolRefExpr
->getKind() == MCSymbolRefExpr::VK_None
;
351 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Imm
.Value
)) {
352 if (const LanaiMCExpr
*SymbolRefExpr
=
353 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS()))
354 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
;
355 if (const MCSymbolRefExpr
*SymbolRefExpr
=
356 dyn_cast
<MCSymbolRefExpr
>(BinaryExpr
->getLHS()))
357 return SymbolRefExpr
->getKind() == MCSymbolRefExpr::VK_None
;
367 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
370 int64_t Value
= ConstExpr
->getValue();
371 return isInt
<10>(Value
);
378 const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Value
);
381 uint64_t Value
= ConstExpr
->getValue();
382 // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
383 // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
384 // value corresponds to a valid condition code.
385 return Value
< LPCC::UNKNOWN
;
388 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
389 // Add as immediates where possible. Null MCExpr = 0
391 Inst
.addOperand(MCOperand::createImm(0));
392 else if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Expr
))
394 MCOperand::createImm(static_cast<int32_t>(ConstExpr
->getValue())));
396 Inst
.addOperand(MCOperand::createExpr(Expr
));
399 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
400 assert(N
== 1 && "Invalid number of operands!");
401 Inst
.addOperand(MCOperand::createReg(getReg()));
404 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
405 assert(N
== 1 && "Invalid number of operands!");
406 addExpr(Inst
, getImm());
409 void addBrTargetOperands(MCInst
&Inst
, unsigned N
) const {
410 assert(N
== 1 && "Invalid number of operands!");
411 addExpr(Inst
, getImm());
414 void addCallTargetOperands(MCInst
&Inst
, unsigned N
) const {
415 assert(N
== 1 && "Invalid number of operands!");
416 addExpr(Inst
, getImm());
419 void addCondCodeOperands(MCInst
&Inst
, unsigned N
) const {
420 assert(N
== 1 && "Invalid number of operands!");
421 addExpr(Inst
, getImm());
424 void addMemImmOperands(MCInst
&Inst
, unsigned N
) const {
425 assert(N
== 1 && "Invalid number of operands!");
426 const MCExpr
*Expr
= getMemOffset();
430 void addMemRegImmOperands(MCInst
&Inst
, unsigned N
) const {
431 assert(N
== 3 && "Invalid number of operands!");
432 Inst
.addOperand(MCOperand::createReg(getMemBaseReg()));
433 const MCExpr
*Expr
= getMemOffset();
435 Inst
.addOperand(MCOperand::createImm(getMemOp()));
438 void addMemRegRegOperands(MCInst
&Inst
, unsigned N
) const {
439 assert(N
== 3 && "Invalid number of operands!");
440 Inst
.addOperand(MCOperand::createReg(getMemBaseReg()));
441 assert(getMemOffsetReg() != 0 && "Invalid offset");
442 Inst
.addOperand(MCOperand::createReg(getMemOffsetReg()));
443 Inst
.addOperand(MCOperand::createImm(getMemOp()));
446 void addMemSplsOperands(MCInst
&Inst
, unsigned N
) const {
448 addMemRegImmOperands(Inst
, N
);
450 addMemRegRegOperands(Inst
, N
);
453 void addImmShiftOperands(MCInst
&Inst
, unsigned N
) const {
454 assert(N
== 1 && "Invalid number of operands!");
455 addExpr(Inst
, getImm());
458 void addImm10Operands(MCInst
&Inst
, unsigned N
) const {
459 assert(N
== 1 && "Invalid number of operands!");
460 addExpr(Inst
, getImm());
463 void addLoImm16Operands(MCInst
&Inst
, unsigned N
) const {
464 assert(N
== 1 && "Invalid number of operands!");
465 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
467 MCOperand::createImm(static_cast<int32_t>(ConstExpr
->getValue())));
468 else if (isa
<LanaiMCExpr
>(getImm())) {
470 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
471 assert(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(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
->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI
);
503 Inst
.addOperand(MCOperand::createExpr(getImm()));
504 } else if (isa
<MCBinaryExpr
>(getImm())) {
506 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
507 assert(isa
<LanaiMCExpr
>(BinaryExpr
->getLHS()) &&
508 cast
<LanaiMCExpr
>(BinaryExpr
->getLHS())->getKind() ==
509 LanaiMCExpr::VK_Lanai_ABS_HI
);
511 Inst
.addOperand(MCOperand::createExpr(getImm()));
513 assert(false && "Operand type not supported.");
516 void addHiImm16AndOperands(MCInst
&Inst
, unsigned N
) const {
517 assert(N
== 1 && "Invalid number of operands!");
518 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
519 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() >> 16));
521 assert(false && "Operand type not supported.");
524 void addLoImm21Operands(MCInst
&Inst
, unsigned N
) const {
525 assert(N
== 1 && "Invalid number of operands!");
526 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(getImm()))
527 Inst
.addOperand(MCOperand::createImm(ConstExpr
->getValue() & 0x1fffff));
528 else if (isa
<LanaiMCExpr
>(getImm())) {
530 const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(getImm());
531 assert(SymbolRefExpr
&&
532 SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
);
534 Inst
.addOperand(MCOperand::createExpr(getImm()));
535 } else if (isa
<MCSymbolRefExpr
>(getImm())) {
537 const MCSymbolRefExpr
*SymbolRefExpr
=
538 dyn_cast
<MCSymbolRefExpr
>(getImm());
539 assert(SymbolRefExpr
&&
540 SymbolRefExpr
->getKind() == MCSymbolRefExpr::VK_None
);
542 Inst
.addOperand(MCOperand::createExpr(getImm()));
543 } else if (isa
<MCBinaryExpr
>(getImm())) {
545 const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(getImm());
546 const LanaiMCExpr
*SymbolRefExpr
=
547 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS());
548 assert(SymbolRefExpr
&&
549 SymbolRefExpr
->getKind() == 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
= 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(unsigned RegNum
, SMLoc Start
,
592 auto Op
= make_unique
<LanaiOperand
>(REGISTER
);
593 Op
->Reg
.RegNum
= RegNum
;
594 Op
->StartLoc
= Start
;
599 static std::unique_ptr
<LanaiOperand
> createImm(const MCExpr
*Value
,
600 SMLoc Start
, SMLoc End
) {
601 auto Op
= 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
;
613 Op
->Mem
.AluOp
= LPAC::ADD
;
614 Op
->Mem
.OffsetReg
= 0;
615 Op
->Mem
.Offset
= Imm
;
619 static std::unique_ptr
<LanaiOperand
>
620 MorphToMemRegReg(unsigned BaseReg
, std::unique_ptr
<LanaiOperand
> Op
,
622 unsigned 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(unsigned 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::ParseDirective(AsmToken
/*DirectiveId*/) { return true; }
648 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc
, unsigned &Opcode
,
649 OperandVector
&Operands
,
652 bool MatchingInlineAsm
) {
656 switch (MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
)) {
658 Out
.EmitInstruction(Inst
, SubtargetInfo
);
659 Opcode
= Inst
.getOpcode();
661 case Match_MissingFeature
:
662 return Error(IdLoc
, "Instruction use requires option to be enabled");
663 case Match_MnemonicFail
:
664 return Error(IdLoc
, "Unrecognized instruction mnemonic");
665 case Match_InvalidOperand
: {
667 if (ErrorInfo
!= ~0U) {
668 if (ErrorInfo
>= Operands
.size())
669 return Error(IdLoc
, "Too few operands for instruction");
671 ErrorLoc
= ((LanaiOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
672 if (ErrorLoc
== SMLoc())
675 return Error(ErrorLoc
, "Invalid operand for instruction");
681 llvm_unreachable("Unknown match type detected!");
684 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
685 // backwards compatible with GCC and the different ways inline assembly is
687 // TODO: see if there isn't a better way to do this.
688 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseRegister() {
689 SMLoc Start
= Parser
.getTok().getLoc();
690 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
694 if (Lexer
.getKind() == AsmToken::Percent
)
696 if (Lexer
.getKind() == AsmToken::Identifier
) {
697 RegNum
= MatchRegisterName(Lexer
.getTok().getIdentifier());
700 Parser
.Lex(); // Eat identifier token
701 return LanaiOperand::createReg(RegNum
, Start
, End
);
706 bool LanaiAsmParser::ParseRegister(unsigned &RegNum
, SMLoc
&StartLoc
,
708 const AsmToken
&Tok
= getParser().getTok();
709 StartLoc
= Tok
.getLoc();
710 EndLoc
= Tok
.getEndLoc();
711 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
713 RegNum
= Op
->getReg();
714 return (Op
== nullptr);
717 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseIdentifier() {
718 SMLoc Start
= Parser
.getTok().getLoc();
719 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
720 const MCExpr
*Res
, *RHS
= nullptr;
721 LanaiMCExpr::VariantKind Kind
= LanaiMCExpr::VK_Lanai_None
;
723 if (Lexer
.getKind() != AsmToken::Identifier
)
726 StringRef Identifier
;
727 if (Parser
.parseIdentifier(Identifier
))
730 // Check if identifier has a modifier
731 if (Identifier
.equals_lower("hi"))
732 Kind
= LanaiMCExpr::VK_Lanai_ABS_HI
;
733 else if (Identifier
.equals_lower("lo"))
734 Kind
= LanaiMCExpr::VK_Lanai_ABS_LO
;
736 // If the identifier corresponds to a variant then extract the real
738 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
739 if (Lexer
.getKind() != AsmToken::LParen
) {
740 Error(Lexer
.getLoc(), "Expected '('");
743 Lexer
.Lex(); // lex '('
746 if (Parser
.parseIdentifier(Identifier
))
750 // If addition parse the RHS.
751 if (Lexer
.getKind() == AsmToken::Plus
&& Parser
.parseExpression(RHS
))
754 // For variants parse the final ')'
755 if (Kind
!= LanaiMCExpr::VK_Lanai_None
) {
756 if (Lexer
.getKind() != AsmToken::RParen
) {
757 Error(Lexer
.getLoc(), "Expected ')'");
760 Lexer
.Lex(); // lex ')'
763 End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
764 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
765 const MCExpr
*Expr
= MCSymbolRefExpr::create(Sym
, getContext());
766 Res
= LanaiMCExpr::create(Kind
, Expr
, getContext());
768 // Nest if this was an addition
770 Res
= MCBinaryExpr::createAdd(Res
, RHS
, getContext());
772 return LanaiOperand::createImm(Res
, Start
, End
);
775 std::unique_ptr
<LanaiOperand
> LanaiAsmParser::parseImmediate() {
776 SMLoc Start
= Parser
.getTok().getLoc();
777 SMLoc End
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
779 const MCExpr
*ExprVal
;
780 switch (Lexer
.getKind()) {
781 case AsmToken::Identifier
:
782 return parseIdentifier();
784 case AsmToken::Minus
:
785 case AsmToken::Integer
:
787 if (!Parser
.parseExpression(ExprVal
))
788 return LanaiOperand::createImm(ExprVal
, Start
, End
);
795 static unsigned AluWithPrePost(unsigned AluCode
, bool PreOp
, bool PostOp
) {
797 return LPAC::makePreOp(AluCode
);
799 return LPAC::makePostOp(AluCode
);
803 unsigned LanaiAsmParser::parseAluOperator(bool PreOp
, bool PostOp
) {
805 Parser
.parseIdentifier(IdString
);
806 unsigned AluCode
= LPAC::stringToLanaiAluCode(IdString
);
807 if (AluCode
== LPAC::UNKNOWN
) {
808 Error(Parser
.getTok().getLoc(), "Can't parse ALU operator");
814 static int SizeForSuffix(StringRef T
) {
815 return StringSwitch
<int>(T
).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
818 bool LanaiAsmParser::parsePrePost(StringRef Type
, int *OffsetValue
) {
819 bool PreOrPost
= false;
820 if (Lexer
.getKind() == Lexer
.peekTok(true).getKind()) {
822 if (Lexer
.is(AsmToken::Minus
))
823 *OffsetValue
= -SizeForSuffix(Type
);
824 else if (Lexer
.is(AsmToken::Plus
))
825 *OffsetValue
= SizeForSuffix(Type
);
829 // Eat the '-' '-' or '+' '+'
832 } else if (Lexer
.is(AsmToken::Star
)) {
833 Parser
.Lex(); // Eat the '*'
840 bool shouldBeSls(const LanaiOperand
&Op
) {
841 // The instruction should be encoded as an SLS if the constant is word
842 // aligned and will fit in 21 bits
843 if (const MCConstantExpr
*ConstExpr
= dyn_cast
<MCConstantExpr
>(Op
.getImm())) {
844 int64_t Value
= ConstExpr
->getValue();
845 return (Value
% 4 == 0) && (Value
>= 0) && (Value
<= 0x1fffff);
847 // The instruction should be encoded as an SLS if the operand is a symbolic
848 // reference with no variant.
849 if (const LanaiMCExpr
*SymbolRefExpr
= dyn_cast
<LanaiMCExpr
>(Op
.getImm()))
850 return SymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
;
851 // The instruction should be encoded as an SLS if the operand is a binary
852 // expression with the left-hand side being a symbolic reference with no
854 if (const MCBinaryExpr
*BinaryExpr
= dyn_cast
<MCBinaryExpr
>(Op
.getImm())) {
855 const LanaiMCExpr
*LHSSymbolRefExpr
=
856 dyn_cast
<LanaiMCExpr
>(BinaryExpr
->getLHS());
857 return (LHSSymbolRefExpr
&&
858 LHSSymbolRefExpr
->getKind() == LanaiMCExpr::VK_Lanai_None
);
863 // Matches memory operand. Returns true if error encountered.
865 LanaiAsmParser::parseMemoryOperand(OperandVector
&Operands
) {
866 // Try to match a memory operand.
867 // The memory operands are of the form:
868 // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
870 // (2) '[' '*'? Register '*'? AluOperator Register ']'
872 // (3) '[' '--'|'++' Register '--'|'++' ']'
874 // (4) '[' Immediate ']' (for SLS)
876 // Store the type for use in parsing pre/post increment/decrement operators
878 if (Operands
[0]->isToken())
879 Type
= static_cast<LanaiOperand
*>(Operands
[0].get())->getToken();
881 // Use 0 if no offset given
883 unsigned BaseReg
= 0;
884 unsigned AluOp
= LPAC::ADD
;
885 bool PostOp
= false, PreOp
= false;
887 // Try to parse the offset
888 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
890 Op
= parseImmediate();
892 // Only continue if next token is '['
893 if (Lexer
.isNot(AsmToken::LBrac
)) {
895 return MatchOperand_NoMatch
;
897 // The start of this custom parsing overlaps with register/immediate so
898 // consider this as a successful match of an operand of that type as the
899 // token stream can't be rewound to allow them to match separately.
900 Operands
.push_back(std::move(Op
));
901 return MatchOperand_Success
;
904 Parser
.Lex(); // Eat the '['.
905 std::unique_ptr
<LanaiOperand
> Offset
= nullptr;
909 // Determine if a pre operation
910 PreOp
= parsePrePost(Type
, &OffsetValue
);
912 Op
= parseRegister();
915 if ((Op
= parseImmediate()) && Lexer
.is(AsmToken::RBrac
)) {
916 Parser
.Lex(); // Eat the ']'
918 // Memory address operations aligned to word boundary are encoded as
919 // SLS, the rest as RM.
920 if (shouldBeSls(*Op
)) {
921 Operands
.push_back(LanaiOperand::MorphToMemImm(std::move(Op
)));
923 if (!Op
->isLoImm16Signed()) {
924 Error(Parser
.getTok().getLoc(),
925 "Memory address is not word "
926 "aligned and larger than class RM can handle");
927 return MatchOperand_ParseFail
;
929 Operands
.push_back(LanaiOperand::MorphToMemRegImm(
930 Lanai::R0
, std::move(Op
), LPAC::ADD
));
932 return MatchOperand_Success
;
936 Error(Parser
.getTok().getLoc(),
937 "Unknown operand, expected register or immediate");
938 return MatchOperand_ParseFail
;
940 BaseReg
= Op
->getReg();
942 // Determine if a post operation
944 PostOp
= parsePrePost(Type
, &OffsetValue
);
946 // If ] match form (1) else match form (2)
947 if (Lexer
.is(AsmToken::RBrac
)) {
948 Parser
.Lex(); // Eat the ']'.
950 SMLoc Start
= Parser
.getTok().getLoc();
952 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
953 const MCConstantExpr
*OffsetConstExpr
=
954 MCConstantExpr::create(OffsetValue
, getContext());
955 Offset
= LanaiOperand::createImm(OffsetConstExpr
, Start
, End
);
958 if (Offset
|| OffsetValue
!= 0) {
959 Error(Parser
.getTok().getLoc(), "Expected ']'");
960 return MatchOperand_ParseFail
;
964 AluOp
= parseAluOperator(PreOp
, PostOp
);
966 // Second form requires offset register
967 Offset
= parseRegister();
968 if (!BaseReg
|| Lexer
.isNot(AsmToken::RBrac
)) {
969 Error(Parser
.getTok().getLoc(), "Expected ']'");
970 return MatchOperand_ParseFail
;
972 Parser
.Lex(); // Eat the ']'.
975 // First form has addition as operator. Add pre- or post-op indicator as
977 AluOp
= AluWithPrePost(AluOp
, PreOp
, PostOp
);
979 // Ensure immediate offset is not too large
980 if (Offset
->isImm() && !Offset
->isLoImm16Signed()) {
981 Error(Parser
.getTok().getLoc(),
982 "Memory address is not word "
983 "aligned and larger than class RM can handle");
984 return MatchOperand_ParseFail
;
989 ? LanaiOperand::MorphToMemRegImm(BaseReg
, std::move(Offset
), AluOp
)
990 : LanaiOperand::MorphToMemRegReg(BaseReg
, std::move(Offset
), AluOp
));
992 return MatchOperand_Success
;
995 // Looks at a token type and creates the relevant operand from this
996 // information, adding to operands.
997 // If operand was parsed, returns false, else true.
999 LanaiAsmParser::parseOperand(OperandVector
*Operands
, StringRef Mnemonic
) {
1000 // Check if the current operand has a custom associated parser, if so, try to
1001 // custom parse the operand, or fallback to the general approach.
1002 OperandMatchResultTy Result
= MatchOperandParserImpl(*Operands
, Mnemonic
);
1004 if (Result
== MatchOperand_Success
)
1006 if (Result
== MatchOperand_ParseFail
) {
1007 Parser
.eatToEndOfStatement();
1011 // Attempt to parse token as register
1012 std::unique_ptr
<LanaiOperand
> Op
= parseRegister();
1014 // Attempt to parse token as immediate
1016 Op
= parseImmediate();
1018 // If the token could not be parsed then fail
1020 Error(Parser
.getTok().getLoc(), "Unknown operand");
1021 Parser
.eatToEndOfStatement();
1022 return MatchOperand_ParseFail
;
1025 // Push back parsed operand into list of operands
1026 Operands
->push_back(std::move(Op
));
1028 return MatchOperand_Success
;
1031 // Split the mnemonic into ASM operand, conditional code and instruction
1032 // qualifier (half-word, byte).
1033 StringRef
LanaiAsmParser::splitMnemonic(StringRef Name
, SMLoc NameLoc
,
1034 OperandVector
*Operands
) {
1035 size_t Next
= Name
.find('.');
1037 StringRef Mnemonic
= Name
;
1040 if (Name
.endswith(".r")) {
1041 Mnemonic
= Name
.substr(0, Name
.size() - 2);
1045 // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1046 if (Mnemonic
[0] == 'b' ||
1047 (Mnemonic
[0] == 's' && !Mnemonic
.startswith("sel") &&
1048 !Mnemonic
.startswith("st"))) {
1049 // Parse instructions with a conditional code. For example, 'bne' is
1050 // converted into two operands 'b' and 'ne'.
1051 LPCC::CondCode CondCode
=
1052 LPCC::suffixToLanaiCondCode(Mnemonic
.substr(1, Next
));
1053 if (CondCode
!= LPCC::UNKNOWN
) {
1054 Mnemonic
= Mnemonic
.slice(0, 1);
1055 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1056 Operands
->push_back(LanaiOperand::createImm(
1057 MCConstantExpr::create(CondCode
, getContext()), NameLoc
, NameLoc
));
1059 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
1065 // Parse other instructions with condition codes (RR instructions).
1066 // We ignore .f here and assume they are flag-setting operations, not
1067 // conditional codes (except for select instructions where flag-setting
1068 // variants are not yet implemented).
1069 if (Mnemonic
.startswith("sel") ||
1070 (!Mnemonic
.endswith(".f") && !Mnemonic
.startswith("st"))) {
1071 LPCC::CondCode CondCode
= LPCC::suffixToLanaiCondCode(Mnemonic
);
1072 if (CondCode
!= LPCC::UNKNOWN
) {
1073 size_t Next
= Mnemonic
.rfind('.', Name
.size());
1074 // 'sel' doesn't use a predicate operand whose printer adds the period,
1075 // but instead has the period as part of the identifier (i.e., 'sel.' is
1076 // expected by the generated matcher). If the mnemonic starts with 'sel'
1077 // then include the period as part of the mnemonic, else don't include it
1078 // as part of the mnemonic.
1079 if (Mnemonic
.startswith("sel")) {
1080 Mnemonic
= Mnemonic
.substr(0, Next
+ 1);
1082 Mnemonic
= Mnemonic
.substr(0, Next
);
1084 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1085 Operands
->push_back(LanaiOperand::createImm(
1086 MCConstantExpr::create(CondCode
, getContext()), NameLoc
, NameLoc
));
1091 Operands
->push_back(LanaiOperand::CreateToken(Mnemonic
, NameLoc
));
1093 Operands
->push_back(LanaiOperand::CreateToken(".r", NameLoc
));
1099 static bool IsMemoryAssignmentError(const OperandVector
&Operands
) {
1100 // Detects if a memory operation has an erroneous base register modification.
1101 // Memory operations are detected by matching the types of operands.
1103 // TODO: This test is focussed on one specific instance (ld/st).
1104 // Extend it to handle more cases or be more robust.
1105 bool Modifies
= false;
1109 if (Operands
.size() < 5)
1111 else if (Operands
[0]->isToken() && Operands
[1]->isReg() &&
1112 Operands
[2]->isImm() && Operands
[3]->isImm() && Operands
[4]->isReg())
1114 else if (Operands
[0]->isToken() && Operands
[1]->isToken() &&
1115 Operands
[2]->isReg() && Operands
[3]->isImm() &&
1116 Operands
[4]->isImm() && Operands
[5]->isReg())
1121 int PossibleAluOpIdx
= Offset
+ 3;
1122 int PossibleBaseIdx
= Offset
+ 1;
1123 int PossibleDestIdx
= Offset
+ 4;
1124 if (LanaiOperand
*PossibleAluOp
=
1125 static_cast<LanaiOperand
*>(Operands
[PossibleAluOpIdx
].get()))
1126 if (PossibleAluOp
->isImm())
1127 if (const MCConstantExpr
*ConstExpr
=
1128 dyn_cast
<MCConstantExpr
>(PossibleAluOp
->getImm()))
1129 Modifies
= LPAC::modifiesOp(ConstExpr
->getValue());
1130 return Modifies
&& Operands
[PossibleBaseIdx
]->isReg() &&
1131 Operands
[PossibleDestIdx
]->isReg() &&
1132 Operands
[PossibleBaseIdx
]->getReg() ==
1133 Operands
[PossibleDestIdx
]->getReg();
1136 static bool IsRegister(const MCParsedAsmOperand
&op
) {
1137 return static_cast<const LanaiOperand
&>(op
).isReg();
1140 static bool MaybePredicatedInst(const OperandVector
&Operands
) {
1141 if (Operands
.size() < 4 || !IsRegister(*Operands
[1]) ||
1142 !IsRegister(*Operands
[2]))
1144 return StringSwitch
<bool>(
1145 static_cast<const LanaiOperand
&>(*Operands
[0]).getToken())
1146 .StartsWith("addc", true)
1147 .StartsWith("add", true)
1148 .StartsWith("and", true)
1149 .StartsWith("sh", true)
1150 .StartsWith("subb", true)
1151 .StartsWith("sub", true)
1152 .StartsWith("or", true)
1153 .StartsWith("xor", true)
1157 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo
& /*Info*/,
1158 StringRef Name
, SMLoc NameLoc
,
1159 OperandVector
&Operands
) {
1160 // First operand is token for instruction
1161 StringRef Mnemonic
= splitMnemonic(Name
, NameLoc
, &Operands
);
1163 // If there are no more operands, then finish
1164 if (Lexer
.is(AsmToken::EndOfStatement
))
1167 // Parse first operand
1168 if (parseOperand(&Operands
, Mnemonic
) != MatchOperand_Success
)
1171 // If it is a st instruction with one 1 operand then it is a "store true".
1172 // Transform <"st"> to <"s">, <LPCC:ICC_T>
1173 if (Lexer
.is(AsmToken::EndOfStatement
) && Name
== "st" &&
1174 Operands
.size() == 2) {
1175 Operands
.erase(Operands
.begin(), Operands
.begin() + 1);
1176 Operands
.insert(Operands
.begin(), LanaiOperand::CreateToken("s", NameLoc
));
1177 Operands
.insert(Operands
.begin() + 1,
1178 LanaiOperand::createImm(
1179 MCConstantExpr::create(LPCC::ICC_T
, getContext()),
1183 // If the instruction is a bt instruction with 1 operand (in assembly) then it
1184 // is an unconditional branch instruction and the first two elements of
1185 // operands need to be merged.
1186 if (Lexer
.is(AsmToken::EndOfStatement
) && Name
.startswith("bt") &&
1187 Operands
.size() == 3) {
1188 Operands
.erase(Operands
.begin(), Operands
.begin() + 2);
1189 Operands
.insert(Operands
.begin(), LanaiOperand::CreateToken("bt", NameLoc
));
1192 // Parse until end of statement, consuming commas between operands
1193 while (Lexer
.isNot(AsmToken::EndOfStatement
) && Lexer
.is(AsmToken::Comma
)) {
1194 // Consume comma token
1197 // Parse next operand
1198 if (parseOperand(&Operands
, Mnemonic
) != MatchOperand_Success
)
1202 if (IsMemoryAssignmentError(Operands
)) {
1203 Error(Parser
.getTok().getLoc(),
1204 "the destination register can't equal the base register in an "
1205 "instruction that modifies the base register.");
1209 // Insert always true operand for instruction that may be predicated but
1210 // are not. Currently the autogenerated parser always expects a predicate.
1211 if (MaybePredicatedInst(Operands
)) {
1212 Operands
.insert(Operands
.begin() + 1,
1213 LanaiOperand::createImm(
1214 MCConstantExpr::create(LPCC::ICC_T
, getContext()),
1221 #define GET_REGISTER_MATCHER
1222 #define GET_MATCHER_IMPLEMENTATION
1223 #include "LanaiGenAsmMatcher.inc"
1225 extern "C" void LLVMInitializeLanaiAsmParser() {
1226 RegisterMCAsmParser
<LanaiAsmParser
> x(getTheLanaiTarget());