1 //===-- VEInstPrinter.cpp - Convert VE MCInst to assembly syntax -----------==//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class prints an VE MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "VEInstPrinter.h"
14 #include "VE.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"
21
22 using namespace llvm;
23
24 #define DEBUG_TYPE "ve-asmprinter"
25
26 #define GET_INSTRUCTION_NAME
27 #define PRINT_ALIAS_INSTR
28 #include "VEGenAsmWriter.inc"
29
printRegName(raw_ostream & OS,MCRegister Reg) const30 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);
37 }
38
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & OS)39 void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address,
40 StringRef Annot, const MCSubtargetInfo &STI,
41 raw_ostream &OS) {
42 if (!printAliasInstr(MI, Address, STI, OS))
43 printInstruction(MI, Address, STI, OS);
44 printAnnotation(OS, Annot);
45 }
46
printOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)47 void VEInstPrinter::printOperand(const MCInst *MI, int OpNum,
48 const MCSubtargetInfo &STI, raw_ostream &O) {
49 const MCOperand &MO = MI->getOperand(OpNum);
50
51 if (MO.isReg()) {
52 printRegName(O, MO.getReg());
53 return;
54 }
55
56 if (MO.isImm()) {
57 // Expects signed 32bit literals.
58 int32_t TruncatedImm = static_cast<int32_t>(MO.getImm());
59 O << TruncatedImm;
60 return;
61 }
62
63 assert(MO.isExpr() && "Unknown operand kind in printOperand");
64 MO.getExpr()->print(O, &MAI);
65 }
66
printMemASXOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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);
73 O << ", ";
74 printOperand(MI, OpNum + 1, STI, O);
75 return;
76 }
77
78 if (MI->getOperand(OpNum + 2).isImm() &&
79 MI->getOperand(OpNum + 2).getImm() == 0) {
80 // don't print "+0"
81 } else {
82 printOperand(MI, OpNum + 2, STI, O);
83 }
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) {
89 O << "0";
90 } else {
91 // don't print "+0,+0"
92 }
93 } else {
94 O << "(";
95 if (MI->getOperand(OpNum + 1).isImm() &&
96 MI->getOperand(OpNum + 1).getImm() == 0) {
97 // don't print "+0"
98 } else {
99 printOperand(MI, OpNum + 1, STI, O);
100 }
101 if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) {
102 // don't print "+0"
103 } else {
104 O << ", ";
105 printOperand(MI, OpNum, STI, O);
106 }
107 O << ")";
108 }
109 }
110
printMemASOperandASX(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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);
117 O << ", ";
118 printOperand(MI, OpNum + 1, STI, O);
119 return;
120 }
121
122 if (MI->getOperand(OpNum + 1).isImm() &&
123 MI->getOperand(OpNum + 1).getImm() == 0) {
124 // don't print "+0"
125 } else {
126 printOperand(MI, OpNum + 1, STI, O);
127 }
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) {
131 O << "0";
132 } else {
133 // don't print "(0)"
134 }
135 } else {
136 O << "(, ";
137 printOperand(MI, OpNum, STI, O);
138 O << ")";
139 }
140 }
141
printMemASOperandRRM(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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);
148 O << ", ";
149 printOperand(MI, OpNum + 1, STI, O);
150 return;
151 }
152
153 if (MI->getOperand(OpNum + 1).isImm() &&
154 MI->getOperand(OpNum + 1).getImm() == 0) {
155 // don't print "+0"
156 } else {
157 printOperand(MI, OpNum + 1, STI, O);
158 }
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) {
162 O << "0";
163 } else {
164 // don't print "(0)"
165 }
166 } else {
167 O << "(";
168 printOperand(MI, OpNum, STI, O);
169 O << ")";
170 }
171 }
172
printMemASOperandHM(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)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);
179 O << ", ";
180 printOperand(MI, OpNum + 1, STI, O);
181 return;
182 }
183
184 if (MI->getOperand(OpNum + 1).isImm() &&
185 MI->getOperand(OpNum + 1).getImm() == 0) {
186 // don't print "+0"
187 } else {
188 printOperand(MI, OpNum + 1, STI, O);
189 }
190 O << "(";
191 if (MI->getOperand(OpNum).isReg())
192 printOperand(MI, OpNum, STI, O);
193 O << ")";
194 }
195
printMImmOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)196 void VEInstPrinter::printMImmOperand(const MCInst *MI, int OpNum,
197 const MCSubtargetInfo &STI,
198 raw_ostream &O) {
199 int MImm = (int)MI->getOperand(OpNum).getImm() & 0x7f;
200 if (MImm > 63)
201 O << "(" << MImm - 64 << ")0";
202 else
203 O << "(" << MImm << ")1";
204 }
205
printCCOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)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);
210 }
211
printRDOperand(const MCInst * MI,int OpNum,const MCSubtargetInfo & STI,raw_ostream & O)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);
216 }
217