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
22using 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
30void 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(i: VE::MISCRegClassID).contains(Reg))
35 AltIdx = VE::NoRegAltName;
36 OS << '%' << getRegisterName(Reg, AltIdx);
37}
38
39void 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, O&: OS);
44 printAnnotation(OS, Annot);
45}
46
47void VEInstPrinter::printOperand(const MCInst *MI, int OpNum,
48 const MCSubtargetInfo &STI, raw_ostream &O) {
49 const MCOperand &MO = MI->getOperand(i: OpNum);
50
51 if (MO.isReg()) {
52 printRegName(OS&: O, Reg: 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(OS&: O, MAI: &MAI);
65}
66
67void 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(s1: Modifier, s2: "arith")) {
72 printOperand(MI, OpNum, STI, O);
73 O << ", ";
74 printOperand(MI, OpNum: OpNum + 1, STI, O);
75 return;
76 }
77
78 if (MI->getOperand(i: OpNum + 2).isImm() &&
79 MI->getOperand(i: OpNum + 2).getImm() == 0) {
80 // don't print "+0"
81 } else {
82 printOperand(MI, OpNum: OpNum + 2, STI, O);
83 }
84 if (MI->getOperand(i: OpNum + 1).isImm() &&
85 MI->getOperand(i: OpNum + 1).getImm() == 0 &&
86 MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
87 if (MI->getOperand(i: OpNum + 2).isImm() &&
88 MI->getOperand(i: OpNum + 2).getImm() == 0) {
89 O << "0";
90 } else {
91 // don't print "+0,+0"
92 }
93 } else {
94 O << "(";
95 if (MI->getOperand(i: OpNum + 1).isImm() &&
96 MI->getOperand(i: OpNum + 1).getImm() == 0) {
97 // don't print "+0"
98 } else {
99 printOperand(MI, OpNum: OpNum + 1, STI, O);
100 }
101 if (MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
102 // don't print "+0"
103 } else {
104 O << ", ";
105 printOperand(MI, OpNum, STI, O);
106 }
107 O << ")";
108 }
109}
110
111void 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(s1: Modifier, s2: "arith")) {
116 printOperand(MI, OpNum, STI, O);
117 O << ", ";
118 printOperand(MI, OpNum: OpNum + 1, STI, O);
119 return;
120 }
121
122 if (MI->getOperand(i: OpNum + 1).isImm() &&
123 MI->getOperand(i: OpNum + 1).getImm() == 0) {
124 // don't print "+0"
125 } else {
126 printOperand(MI, OpNum: OpNum + 1, STI, O);
127 }
128 if (MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
129 if (MI->getOperand(i: OpNum + 1).isImm() &&
130 MI->getOperand(i: 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
142void 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(s1: Modifier, s2: "arith")) {
147 printOperand(MI, OpNum, STI, O);
148 O << ", ";
149 printOperand(MI, OpNum: OpNum + 1, STI, O);
150 return;
151 }
152
153 if (MI->getOperand(i: OpNum + 1).isImm() &&
154 MI->getOperand(i: OpNum + 1).getImm() == 0) {
155 // don't print "+0"
156 } else {
157 printOperand(MI, OpNum: OpNum + 1, STI, O);
158 }
159 if (MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
160 if (MI->getOperand(i: OpNum + 1).isImm() &&
161 MI->getOperand(i: 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
173void 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(s1: Modifier, s2: "arith")) {
178 printOperand(MI, OpNum, STI, O);
179 O << ", ";
180 printOperand(MI, OpNum: OpNum + 1, STI, O);
181 return;
182 }
183
184 if (MI->getOperand(i: OpNum + 1).isImm() &&
185 MI->getOperand(i: OpNum + 1).getImm() == 0) {
186 // don't print "+0"
187 } else {
188 printOperand(MI, OpNum: OpNum + 1, STI, O);
189 }
190 O << "(";
191 if (MI->getOperand(i: OpNum).isReg())
192 printOperand(MI, OpNum, STI, O);
193 O << ")";
194}
195
196void VEInstPrinter::printMImmOperand(const MCInst *MI, int OpNum,
197 const MCSubtargetInfo &STI,
198 raw_ostream &O) {
199 int MImm = (int)MI->getOperand(i: OpNum).getImm() & 0x7f;
200 if (MImm > 63)
201 O << "(" << MImm - 64 << ")0";
202 else
203 O << "(" << MImm << ")1";
204}
205
206void VEInstPrinter::printCCOperand(const MCInst *MI, int OpNum,
207 const MCSubtargetInfo &STI, raw_ostream &O) {
208 int CC = (int)MI->getOperand(i: OpNum).getImm();
209 O << VECondCodeToString(CC: (VECC::CondCode)CC);
210}
211
212void VEInstPrinter::printRDOperand(const MCInst *MI, int OpNum,
213 const MCSubtargetInfo &STI, raw_ostream &O) {
214 int RD = (int)MI->getOperand(i: OpNum).getImm();
215 O << VERDToString(R: (VERD::RoundingMode)RD);
216}
217