1 //===-- VEAsmParser.cpp - Parse VE 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 "MCTargetDesc/VEMCExpr.h"
10 #include "MCTargetDesc/VEMCTargetDesc.h"
11 #include "TargetInfo/VETargetInfo.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCAsmParser.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/TargetRegistry.h"
30 #include "llvm/Support/raw_ostream.h"
36 #define DEBUG_TYPE "ve-asmparser"
42 class VEAsmParser
: public MCTargetAsmParser
{
45 /// @name Auto-generated Match Functions
48 #define GET_ASSEMBLER_HEADER
49 #include "VEGenAsmMatcher.inc"
53 // public interface of the MCTargetAsmParser.
54 bool MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
55 OperandVector
&Operands
, MCStreamer
&Out
,
57 bool MatchingInlineAsm
) override
;
58 bool parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
59 int parseRegisterName(unsigned (*matchFn
)(StringRef
));
60 ParseStatus
tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
61 SMLoc
&EndLoc
) override
;
62 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
63 SMLoc NameLoc
, OperandVector
&Operands
) override
;
64 ParseStatus
parseDirective(AsmToken DirectiveID
) override
;
66 unsigned validateTargetOperandClass(MCParsedAsmOperand
&Op
,
67 unsigned Kind
) override
;
69 // Custom parse functions for VE specific operands.
70 ParseStatus
parseMEMOperand(OperandVector
&Operands
);
71 ParseStatus
parseMEMAsOperand(OperandVector
&Operands
);
72 ParseStatus
parseCCOpOperand(OperandVector
&Operands
);
73 ParseStatus
parseRDOpOperand(OperandVector
&Operands
);
74 ParseStatus
parseMImmOperand(OperandVector
&Operands
);
75 ParseStatus
parseOperand(OperandVector
&Operands
, StringRef Name
);
76 ParseStatus
parseVEAsmOperand(std::unique_ptr
<VEOperand
> &Operand
);
78 // Helper function to parse expression with a symbol.
79 const MCExpr
*extractModifierFromExpr(const MCExpr
*E
,
80 VEMCExpr::VariantKind
&Variant
);
81 const MCExpr
*fixupVariantKind(const MCExpr
*E
);
82 bool parseExpression(const MCExpr
*&EVal
);
84 // Split the mnemonic stripping conditional code and quantifiers
85 StringRef
splitMnemonic(StringRef Name
, SMLoc NameLoc
,
86 OperandVector
*Operands
);
88 bool parseLiteralValues(unsigned Size
, SMLoc L
);
91 VEAsmParser(const MCSubtargetInfo
&sti
, MCAsmParser
&parser
,
92 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
93 : MCTargetAsmParser(Options
, sti
, MII
), Parser(parser
) {
94 // Initialize the set of available features.
95 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
99 } // end anonymous namespace
101 static const MCPhysReg I32Regs
[64] = {
102 VE::SW0
, VE::SW1
, VE::SW2
, VE::SW3
, VE::SW4
, VE::SW5
, VE::SW6
,
103 VE::SW7
, VE::SW8
, VE::SW9
, VE::SW10
, VE::SW11
, VE::SW12
, VE::SW13
,
104 VE::SW14
, VE::SW15
, VE::SW16
, VE::SW17
, VE::SW18
, VE::SW19
, VE::SW20
,
105 VE::SW21
, VE::SW22
, VE::SW23
, VE::SW24
, VE::SW25
, VE::SW26
, VE::SW27
,
106 VE::SW28
, VE::SW29
, VE::SW30
, VE::SW31
, VE::SW32
, VE::SW33
, VE::SW34
,
107 VE::SW35
, VE::SW36
, VE::SW37
, VE::SW38
, VE::SW39
, VE::SW40
, VE::SW41
,
108 VE::SW42
, VE::SW43
, VE::SW44
, VE::SW45
, VE::SW46
, VE::SW47
, VE::SW48
,
109 VE::SW49
, VE::SW50
, VE::SW51
, VE::SW52
, VE::SW53
, VE::SW54
, VE::SW55
,
110 VE::SW56
, VE::SW57
, VE::SW58
, VE::SW59
, VE::SW60
, VE::SW61
, VE::SW62
,
113 static const MCPhysReg F32Regs
[64] = {
114 VE::SF0
, VE::SF1
, VE::SF2
, VE::SF3
, VE::SF4
, VE::SF5
, VE::SF6
,
115 VE::SF7
, VE::SF8
, VE::SF9
, VE::SF10
, VE::SF11
, VE::SF12
, VE::SF13
,
116 VE::SF14
, VE::SF15
, VE::SF16
, VE::SF17
, VE::SF18
, VE::SF19
, VE::SF20
,
117 VE::SF21
, VE::SF22
, VE::SF23
, VE::SF24
, VE::SF25
, VE::SF26
, VE::SF27
,
118 VE::SF28
, VE::SF29
, VE::SF30
, VE::SF31
, VE::SF32
, VE::SF33
, VE::SF34
,
119 VE::SF35
, VE::SF36
, VE::SF37
, VE::SF38
, VE::SF39
, VE::SF40
, VE::SF41
,
120 VE::SF42
, VE::SF43
, VE::SF44
, VE::SF45
, VE::SF46
, VE::SF47
, VE::SF48
,
121 VE::SF49
, VE::SF50
, VE::SF51
, VE::SF52
, VE::SF53
, VE::SF54
, VE::SF55
,
122 VE::SF56
, VE::SF57
, VE::SF58
, VE::SF59
, VE::SF60
, VE::SF61
, VE::SF62
,
125 static const MCPhysReg F128Regs
[32] = {
126 VE::Q0
, VE::Q1
, VE::Q2
, VE::Q3
, VE::Q4
, VE::Q5
, VE::Q6
, VE::Q7
,
127 VE::Q8
, VE::Q9
, VE::Q10
, VE::Q11
, VE::Q12
, VE::Q13
, VE::Q14
, VE::Q15
,
128 VE::Q16
, VE::Q17
, VE::Q18
, VE::Q19
, VE::Q20
, VE::Q21
, VE::Q22
, VE::Q23
,
129 VE::Q24
, VE::Q25
, VE::Q26
, VE::Q27
, VE::Q28
, VE::Q29
, VE::Q30
, VE::Q31
};
131 static const MCPhysReg VM512Regs
[8] = {VE::VMP0
, VE::VMP1
, VE::VMP2
, VE::VMP3
,
132 VE::VMP4
, VE::VMP5
, VE::VMP6
, VE::VMP7
};
134 static const MCPhysReg MISCRegs
[31] = {
135 VE::USRCC
, VE::PSW
, VE::SAR
, VE::NoRegister
,
136 VE::NoRegister
, VE::NoRegister
, VE::NoRegister
, VE::PMMR
,
137 VE::PMCR0
, VE::PMCR1
, VE::PMCR2
, VE::PMCR3
,
138 VE::NoRegister
, VE::NoRegister
, VE::NoRegister
, VE::NoRegister
,
139 VE::PMC0
, VE::PMC1
, VE::PMC2
, VE::PMC3
,
140 VE::PMC4
, VE::PMC5
, VE::PMC6
, VE::PMC7
,
141 VE::PMC8
, VE::PMC9
, VE::PMC10
, VE::PMC11
,
142 VE::PMC12
, VE::PMC13
, VE::PMC14
};
146 /// VEOperand - Instances of this class represent a parsed VE machine
148 class VEOperand
: public MCParsedAsmOperand
{
154 // SX-Aurora ASX form is disp(index, base).
155 k_MemoryRegRegImm
, // base=reg, index=reg, disp=imm
156 k_MemoryRegImmImm
, // base=reg, index=imm, disp=imm
157 k_MemoryZeroRegImm
, // base=0, index=reg, disp=imm
158 k_MemoryZeroImmImm
, // base=0, index=imm, disp=imm
159 // SX-Aurora AS form is disp(base).
160 k_MemoryRegImm
, // base=reg, disp=imm
161 k_MemoryZeroImm
, // base=0, disp=imm
162 // Other special cases for Aurora VE
163 k_CCOp
, // condition code
164 k_RDOp
, // rounding mode
165 k_MImmOp
, // Special immediate value of sequential bit stream of 0 or 1.
168 SMLoc StartLoc
, EndLoc
;
187 const MCExpr
*Offset
;
214 VEOperand(KindTy K
) : Kind(K
) {}
216 bool isToken() const override
{ return Kind
== k_Token
; }
217 bool isReg() const override
{ return Kind
== k_Register
; }
218 bool isImm() const override
{ return Kind
== k_Immediate
; }
219 bool isMem() const override
{
220 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
223 bool isMEMrri() const { return Kind
== k_MemoryRegRegImm
; }
224 bool isMEMrii() const { return Kind
== k_MemoryRegImmImm
; }
225 bool isMEMzri() const { return Kind
== k_MemoryZeroRegImm
; }
226 bool isMEMzii() const { return Kind
== k_MemoryZeroImmImm
; }
227 bool isMEMri() const { return Kind
== k_MemoryRegImm
; }
228 bool isMEMzi() const { return Kind
== k_MemoryZeroImm
; }
229 bool isCCOp() const { return Kind
== k_CCOp
; }
230 bool isRDOp() const { return Kind
== k_RDOp
; }
236 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
237 int64_t Value
= ConstExpr
->getValue();
247 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
248 int64_t Value
= ConstExpr
->getValue();
249 return Value
>= 0 && Value
< 3;
258 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
259 int64_t Value
= ConstExpr
->getValue();
260 return isUInt
<1>(Value
);
269 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
270 int64_t Value
= ConstExpr
->getValue();
271 return isUInt
<2>(Value
);
280 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
281 int64_t Value
= ConstExpr
->getValue();
282 return isUInt
<3>(Value
);
291 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
292 int64_t Value
= ConstExpr
->getValue();
293 return isUInt
<4>(Value
);
302 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
303 int64_t Value
= ConstExpr
->getValue();
304 return isUInt
<6>(Value
);
313 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
314 int64_t Value
= ConstExpr
->getValue();
315 return isUInt
<7>(Value
);
324 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Imm
.Val
)) {
325 int64_t Value
= ConstExpr
->getValue();
326 return isInt
<7>(Value
);
330 bool isMImm() const {
331 if (Kind
!= k_MImmOp
)
335 if (const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(MImm
.Val
)) {
336 int64_t Value
= ConstExpr
->getValue();
337 return isUInt
<6>(Value
);
342 StringRef
getToken() const {
343 assert(Kind
== k_Token
&& "Invalid access!");
344 return StringRef(Tok
.Data
, Tok
.Length
);
347 unsigned getReg() const override
{
348 assert((Kind
== k_Register
) && "Invalid access!");
352 const MCExpr
*getImm() const {
353 assert((Kind
== k_Immediate
) && "Invalid access!");
357 unsigned getMemBase() const {
358 assert((Kind
== k_MemoryRegRegImm
|| Kind
== k_MemoryRegImmImm
||
359 Kind
== k_MemoryRegImm
) &&
364 unsigned getMemIndexReg() const {
365 assert((Kind
== k_MemoryRegRegImm
|| Kind
== k_MemoryZeroRegImm
) &&
370 const MCExpr
*getMemIndex() const {
371 assert((Kind
== k_MemoryRegImmImm
|| Kind
== k_MemoryZeroImmImm
) &&
376 const MCExpr
*getMemOffset() const {
377 assert((Kind
== k_MemoryRegRegImm
|| Kind
== k_MemoryRegImmImm
||
378 Kind
== k_MemoryZeroImmImm
|| Kind
== k_MemoryZeroRegImm
||
379 Kind
== k_MemoryRegImm
|| Kind
== k_MemoryZeroImm
) &&
384 void setMemOffset(const MCExpr
*off
) {
385 assert((Kind
== k_MemoryRegRegImm
|| Kind
== k_MemoryRegImmImm
||
386 Kind
== k_MemoryZeroImmImm
|| Kind
== k_MemoryZeroRegImm
||
387 Kind
== k_MemoryRegImm
|| Kind
== k_MemoryZeroImm
) &&
392 unsigned getCCVal() const {
393 assert((Kind
== k_CCOp
) && "Invalid access!");
397 unsigned getRDVal() const {
398 assert((Kind
== k_RDOp
) && "Invalid access!");
402 const MCExpr
*getMImmVal() const {
403 assert((Kind
== k_MImmOp
) && "Invalid access!");
406 bool getM0Flag() const {
407 assert((Kind
== k_MImmOp
) && "Invalid access!");
411 /// getStartLoc - Get the location of the first token of this operand.
412 SMLoc
getStartLoc() const override
{ return StartLoc
; }
413 /// getEndLoc - Get the location of the last token of this operand.
414 SMLoc
getEndLoc() const override
{ return EndLoc
; }
416 void print(raw_ostream
&OS
) const override
{
419 OS
<< "Token: " << getToken() << "\n";
422 OS
<< "Reg: #" << getReg() << "\n";
425 OS
<< "Imm: " << getImm() << "\n";
427 case k_MemoryRegRegImm
:
428 assert(getMemOffset() != nullptr);
429 OS
<< "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+"
430 << *getMemOffset() << "\n";
432 case k_MemoryRegImmImm
:
433 assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
434 OS
<< "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+"
435 << *getMemOffset() << "\n";
437 case k_MemoryZeroRegImm
:
438 assert(getMemOffset() != nullptr);
439 OS
<< "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n";
441 case k_MemoryZeroImmImm
:
442 assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
443 OS
<< "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n";
446 assert(getMemOffset() != nullptr);
447 OS
<< "Mem: #" << getMemBase() << "+" << *getMemOffset() << "\n";
449 case k_MemoryZeroImm
:
450 assert(getMemOffset() != nullptr);
451 OS
<< "Mem: 0+" << *getMemOffset() << "\n";
454 OS
<< "CCOp: " << getCCVal() << "\n";
457 OS
<< "RDOp: " << getRDVal() << "\n";
460 OS
<< "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n";
465 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
466 assert(N
== 1 && "Invalid number of operands!");
467 Inst
.addOperand(MCOperand::createReg(getReg()));
470 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
471 assert(N
== 1 && "Invalid number of operands!");
472 const MCExpr
*Expr
= getImm();
476 void addZeroOperands(MCInst
&Inst
, unsigned N
) const {
477 addImmOperands(Inst
, N
);
480 void addUImm0to2Operands(MCInst
&Inst
, unsigned N
) const {
481 addImmOperands(Inst
, N
);
484 void addUImm1Operands(MCInst
&Inst
, unsigned N
) const {
485 addImmOperands(Inst
, N
);
488 void addUImm2Operands(MCInst
&Inst
, unsigned N
) const {
489 addImmOperands(Inst
, N
);
492 void addUImm3Operands(MCInst
&Inst
, unsigned N
) const {
493 addImmOperands(Inst
, N
);
496 void addUImm4Operands(MCInst
&Inst
, unsigned N
) const {
497 addImmOperands(Inst
, N
);
500 void addUImm6Operands(MCInst
&Inst
, unsigned N
) const {
501 addImmOperands(Inst
, N
);
504 void addUImm7Operands(MCInst
&Inst
, unsigned N
) const {
505 addImmOperands(Inst
, N
);
508 void addSImm7Operands(MCInst
&Inst
, unsigned N
) const {
509 addImmOperands(Inst
, N
);
512 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
513 // Add as immediate when possible. Null MCExpr = 0.
515 Inst
.addOperand(MCOperand::createImm(0));
516 else if (const auto *CE
= dyn_cast
<MCConstantExpr
>(Expr
))
517 Inst
.addOperand(MCOperand::createImm(CE
->getValue()));
519 Inst
.addOperand(MCOperand::createExpr(Expr
));
522 void addMEMrriOperands(MCInst
&Inst
, unsigned N
) const {
523 assert(N
== 3 && "Invalid number of operands!");
525 Inst
.addOperand(MCOperand::createReg(getMemBase()));
526 Inst
.addOperand(MCOperand::createReg(getMemIndexReg()));
527 addExpr(Inst
, getMemOffset());
530 void addMEMriiOperands(MCInst
&Inst
, unsigned N
) const {
531 assert(N
== 3 && "Invalid number of operands!");
533 Inst
.addOperand(MCOperand::createReg(getMemBase()));
534 addExpr(Inst
, getMemIndex());
535 addExpr(Inst
, getMemOffset());
538 void addMEMzriOperands(MCInst
&Inst
, unsigned N
) const {
539 assert(N
== 3 && "Invalid number of operands!");
541 Inst
.addOperand(MCOperand::createImm(0));
542 Inst
.addOperand(MCOperand::createReg(getMemIndexReg()));
543 addExpr(Inst
, getMemOffset());
546 void addMEMziiOperands(MCInst
&Inst
, unsigned N
) const {
547 assert(N
== 3 && "Invalid number of operands!");
549 Inst
.addOperand(MCOperand::createImm(0));
550 addExpr(Inst
, getMemIndex());
551 addExpr(Inst
, getMemOffset());
554 void addMEMriOperands(MCInst
&Inst
, unsigned N
) const {
555 assert(N
== 2 && "Invalid number of operands!");
557 Inst
.addOperand(MCOperand::createReg(getMemBase()));
558 addExpr(Inst
, getMemOffset());
561 void addMEMziOperands(MCInst
&Inst
, unsigned N
) const {
562 assert(N
== 2 && "Invalid number of operands!");
564 Inst
.addOperand(MCOperand::createImm(0));
565 addExpr(Inst
, getMemOffset());
568 void addCCOpOperands(MCInst
&Inst
, unsigned N
) const {
569 assert(N
== 1 && "Invalid number of operands!");
571 Inst
.addOperand(MCOperand::createImm(getCCVal()));
574 void addRDOpOperands(MCInst
&Inst
, unsigned N
) const {
575 assert(N
== 1 && "Invalid number of operands!");
577 Inst
.addOperand(MCOperand::createImm(getRDVal()));
580 void addMImmOperands(MCInst
&Inst
, unsigned N
) const {
581 assert(N
== 1 && "Invalid number of operands!");
582 const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(getMImmVal());
583 assert(ConstExpr
&& "Null operands!");
584 int64_t Value
= ConstExpr
->getValue();
587 Inst
.addOperand(MCOperand::createImm(Value
));
590 static std::unique_ptr
<VEOperand
> CreateToken(StringRef Str
, SMLoc S
) {
591 auto Op
= std::make_unique
<VEOperand
>(k_Token
);
592 Op
->Tok
.Data
= Str
.data();
593 Op
->Tok
.Length
= Str
.size();
599 static std::unique_ptr
<VEOperand
> CreateReg(unsigned RegNum
, SMLoc S
,
601 auto Op
= std::make_unique
<VEOperand
>(k_Register
);
602 Op
->Reg
.RegNum
= RegNum
;
608 static std::unique_ptr
<VEOperand
> CreateImm(const MCExpr
*Val
, SMLoc S
,
610 auto Op
= std::make_unique
<VEOperand
>(k_Immediate
);
617 static std::unique_ptr
<VEOperand
> CreateCCOp(unsigned CCVal
, SMLoc S
,
619 auto Op
= std::make_unique
<VEOperand
>(k_CCOp
);
620 Op
->CC
.CCVal
= CCVal
;
626 static std::unique_ptr
<VEOperand
> CreateRDOp(unsigned RDVal
, SMLoc S
,
628 auto Op
= std::make_unique
<VEOperand
>(k_RDOp
);
629 Op
->RD
.RDVal
= RDVal
;
635 static std::unique_ptr
<VEOperand
> CreateMImm(const MCExpr
*Val
, bool Flag
,
637 auto Op
= std::make_unique
<VEOperand
>(k_MImmOp
);
639 Op
->MImm
.M0Flag
= Flag
;
645 static bool MorphToI32Reg(VEOperand
&Op
) {
646 unsigned Reg
= Op
.getReg();
647 unsigned regIdx
= Reg
- VE::SX0
;
650 Op
.Reg
.RegNum
= I32Regs
[regIdx
];
654 static bool MorphToF32Reg(VEOperand
&Op
) {
655 unsigned Reg
= Op
.getReg();
656 unsigned regIdx
= Reg
- VE::SX0
;
659 Op
.Reg
.RegNum
= F32Regs
[regIdx
];
663 static bool MorphToF128Reg(VEOperand
&Op
) {
664 unsigned Reg
= Op
.getReg();
665 unsigned regIdx
= Reg
- VE::SX0
;
666 if (regIdx
% 2 || regIdx
> 63)
668 Op
.Reg
.RegNum
= F128Regs
[regIdx
/ 2];
672 static bool MorphToVM512Reg(VEOperand
&Op
) {
673 unsigned Reg
= Op
.getReg();
674 unsigned regIdx
= Reg
- VE::VM0
;
675 if (regIdx
% 2 || regIdx
> 15)
677 Op
.Reg
.RegNum
= VM512Regs
[regIdx
/ 2];
681 static bool MorphToMISCReg(VEOperand
&Op
) {
682 const auto *ConstExpr
= dyn_cast
<MCConstantExpr
>(Op
.getImm());
685 unsigned regIdx
= ConstExpr
->getValue();
686 if (regIdx
> 31 || MISCRegs
[regIdx
] == VE::NoRegister
)
688 Op
.Kind
= k_Register
;
689 Op
.Reg
.RegNum
= MISCRegs
[regIdx
];
693 static std::unique_ptr
<VEOperand
>
694 MorphToMEMri(unsigned Base
, std::unique_ptr
<VEOperand
> Op
) {
695 const MCExpr
*Imm
= Op
->getImm();
696 Op
->Kind
= k_MemoryRegImm
;
698 Op
->Mem
.IndexReg
= 0;
699 Op
->Mem
.Index
= nullptr;
700 Op
->Mem
.Offset
= Imm
;
704 static std::unique_ptr
<VEOperand
>
705 MorphToMEMzi(std::unique_ptr
<VEOperand
> Op
) {
706 const MCExpr
*Imm
= Op
->getImm();
707 Op
->Kind
= k_MemoryZeroImm
;
709 Op
->Mem
.IndexReg
= 0;
710 Op
->Mem
.Index
= nullptr;
711 Op
->Mem
.Offset
= Imm
;
715 static std::unique_ptr
<VEOperand
>
716 MorphToMEMrri(unsigned Base
, unsigned Index
, std::unique_ptr
<VEOperand
> Op
) {
717 const MCExpr
*Imm
= Op
->getImm();
718 Op
->Kind
= k_MemoryRegRegImm
;
720 Op
->Mem
.IndexReg
= Index
;
721 Op
->Mem
.Index
= nullptr;
722 Op
->Mem
.Offset
= Imm
;
726 static std::unique_ptr
<VEOperand
>
727 MorphToMEMrii(unsigned Base
, const MCExpr
*Index
,
728 std::unique_ptr
<VEOperand
> Op
) {
729 const MCExpr
*Imm
= Op
->getImm();
730 Op
->Kind
= k_MemoryRegImmImm
;
732 Op
->Mem
.IndexReg
= 0;
733 Op
->Mem
.Index
= Index
;
734 Op
->Mem
.Offset
= Imm
;
738 static std::unique_ptr
<VEOperand
>
739 MorphToMEMzri(unsigned Index
, std::unique_ptr
<VEOperand
> Op
) {
740 const MCExpr
*Imm
= Op
->getImm();
741 Op
->Kind
= k_MemoryZeroRegImm
;
743 Op
->Mem
.IndexReg
= Index
;
744 Op
->Mem
.Index
= nullptr;
745 Op
->Mem
.Offset
= Imm
;
749 static std::unique_ptr
<VEOperand
>
750 MorphToMEMzii(const MCExpr
*Index
, std::unique_ptr
<VEOperand
> Op
) {
751 const MCExpr
*Imm
= Op
->getImm();
752 Op
->Kind
= k_MemoryZeroImmImm
;
754 Op
->Mem
.IndexReg
= 0;
755 Op
->Mem
.Index
= Index
;
756 Op
->Mem
.Offset
= Imm
;
761 } // end anonymous namespace
763 bool VEAsmParser::MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
764 OperandVector
&Operands
,
765 MCStreamer
&Out
, uint64_t &ErrorInfo
,
766 bool MatchingInlineAsm
) {
768 unsigned MatchResult
=
769 MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
);
770 switch (MatchResult
) {
773 Out
.emitInstruction(Inst
, getSTI());
776 case Match_MissingFeature
:
778 "instruction requires a CPU feature not currently enabled");
780 case Match_InvalidOperand
: {
781 SMLoc ErrorLoc
= IDLoc
;
782 if (ErrorInfo
!= ~0ULL) {
783 if (ErrorInfo
>= Operands
.size())
784 return Error(IDLoc
, "too few operands for instruction");
786 ErrorLoc
= ((VEOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
787 if (ErrorLoc
== SMLoc())
791 return Error(ErrorLoc
, "invalid operand for instruction");
793 case Match_MnemonicFail
:
794 return Error(IDLoc
, "invalid instruction mnemonic");
796 llvm_unreachable("Implement any new match types added!");
799 bool VEAsmParser::parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
801 if (!tryParseRegister(Reg
, StartLoc
, EndLoc
).isSuccess())
802 return Error(StartLoc
, "invalid register name");
806 /// Parses a register name using a given matching function.
807 /// Checks for lowercase or uppercase if necessary.
808 int VEAsmParser::parseRegisterName(unsigned (*matchFn
)(StringRef
)) {
809 StringRef Name
= Parser
.getTok().getString();
811 int RegNum
= matchFn(Name
);
813 // GCC supports case insensitive register names. All of the VE registers
814 // are all lower case.
815 if (RegNum
== VE::NoRegister
) {
816 RegNum
= matchFn(Name
.lower());
822 /// Maps from the set of all register names to a register number.
823 /// \note Generated by TableGen.
824 static unsigned MatchRegisterName(StringRef Name
);
826 /// Maps from the set of all alternative registernames to a register number.
827 /// \note Generated by TableGen.
828 static unsigned MatchRegisterAltName(StringRef Name
);
830 ParseStatus
VEAsmParser::tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
832 const AsmToken Tok
= Parser
.getTok();
833 StartLoc
= Tok
.getLoc();
834 EndLoc
= Tok
.getEndLoc();
835 Reg
= VE::NoRegister
;
836 if (getLexer().getKind() != AsmToken::Percent
)
837 return ParseStatus::NoMatch
;
840 Reg
= parseRegisterName(&MatchRegisterName
);
841 if (Reg
== VE::NoRegister
)
842 Reg
= parseRegisterName(&MatchRegisterAltName
);
844 if (Reg
!= VE::NoRegister
) {
846 return ParseStatus::Success
;
849 getLexer().UnLex(Tok
);
850 return ParseStatus::NoMatch
;
853 static StringRef
parseCC(StringRef Name
, unsigned Prefix
, unsigned Suffix
,
854 bool IntegerCC
, bool OmitCC
, SMLoc NameLoc
,
855 OperandVector
*Operands
) {
856 // Parse instructions with a conditional code. For example, 'bne' is
857 // converted into two operands 'b' and 'ne'.
858 StringRef Cond
= Name
.slice(Prefix
, Suffix
);
859 VECC::CondCode CondCode
=
860 IntegerCC
? stringToVEICondCode(Cond
) : stringToVEFCondCode(Cond
);
862 // If OmitCC is enabled, CC_AT and CC_AF is treated as a part of mnemonic.
863 if (CondCode
!= VECC::UNKNOWN
&&
864 (!OmitCC
|| (CondCode
!= VECC::CC_AT
&& CondCode
!= VECC::CC_AF
))) {
865 StringRef SuffixStr
= Name
.substr(Suffix
);
867 Name
= Name
.slice(0, Prefix
);
868 Operands
->push_back(VEOperand::CreateToken(Name
, NameLoc
));
870 SMLoc CondLoc
= SMLoc::getFromPointer(NameLoc
.getPointer() + Prefix
);
871 SMLoc SuffixLoc
= SMLoc::getFromPointer(NameLoc
.getPointer() + Suffix
);
872 Operands
->push_back(VEOperand::CreateCCOp(CondCode
, CondLoc
, SuffixLoc
));
873 // push suffix like ".l.t"
874 if (!SuffixStr
.empty())
875 Operands
->push_back(VEOperand::CreateToken(SuffixStr
, SuffixLoc
));
877 Operands
->push_back(VEOperand::CreateToken(Name
, NameLoc
));
882 static StringRef
parseRD(StringRef Name
, unsigned Prefix
, SMLoc NameLoc
,
883 OperandVector
*Operands
) {
884 // Parse instructions with a conditional code. For example, 'cvt.w.d.sx.rz'
885 // is converted into two operands 'cvt.w.d.sx' and '.rz'.
886 StringRef RD
= Name
.substr(Prefix
);
887 VERD::RoundingMode RoundingMode
= stringToVERD(RD
);
889 if (RoundingMode
!= VERD::UNKNOWN
) {
890 Name
= Name
.slice(0, Prefix
);
891 // push 1st like `cvt.w.d.sx`
892 Operands
->push_back(VEOperand::CreateToken(Name
, NameLoc
));
894 SMLoc::getFromPointer(NameLoc
.getPointer() + (RD
.data() - Name
.data()));
896 SMLoc::getFromPointer(NameLoc
.getPointer() + (RD
.end() - Name
.data()));
897 // push $round if it has rounding mode
899 VEOperand::CreateRDOp(RoundingMode
, SuffixLoc
, SuffixEnd
));
901 Operands
->push_back(VEOperand::CreateToken(Name
, NameLoc
));
906 // Split the mnemonic into ASM operand, conditional code and instruction
907 // qualifier (half-word, byte).
908 StringRef
VEAsmParser::splitMnemonic(StringRef Name
, SMLoc NameLoc
,
909 OperandVector
*Operands
) {
910 // Create the leading tokens for the mnemonic
911 StringRef Mnemonic
= Name
;
913 if (Name
[0] == 'b') {
914 // Match b?? or br??.
916 size_t Next
= Name
.find('.');
917 // Adjust position of CondCode.
918 if (Name
.size() > 1 && Name
[1] == 'r')
922 if (Next
+ 1 < Name
.size() &&
923 (Name
[Next
+ 1] == 'd' || Name
[Next
+ 1] == 's'))
925 Mnemonic
= parseCC(Name
, Start
, Next
, ICC
, true, NameLoc
, Operands
);
926 } else if (Name
.starts_with("cmov.l.") || Name
.starts_with("cmov.w.") ||
927 Name
.starts_with("cmov.d.") || Name
.starts_with("cmov.s.")) {
928 bool ICC
= Name
[5] == 'l' || Name
[5] == 'w';
929 Mnemonic
= parseCC(Name
, 7, Name
.size(), ICC
, false, NameLoc
, Operands
);
930 } else if (Name
.starts_with("cvt.w.d.sx") || Name
.starts_with("cvt.w.d.zx") ||
931 Name
.starts_with("cvt.w.s.sx") || Name
.starts_with("cvt.w.s.zx")) {
932 Mnemonic
= parseRD(Name
, 10, NameLoc
, Operands
);
933 } else if (Name
.starts_with("cvt.l.d")) {
934 Mnemonic
= parseRD(Name
, 7, NameLoc
, Operands
);
935 } else if (Name
.starts_with("vcvt.w.d.sx") ||
936 Name
.starts_with("vcvt.w.d.zx") ||
937 Name
.starts_with("vcvt.w.s.sx") ||
938 Name
.starts_with("vcvt.w.s.zx")) {
939 Mnemonic
= parseRD(Name
, 11, NameLoc
, Operands
);
940 } else if (Name
.starts_with("vcvt.l.d")) {
941 Mnemonic
= parseRD(Name
, 8, NameLoc
, Operands
);
942 } else if (Name
.starts_with("pvcvt.w.s.lo") ||
943 Name
.starts_with("pvcvt.w.s.up")) {
944 Mnemonic
= parseRD(Name
, 12, NameLoc
, Operands
);
945 } else if (Name
.starts_with("pvcvt.w.s")) {
946 Mnemonic
= parseRD(Name
, 9, NameLoc
, Operands
);
947 } else if (Name
.starts_with("vfmk.l.") || Name
.starts_with("vfmk.w.") ||
948 Name
.starts_with("vfmk.d.") || Name
.starts_with("vfmk.s.")) {
949 bool ICC
= Name
[5] == 'l' || Name
[5] == 'w' ? true : false;
950 Mnemonic
= parseCC(Name
, 7, Name
.size(), ICC
, true, NameLoc
, Operands
);
951 } else if (Name
.starts_with("pvfmk.w.lo.") ||
952 Name
.starts_with("pvfmk.w.up.") ||
953 Name
.starts_with("pvfmk.s.lo.") ||
954 Name
.starts_with("pvfmk.s.up.")) {
955 bool ICC
= Name
[6] == 'l' || Name
[6] == 'w' ? true : false;
956 Mnemonic
= parseCC(Name
, 11, Name
.size(), ICC
, true, NameLoc
, Operands
);
958 Operands
->push_back(VEOperand::CreateToken(Mnemonic
, NameLoc
));
964 static void applyMnemonicAliases(StringRef
&Mnemonic
,
965 const FeatureBitset
&Features
,
968 bool VEAsmParser::ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
969 SMLoc NameLoc
, OperandVector
&Operands
) {
970 // If the target architecture uses MnemonicAlias, call it here to parse
971 // operands correctly.
972 applyMnemonicAliases(Name
, getAvailableFeatures(), 0);
974 // Split name to first token and the rest, e.g. "bgt.l.t" to "b", "gt", and
975 // ".l.t". We treat "b" as a mnemonic, "gt" as first operand, and ".l.t"
976 // as second operand.
977 StringRef Mnemonic
= splitMnemonic(Name
, NameLoc
, &Operands
);
979 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
980 // Read the first operand.
981 if (!parseOperand(Operands
, Mnemonic
).isSuccess()) {
982 SMLoc Loc
= getLexer().getLoc();
983 return Error(Loc
, "unexpected token");
986 while (getLexer().is(AsmToken::Comma
)) {
987 Parser
.Lex(); // Eat the comma.
988 // Parse and remember the operand.
989 if (!parseOperand(Operands
, Mnemonic
).isSuccess()) {
990 SMLoc Loc
= getLexer().getLoc();
991 return Error(Loc
, "unexpected token");
995 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
996 SMLoc Loc
= getLexer().getLoc();
997 return Error(Loc
, "unexpected token");
999 Parser
.Lex(); // Consume the EndOfStatement.
1003 ParseStatus
VEAsmParser::parseDirective(AsmToken DirectiveID
) {
1004 std::string IDVal
= DirectiveID
.getIdentifier().lower();
1006 // Defines VE specific directives. Reference is "Vector Engine Assembly
1007 // Language Reference Manual":
1008 // https://www.hpc.nec/documents/sdk/pdfs/VectorEngine-as-manual-v1.3.pdf
1010 // The .word is 4 bytes long on VE.
1011 if (IDVal
== ".word")
1012 return parseLiteralValues(4, DirectiveID
.getLoc());
1014 // The .long is 8 bytes long on VE.
1015 if (IDVal
== ".long")
1016 return parseLiteralValues(8, DirectiveID
.getLoc());
1018 // The .llong is 8 bytes long on VE.
1019 if (IDVal
== ".llong")
1020 return parseLiteralValues(8, DirectiveID
.getLoc());
1022 // Let the MC layer to handle other directives.
1023 return ParseStatus::NoMatch
;
1026 /// parseLiteralValues
1027 /// ::= .word expression [, expression]*
1028 /// ::= .long expression [, expression]*
1029 /// ::= .llong expression [, expression]*
1030 bool VEAsmParser::parseLiteralValues(unsigned Size
, SMLoc L
) {
1031 auto parseOne
= [&]() -> bool {
1032 const MCExpr
*Value
;
1033 if (getParser().parseExpression(Value
))
1035 getParser().getStreamer().emitValue(Value
, Size
, L
);
1038 return (parseMany(parseOne
));
1041 /// Extract \code @lo32/@hi32/etc \endcode modifier from expression.
1042 /// Recursively scan the expression and check for VK_VE_HI32/LO32/etc
1043 /// symbol variants. If all symbols with modifier use the same
1044 /// variant, return the corresponding VEMCExpr::VariantKind,
1045 /// and a modified expression using the default symbol variant.
1046 /// Otherwise, return NULL.
1048 VEAsmParser::extractModifierFromExpr(const MCExpr
*E
,
1049 VEMCExpr::VariantKind
&Variant
) {
1050 MCContext
&Context
= getParser().getContext();
1051 Variant
= VEMCExpr::VK_VE_None
;
1053 switch (E
->getKind()) {
1054 case MCExpr::Target
:
1055 case MCExpr::Constant
:
1058 case MCExpr::SymbolRef
: {
1059 const MCSymbolRefExpr
*SRE
= cast
<MCSymbolRefExpr
>(E
);
1061 switch (SRE
->getKind()) {
1062 case MCSymbolRefExpr::VK_None
:
1063 // Use VK_VE_REFLONG to a symbol without modifiers.
1064 Variant
= VEMCExpr::VK_VE_REFLONG
;
1066 case MCSymbolRefExpr::VK_VE_HI32
:
1067 Variant
= VEMCExpr::VK_VE_HI32
;
1069 case MCSymbolRefExpr::VK_VE_LO32
:
1070 Variant
= VEMCExpr::VK_VE_LO32
;
1072 case MCSymbolRefExpr::VK_VE_PC_HI32
:
1073 Variant
= VEMCExpr::VK_VE_PC_HI32
;
1075 case MCSymbolRefExpr::VK_VE_PC_LO32
:
1076 Variant
= VEMCExpr::VK_VE_PC_LO32
;
1078 case MCSymbolRefExpr::VK_VE_GOT_HI32
:
1079 Variant
= VEMCExpr::VK_VE_GOT_HI32
;
1081 case MCSymbolRefExpr::VK_VE_GOT_LO32
:
1082 Variant
= VEMCExpr::VK_VE_GOT_LO32
;
1084 case MCSymbolRefExpr::VK_VE_GOTOFF_HI32
:
1085 Variant
= VEMCExpr::VK_VE_GOTOFF_HI32
;
1087 case MCSymbolRefExpr::VK_VE_GOTOFF_LO32
:
1088 Variant
= VEMCExpr::VK_VE_GOTOFF_LO32
;
1090 case MCSymbolRefExpr::VK_VE_PLT_HI32
:
1091 Variant
= VEMCExpr::VK_VE_PLT_HI32
;
1093 case MCSymbolRefExpr::VK_VE_PLT_LO32
:
1094 Variant
= VEMCExpr::VK_VE_PLT_LO32
;
1096 case MCSymbolRefExpr::VK_VE_TLS_GD_HI32
:
1097 Variant
= VEMCExpr::VK_VE_TLS_GD_HI32
;
1099 case MCSymbolRefExpr::VK_VE_TLS_GD_LO32
:
1100 Variant
= VEMCExpr::VK_VE_TLS_GD_LO32
;
1102 case MCSymbolRefExpr::VK_VE_TPOFF_HI32
:
1103 Variant
= VEMCExpr::VK_VE_TPOFF_HI32
;
1105 case MCSymbolRefExpr::VK_VE_TPOFF_LO32
:
1106 Variant
= VEMCExpr::VK_VE_TPOFF_LO32
;
1112 return MCSymbolRefExpr::create(&SRE
->getSymbol(), Context
);
1115 case MCExpr::Unary
: {
1116 const MCUnaryExpr
*UE
= cast
<MCUnaryExpr
>(E
);
1117 const MCExpr
*Sub
= extractModifierFromExpr(UE
->getSubExpr(), Variant
);
1120 return MCUnaryExpr::create(UE
->getOpcode(), Sub
, Context
);
1123 case MCExpr::Binary
: {
1124 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(E
);
1125 VEMCExpr::VariantKind LHSVariant
, RHSVariant
;
1126 const MCExpr
*LHS
= extractModifierFromExpr(BE
->getLHS(), LHSVariant
);
1127 const MCExpr
*RHS
= extractModifierFromExpr(BE
->getRHS(), RHSVariant
);
1137 if (LHSVariant
== VEMCExpr::VK_VE_None
)
1138 Variant
= RHSVariant
;
1139 else if (RHSVariant
== VEMCExpr::VK_VE_None
)
1140 Variant
= LHSVariant
;
1141 else if (LHSVariant
== RHSVariant
)
1142 Variant
= LHSVariant
;
1146 return MCBinaryExpr::create(BE
->getOpcode(), LHS
, RHS
, Context
);
1150 llvm_unreachable("Invalid expression kind!");
1153 const MCExpr
*VEAsmParser::fixupVariantKind(const MCExpr
*E
) {
1154 MCContext
&Context
= getParser().getContext();
1156 switch (E
->getKind()) {
1157 case MCExpr::Target
:
1158 case MCExpr::Constant
:
1159 case MCExpr::SymbolRef
:
1162 case MCExpr::Unary
: {
1163 const MCUnaryExpr
*UE
= cast
<MCUnaryExpr
>(E
);
1164 const MCExpr
*Sub
= fixupVariantKind(UE
->getSubExpr());
1165 if (Sub
== UE
->getSubExpr())
1167 return MCUnaryExpr::create(UE
->getOpcode(), Sub
, Context
);
1170 case MCExpr::Binary
: {
1171 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(E
);
1172 const MCExpr
*LHS
= fixupVariantKind(BE
->getLHS());
1173 const MCExpr
*RHS
= fixupVariantKind(BE
->getRHS());
1174 if (LHS
== BE
->getLHS() && RHS
== BE
->getRHS())
1176 return MCBinaryExpr::create(BE
->getOpcode(), LHS
, RHS
, Context
);
1180 llvm_unreachable("Invalid expression kind!");
1183 /// ParseExpression. This differs from the default "parseExpression" in that
1184 /// it handles modifiers.
1185 bool VEAsmParser::parseExpression(const MCExpr
*&EVal
) {
1186 // Handle \code symbol @lo32/@hi32/etc \endcode.
1187 if (getParser().parseExpression(EVal
))
1190 // Convert MCSymbolRefExpr with VK_* to MCExpr with VK_*.
1191 EVal
= fixupVariantKind(EVal
);
1192 VEMCExpr::VariantKind Variant
;
1193 const MCExpr
*E
= extractModifierFromExpr(EVal
, Variant
);
1195 EVal
= VEMCExpr::create(Variant
, E
, getParser().getContext());
1200 ParseStatus
VEAsmParser::parseMEMOperand(OperandVector
&Operands
) {
1201 LLVM_DEBUG(dbgs() << "parseMEMOperand\n");
1202 const AsmToken
&Tok
= Parser
.getTok();
1203 SMLoc S
= Tok
.getLoc();
1204 SMLoc E
= Tok
.getEndLoc();
1209 // disp(index, base)
1214 std::unique_ptr
<VEOperand
> Offset
;
1215 switch (getLexer().getKind()) {
1217 return ParseStatus::NoMatch
;
1219 case AsmToken::Minus
:
1220 case AsmToken::Integer
:
1222 case AsmToken::Identifier
: {
1224 if (!parseExpression(EVal
))
1225 Offset
= VEOperand::CreateImm(EVal
, S
, E
);
1227 return ParseStatus::NoMatch
;
1231 case AsmToken::LParen
:
1234 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S
, E
);
1238 switch (getLexer().getKind()) {
1240 return ParseStatus::Failure
;
1242 case AsmToken::EndOfStatement
:
1243 Operands
.push_back(VEOperand::MorphToMEMzii(
1244 MCConstantExpr::create(0, getContext()), std::move(Offset
)));
1245 return ParseStatus::Success
;
1247 case AsmToken::LParen
:
1248 Parser
.Lex(); // Eat the (
1252 const MCExpr
*IndexValue
= nullptr;
1253 MCRegister IndexReg
;
1255 switch (getLexer().getKind()) {
1257 if (parseRegister(IndexReg
, S
, E
))
1258 return ParseStatus::Failure
;
1261 case AsmToken::Minus
:
1262 case AsmToken::Integer
:
1264 if (getParser().parseExpression(IndexValue
, E
))
1265 return ParseStatus::Failure
;
1268 case AsmToken::Comma
:
1270 IndexValue
= MCConstantExpr::create(0, getContext());
1274 switch (getLexer().getKind()) {
1276 return ParseStatus::Failure
;
1278 case AsmToken::RParen
:
1279 Parser
.Lex(); // Eat the )
1281 IndexValue
? VEOperand::MorphToMEMzii(IndexValue
, std::move(Offset
))
1282 : VEOperand::MorphToMEMzri(IndexReg
, std::move(Offset
)));
1283 return ParseStatus::Success
;
1285 case AsmToken::Comma
:
1286 Parser
.Lex(); // Eat the ,
1291 if (parseRegister(BaseReg
, S
, E
))
1292 return ParseStatus::Failure
;
1294 if (!Parser
.getTok().is(AsmToken::RParen
))
1295 return ParseStatus::Failure
;
1297 Parser
.Lex(); // Eat the )
1300 ? VEOperand::MorphToMEMrii(BaseReg
, IndexValue
, std::move(Offset
))
1301 : VEOperand::MorphToMEMrri(BaseReg
, IndexReg
, std::move(Offset
)));
1303 return ParseStatus::Success
;
1306 ParseStatus
VEAsmParser::parseMEMAsOperand(OperandVector
&Operands
) {
1307 LLVM_DEBUG(dbgs() << "parseMEMAsOperand\n");
1308 const AsmToken
&Tok
= Parser
.getTok();
1309 SMLoc S
= Tok
.getLoc();
1310 SMLoc E
= Tok
.getEndLoc();
1321 std::unique_ptr
<VEOperand
> Offset
;
1322 switch (getLexer().getKind()) {
1324 return ParseStatus::NoMatch
;
1326 case AsmToken::Minus
:
1327 case AsmToken::Integer
:
1329 case AsmToken::Identifier
: {
1331 if (!parseExpression(EVal
))
1332 Offset
= VEOperand::CreateImm(EVal
, S
, E
);
1334 return ParseStatus::NoMatch
;
1338 case AsmToken::Percent
:
1339 if (parseRegister(BaseReg
, S
, E
))
1340 return ParseStatus::NoMatch
;
1342 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S
, E
);
1345 case AsmToken::LParen
:
1348 VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S
, E
);
1352 switch (getLexer().getKind()) {
1354 return ParseStatus::Failure
;
1356 case AsmToken::EndOfStatement
:
1357 case AsmToken::Comma
:
1358 Operands
.push_back(BaseReg
!= VE::NoRegister
1359 ? VEOperand::MorphToMEMri(BaseReg
, std::move(Offset
))
1360 : VEOperand::MorphToMEMzi(std::move(Offset
)));
1361 return ParseStatus::Success
;
1363 case AsmToken::LParen
:
1364 if (BaseReg
!= VE::NoRegister
)
1365 return ParseStatus::Failure
;
1366 Parser
.Lex(); // Eat the (
1370 switch (getLexer().getKind()) {
1372 if (parseRegister(BaseReg
, S
, E
))
1373 return ParseStatus::Failure
;
1376 case AsmToken::Comma
:
1377 Parser
.Lex(); // Eat the ,
1378 if (parseRegister(BaseReg
, S
, E
))
1379 return ParseStatus::Failure
;
1382 case AsmToken::RParen
:
1386 if (!Parser
.getTok().is(AsmToken::RParen
))
1387 return ParseStatus::Failure
;
1389 Parser
.Lex(); // Eat the )
1390 Operands
.push_back(BaseReg
!= VE::NoRegister
1391 ? VEOperand::MorphToMEMri(BaseReg
, std::move(Offset
))
1392 : VEOperand::MorphToMEMzi(std::move(Offset
)));
1394 return ParseStatus::Success
;
1397 ParseStatus
VEAsmParser::parseMImmOperand(OperandVector
&Operands
) {
1398 LLVM_DEBUG(dbgs() << "parseMImmOperand\n");
1400 // Parsing "(" + number + ")0/1"
1401 const AsmToken Tok1
= Parser
.getTok();
1402 if (!Tok1
.is(AsmToken::LParen
))
1403 return ParseStatus::NoMatch
;
1405 Parser
.Lex(); // Eat the '('.
1407 const AsmToken Tok2
= Parser
.getTok();
1410 if (!Tok2
.is(AsmToken::Integer
) || getParser().parseExpression(EVal
, E
)) {
1411 getLexer().UnLex(Tok1
);
1412 return ParseStatus::NoMatch
;
1415 const AsmToken Tok3
= Parser
.getTok();
1416 if (!Tok3
.is(AsmToken::RParen
)) {
1417 getLexer().UnLex(Tok2
);
1418 getLexer().UnLex(Tok1
);
1419 return ParseStatus::NoMatch
;
1421 Parser
.Lex(); // Eat the ')'.
1423 const AsmToken
&Tok4
= Parser
.getTok();
1424 StringRef Suffix
= Tok4
.getString();
1425 if (Suffix
!= "1" && Suffix
!= "0") {
1426 getLexer().UnLex(Tok3
);
1427 getLexer().UnLex(Tok2
);
1428 getLexer().UnLex(Tok1
);
1429 return ParseStatus::NoMatch
;
1431 Parser
.Lex(); // Eat the value.
1432 SMLoc EndLoc
= SMLoc::getFromPointer(Suffix
.end());
1434 VEOperand::CreateMImm(EVal
, Suffix
== "0", Tok1
.getLoc(), EndLoc
));
1435 return ParseStatus::Success
;
1438 ParseStatus
VEAsmParser::parseOperand(OperandVector
&Operands
,
1439 StringRef Mnemonic
) {
1440 LLVM_DEBUG(dbgs() << "parseOperand\n");
1441 ParseStatus Res
= MatchOperandParserImpl(Operands
, Mnemonic
);
1443 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1444 // there was a match, but an error occurred, in which case, just return that
1445 // the operand parsing failed.
1446 if (Res
.isSuccess() || Res
.isFailure())
1449 switch (getLexer().getKind()) {
1450 case AsmToken::LParen
: {
1451 // Parsing "(" + %vreg + ", " + %vreg + ")"
1452 const AsmToken Tok1
= Parser
.getTok();
1453 Parser
.Lex(); // Eat the '('.
1457 if (!tryParseRegister(Reg1
, S1
, E1
).isSuccess()) {
1458 getLexer().UnLex(Tok1
);
1459 return ParseStatus::NoMatch
;
1462 if (!Parser
.getTok().is(AsmToken::Comma
))
1463 return ParseStatus::Failure
;
1464 Parser
.Lex(); // Eat the ','.
1468 if (!tryParseRegister(Reg2
, S2
, E2
).isSuccess())
1469 return ParseStatus::Failure
;
1471 if (!Parser
.getTok().is(AsmToken::RParen
))
1472 return ParseStatus::Failure
;
1474 Operands
.push_back(VEOperand::CreateToken(Tok1
.getString(), Tok1
.getLoc()));
1475 Operands
.push_back(VEOperand::CreateReg(Reg1
, S1
, E1
));
1476 Operands
.push_back(VEOperand::CreateReg(Reg2
, S2
, E2
));
1477 Operands
.push_back(VEOperand::CreateToken(Parser
.getTok().getString(),
1478 Parser
.getTok().getLoc()));
1479 Parser
.Lex(); // Eat the ')'.
1483 std::unique_ptr
<VEOperand
> Op
;
1484 Res
= parseVEAsmOperand(Op
);
1485 if (!Res
.isSuccess() || !Op
)
1486 return ParseStatus::Failure
;
1488 // Push the parsed operand into the list of operands
1489 Operands
.push_back(std::move(Op
));
1491 if (!Parser
.getTok().is(AsmToken::LParen
))
1494 // Parsing %vec-reg + "(" + %sclar-reg/number + ")"
1495 std::unique_ptr
<VEOperand
> Op1
= VEOperand::CreateToken(
1496 Parser
.getTok().getString(), Parser
.getTok().getLoc());
1497 Parser
.Lex(); // Eat the '('.
1499 std::unique_ptr
<VEOperand
> Op2
;
1500 Res
= parseVEAsmOperand(Op2
);
1501 if (!Res
.isSuccess() || !Op2
)
1502 return ParseStatus::Failure
;
1504 if (!Parser
.getTok().is(AsmToken::RParen
))
1505 return ParseStatus::Failure
;
1507 Operands
.push_back(std::move(Op1
));
1508 Operands
.push_back(std::move(Op2
));
1509 Operands
.push_back(VEOperand::CreateToken(Parser
.getTok().getString(),
1510 Parser
.getTok().getLoc()));
1511 Parser
.Lex(); // Eat the ')'.
1516 return ParseStatus::Success
;
1519 ParseStatus
VEAsmParser::parseVEAsmOperand(std::unique_ptr
<VEOperand
> &Op
) {
1520 LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n");
1521 SMLoc S
= Parser
.getTok().getLoc();
1522 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1526 switch (getLexer().getKind()) {
1530 case AsmToken::Percent
: {
1532 if (tryParseRegister(Reg
, S
, E
).isSuccess())
1533 Op
= VEOperand::CreateReg(Reg
, S
, E
);
1536 case AsmToken::Minus
:
1537 case AsmToken::Integer
:
1539 case AsmToken::Identifier
:
1540 if (!parseExpression(EVal
))
1541 Op
= VEOperand::CreateImm(EVal
, S
, E
);
1544 return Op
? ParseStatus::Success
: ParseStatus::Failure
;
1547 // Force static initialization.
1548 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeVEAsmParser() {
1549 RegisterMCAsmParser
<VEAsmParser
> A(getTheVETarget());
1552 #define GET_REGISTER_MATCHER
1553 #define GET_MATCHER_IMPLEMENTATION
1554 #include "VEGenAsmMatcher.inc"
1556 unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand
&GOp
,
1558 VEOperand
&Op
= (VEOperand
&)GOp
;
1560 // VE uses identical register name for all registers like both
1561 // F32 and I32 uses "%s23". Need to convert the name of them
1567 if (Op
.isReg() && VEOperand::MorphToF32Reg(Op
))
1568 return MCTargetAsmParser::Match_Success
;
1571 if (Op
.isReg() && VEOperand::MorphToI32Reg(Op
))
1572 return MCTargetAsmParser::Match_Success
;
1575 if (Op
.isReg() && VEOperand::MorphToF128Reg(Op
))
1576 return MCTargetAsmParser::Match_Success
;
1579 if (Op
.isReg() && VEOperand::MorphToVM512Reg(Op
))
1580 return MCTargetAsmParser::Match_Success
;
1583 if (Op
.isImm() && VEOperand::MorphToMISCReg(Op
))
1584 return MCTargetAsmParser::Match_Success
;
1587 return Match_InvalidOperand
;