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/MCAsmInfo.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCInst.h"
18#include "llvm/MC/MCRegisterInfo.h"
19#include "llvm/MC/MCSubtargetInfo.h"
20#include "llvm/MC/MCSymbol.h"
21#include "llvm/Support/raw_ostream.h"
22
23using namespace llvm;
24
25#define DEBUG_TYPE "ve-asmprinter"
26
27#define GET_INSTRUCTION_NAME
28#define PRINT_ALIAS_INSTR
29#include "VEGenAsmWriter.inc"
30
31void VEInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {
32 // Generic registers have identical register name among register classes.
33 unsigned AltIdx = VE::AsmName;
34 // Misc registers have each own name, so no use alt-names.
35 if (MRI.getRegClass(i: VE::MISCRegClassID).contains(Reg))
36 AltIdx = VE::NoRegAltName;
37 OS << '%' << getRegisterName(Reg, AltIdx);
38}
39
40void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address,
41 StringRef Annot, const MCSubtargetInfo &STI,
42 raw_ostream &OS) {
43 if (!printAliasInstr(MI, Address, STI, OS))
44 printInstruction(MI, Address, STI, O&: OS);
45 printAnnotation(OS, Annot);
46}
47
48void VEInstPrinter::printOperand(const MCInst *MI, int OpNum,
49 const MCSubtargetInfo &STI, raw_ostream &O) {
50 const MCOperand &MO = MI->getOperand(i: OpNum);
51
52 if (MO.isReg()) {
53 printRegName(OS&: O, Reg: MO.getReg());
54 return;
55 }
56
57 if (MO.isImm()) {
58 // Expects signed 32bit literals.
59 int32_t TruncatedImm = static_cast<int32_t>(MO.getImm());
60 O << TruncatedImm;
61 return;
62 }
63
64 assert(MO.isExpr() && "Unknown operand kind in printOperand");
65 MAI.printExpr(O, *MO.getExpr());
66}
67
68void VEInstPrinter::printMemASXOperand(const MCInst *MI, int OpNum,
69 const MCSubtargetInfo &STI,
70 raw_ostream &O) {
71 if (MI->getOperand(i: OpNum + 2).isImm() &&
72 MI->getOperand(i: OpNum + 2).getImm() == 0) {
73 // don't print "+0"
74 } else {
75 printOperand(MI, OpNum: OpNum + 2, STI, O);
76 }
77 if (MI->getOperand(i: OpNum + 1).isImm() &&
78 MI->getOperand(i: OpNum + 1).getImm() == 0 &&
79 MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
80 if (MI->getOperand(i: OpNum + 2).isImm() &&
81 MI->getOperand(i: OpNum + 2).getImm() == 0) {
82 O << "0";
83 } else {
84 // don't print "+0,+0"
85 }
86 } else {
87 O << "(";
88 if (MI->getOperand(i: OpNum + 1).isImm() &&
89 MI->getOperand(i: OpNum + 1).getImm() == 0) {
90 // don't print "+0"
91 } else {
92 printOperand(MI, OpNum: OpNum + 1, STI, O);
93 }
94 if (MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
95 // don't print "+0"
96 } else {
97 O << ", ";
98 printOperand(MI, OpNum, STI, O);
99 }
100 O << ")";
101 }
102}
103
104void VEInstPrinter::printMemASOperandASX(const MCInst *MI, int OpNum,
105 const MCSubtargetInfo &STI,
106 raw_ostream &O) {
107 if (MI->getOperand(i: OpNum + 1).isImm() &&
108 MI->getOperand(i: OpNum + 1).getImm() == 0) {
109 // don't print "+0"
110 } else {
111 printOperand(MI, OpNum: OpNum + 1, STI, O);
112 }
113 if (MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
114 if (MI->getOperand(i: OpNum + 1).isImm() &&
115 MI->getOperand(i: OpNum + 1).getImm() == 0) {
116 O << "0";
117 } else {
118 // don't print "(0)"
119 }
120 } else {
121 O << "(, ";
122 printOperand(MI, OpNum, STI, O);
123 O << ")";
124 }
125}
126
127void VEInstPrinter::printMemASOperandRRM(const MCInst *MI, int OpNum,
128 const MCSubtargetInfo &STI,
129 raw_ostream &O) {
130 if (MI->getOperand(i: OpNum + 1).isImm() &&
131 MI->getOperand(i: OpNum + 1).getImm() == 0) {
132 // don't print "+0"
133 } else {
134 printOperand(MI, OpNum: OpNum + 1, STI, O);
135 }
136 if (MI->getOperand(i: OpNum).isImm() && MI->getOperand(i: OpNum).getImm() == 0) {
137 if (MI->getOperand(i: OpNum + 1).isImm() &&
138 MI->getOperand(i: OpNum + 1).getImm() == 0) {
139 O << "0";
140 } else {
141 // don't print "(0)"
142 }
143 } else {
144 O << "(";
145 printOperand(MI, OpNum, STI, O);
146 O << ")";
147 }
148}
149
150void VEInstPrinter::printMemASOperandHM(const MCInst *MI, int OpNum,
151 const MCSubtargetInfo &STI,
152 raw_ostream &O) {
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 O << "(";
160 if (MI->getOperand(i: OpNum).isReg())
161 printOperand(MI, OpNum, STI, O);
162 O << ")";
163}
164
165void VEInstPrinter::printMImmOperand(const MCInst *MI, int OpNum,
166 const MCSubtargetInfo &STI,
167 raw_ostream &O) {
168 int MImm = (int)MI->getOperand(i: OpNum).getImm() & 0x7f;
169 if (MImm > 63)
170 O << "(" << MImm - 64 << ")0";
171 else
172 O << "(" << MImm << ")1";
173}
174
175void VEInstPrinter::printCCOperand(const MCInst *MI, int OpNum,
176 const MCSubtargetInfo &STI, raw_ostream &O) {
177 int CC = (int)MI->getOperand(i: OpNum).getImm();
178 O << VECondCodeToString(CC: (VECC::CondCode)CC);
179}
180
181void VEInstPrinter::printRDOperand(const MCInst *MI, int OpNum,
182 const MCSubtargetInfo &STI, raw_ostream &O) {
183 int RD = (int)MI->getOperand(i: OpNum).getImm();
184 O << VERDToString(R: (VERD::RoundingMode)RD);
185}
186