1 //===-- VEInstPrinter.cpp - Convert VE MCInst to assembly syntax -----------==//
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 // This class prints an VE MCInst to a .s file.
11 //===----------------------------------------------------------------------===//
13 #include "VEInstPrinter.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCRegisterInfo.h"
18 #include "llvm/MC/MCSubtargetInfo.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Support/raw_ostream.h"
24 #define DEBUG_TYPE "ve-asmprinter"
26 #define GET_INSTRUCTION_NAME
27 #define PRINT_ALIAS_INSTR
28 #include "VEGenAsmWriter.inc"
30 void VEInstPrinter::printRegName(raw_ostream
&OS
, MCRegister Reg
) const {
31 // Generic registers have identical register name among register classes.
32 unsigned AltIdx
= VE::AsmName
;
33 // Misc registers have each own name, so no use alt-names.
34 if (MRI
.getRegClass(VE::MISCRegClassID
).contains(Reg
))
35 AltIdx
= VE::NoRegAltName
;
36 OS
<< '%' << getRegisterName(Reg
, AltIdx
);
39 void VEInstPrinter::printInst(const MCInst
*MI
, uint64_t Address
,
40 StringRef Annot
, const MCSubtargetInfo
&STI
,
42 if (!printAliasInstr(MI
, Address
, STI
, OS
))
43 printInstruction(MI
, Address
, STI
, OS
);
44 printAnnotation(OS
, Annot
);
47 void VEInstPrinter::printOperand(const MCInst
*MI
, int OpNum
,
48 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
49 const MCOperand
&MO
= MI
->getOperand(OpNum
);
52 printRegName(O
, MO
.getReg());
57 // Expects signed 32bit literals.
58 int32_t TruncatedImm
= static_cast<int32_t>(MO
.getImm());
63 assert(MO
.isExpr() && "Unknown operand kind in printOperand");
64 MO
.getExpr()->print(O
, &MAI
);
67 void VEInstPrinter::printMemASXOperand(const MCInst
*MI
, int OpNum
,
68 const MCSubtargetInfo
&STI
,
69 raw_ostream
&O
, const char *Modifier
) {
70 // If this is an ADD operand, emit it like normal operands.
71 if (Modifier
&& !strcmp(Modifier
, "arith")) {
72 printOperand(MI
, OpNum
, STI
, O
);
74 printOperand(MI
, OpNum
+ 1, STI
, O
);
78 if (MI
->getOperand(OpNum
+ 2).isImm() &&
79 MI
->getOperand(OpNum
+ 2).getImm() == 0) {
82 printOperand(MI
, OpNum
+ 2, STI
, O
);
84 if (MI
->getOperand(OpNum
+ 1).isImm() &&
85 MI
->getOperand(OpNum
+ 1).getImm() == 0 &&
86 MI
->getOperand(OpNum
).isImm() && MI
->getOperand(OpNum
).getImm() == 0) {
87 if (MI
->getOperand(OpNum
+ 2).isImm() &&
88 MI
->getOperand(OpNum
+ 2).getImm() == 0) {
91 // don't print "+0,+0"
95 if (MI
->getOperand(OpNum
+ 1).isImm() &&
96 MI
->getOperand(OpNum
+ 1).getImm() == 0) {
99 printOperand(MI
, OpNum
+ 1, STI
, O
);
101 if (MI
->getOperand(OpNum
).isImm() && MI
->getOperand(OpNum
).getImm() == 0) {
105 printOperand(MI
, OpNum
, STI
, O
);
111 void VEInstPrinter::printMemASOperandASX(const MCInst
*MI
, int OpNum
,
112 const MCSubtargetInfo
&STI
,
113 raw_ostream
&O
, const char *Modifier
) {
114 // If this is an ADD operand, emit it like normal operands.
115 if (Modifier
&& !strcmp(Modifier
, "arith")) {
116 printOperand(MI
, OpNum
, STI
, O
);
118 printOperand(MI
, OpNum
+ 1, STI
, O
);
122 if (MI
->getOperand(OpNum
+ 1).isImm() &&
123 MI
->getOperand(OpNum
+ 1).getImm() == 0) {
126 printOperand(MI
, OpNum
+ 1, STI
, O
);
128 if (MI
->getOperand(OpNum
).isImm() && MI
->getOperand(OpNum
).getImm() == 0) {
129 if (MI
->getOperand(OpNum
+ 1).isImm() &&
130 MI
->getOperand(OpNum
+ 1).getImm() == 0) {
137 printOperand(MI
, OpNum
, STI
, O
);
142 void VEInstPrinter::printMemASOperandRRM(const MCInst
*MI
, int OpNum
,
143 const MCSubtargetInfo
&STI
,
144 raw_ostream
&O
, const char *Modifier
) {
145 // If this is an ADD operand, emit it like normal operands.
146 if (Modifier
&& !strcmp(Modifier
, "arith")) {
147 printOperand(MI
, OpNum
, STI
, O
);
149 printOperand(MI
, OpNum
+ 1, STI
, O
);
153 if (MI
->getOperand(OpNum
+ 1).isImm() &&
154 MI
->getOperand(OpNum
+ 1).getImm() == 0) {
157 printOperand(MI
, OpNum
+ 1, STI
, O
);
159 if (MI
->getOperand(OpNum
).isImm() && MI
->getOperand(OpNum
).getImm() == 0) {
160 if (MI
->getOperand(OpNum
+ 1).isImm() &&
161 MI
->getOperand(OpNum
+ 1).getImm() == 0) {
168 printOperand(MI
, OpNum
, STI
, O
);
173 void VEInstPrinter::printMemASOperandHM(const MCInst
*MI
, int OpNum
,
174 const MCSubtargetInfo
&STI
,
175 raw_ostream
&O
, const char *Modifier
) {
176 // If this is an ADD operand, emit it like normal operands.
177 if (Modifier
&& !strcmp(Modifier
, "arith")) {
178 printOperand(MI
, OpNum
, STI
, O
);
180 printOperand(MI
, OpNum
+ 1, STI
, O
);
184 if (MI
->getOperand(OpNum
+ 1).isImm() &&
185 MI
->getOperand(OpNum
+ 1).getImm() == 0) {
188 printOperand(MI
, OpNum
+ 1, STI
, O
);
191 if (MI
->getOperand(OpNum
).isReg())
192 printOperand(MI
, OpNum
, STI
, O
);
196 void VEInstPrinter::printMImmOperand(const MCInst
*MI
, int OpNum
,
197 const MCSubtargetInfo
&STI
,
199 int MImm
= (int)MI
->getOperand(OpNum
).getImm() & 0x7f;
201 O
<< "(" << MImm
- 64 << ")0";
203 O
<< "(" << MImm
<< ")1";
206 void VEInstPrinter::printCCOperand(const MCInst
*MI
, int OpNum
,
207 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
208 int CC
= (int)MI
->getOperand(OpNum
).getImm();
209 O
<< VECondCodeToString((VECC::CondCode
)CC
);
212 void VEInstPrinter::printRDOperand(const MCInst
*MI
, int OpNum
,
213 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
214 int RD
= (int)MI
->getOperand(OpNum
).getImm();
215 O
<< VERDToString((VERD::RoundingMode
)RD
);