1 //===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "SystemZInstPrinter.h"
11 #include "llvm/MC/MCExpr.h"
12 #include "llvm/MC/MCInst.h"
13 #include "llvm/MC/MCSymbol.h"
14 #include "llvm/Support/Casting.h"
15 #include "llvm/Support/ErrorHandling.h"
16 #include "llvm/Support/MathExtras.h"
17 #include "llvm/Support/raw_ostream.h"
23 #define DEBUG_TYPE "asm-printer"
25 #include "SystemZGenAsmWriter.inc"
27 void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
28 unsigned Index, raw_ostream &O) {
33 O << '%' << getRegisterName(Index);
38 O << '%' << getRegisterName(Base);
43 void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
46 O << '%' << getRegisterName(MO.getReg());
50 MO.getExpr()->print(O, MAI);
52 llvm_unreachable("Invalid operand");
55 void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
57 const MCSubtargetInfo &STI) {
58 printInstruction(MI, O);
59 printAnnotation(O, Annot);
62 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
63 O << '%' << getRegisterName(RegNo);
67 static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
68 int64_t Value = MI->getOperand(OpNum).getImm();
69 assert(isUInt<N>(Value) && "Invalid uimm argument");
74 static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
75 int64_t Value = MI->getOperand(OpNum).getImm();
76 assert(isInt<N>(Value) && "Invalid simm argument");
80 void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
82 printUImmOperand<1>(MI, OpNum, O);
85 void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
87 printUImmOperand<2>(MI, OpNum, O);
90 void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
92 printUImmOperand<3>(MI, OpNum, O);
95 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
97 printUImmOperand<4>(MI, OpNum, O);
100 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
102 printUImmOperand<6>(MI, OpNum, O);
105 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
107 printSImmOperand<8>(MI, OpNum, O);
110 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
112 printUImmOperand<8>(MI, OpNum, O);
115 void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
117 printUImmOperand<12>(MI, OpNum, O);
120 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
122 printSImmOperand<16>(MI, OpNum, O);
125 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
127 printUImmOperand<16>(MI, OpNum, O);
130 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
132 printSImmOperand<32>(MI, OpNum, O);
135 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
137 printUImmOperand<32>(MI, OpNum, O);
140 void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
142 printUImmOperand<48>(MI, OpNum, O);
145 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
147 const MCOperand &MO = MI->getOperand(OpNum);
150 O.write_hex(MO.getImm());
152 MO.getExpr()->print(O, &MAI);
155 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
157 // Output the PC-relative operand.
158 printPCRelOperand(MI, OpNum, O);
160 // Output the TLS marker if present.
161 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
162 const MCOperand &MO = MI->getOperand(OpNum + 1);
163 const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
164 switch (refExp.getKind()) {
165 case MCSymbolRefExpr::VK_TLSGD:
168 case MCSymbolRefExpr::VK_TLSLDM:
172 llvm_unreachable("Unexpected symbol kind");
174 O << refExp.getSymbol().getName();
178 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
180 printOperand(MI->getOperand(OpNum), &MAI, O);
183 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
185 printAddress(MI->getOperand(OpNum).getReg(),
186 MI->getOperand(OpNum + 1).getImm(), 0, O);
189 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
191 printAddress(MI->getOperand(OpNum).getReg(),
192 MI->getOperand(OpNum + 1).getImm(),
193 MI->getOperand(OpNum + 2).getReg(), O);
196 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
198 unsigned Base = MI->getOperand(OpNum).getReg();
199 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
200 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
201 O << Disp << '(' << Length;
203 O << ",%" << getRegisterName(Base);
207 void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
209 unsigned Base = MI->getOperand(OpNum).getReg();
210 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
211 unsigned Length = MI->getOperand(OpNum + 2).getReg();
212 O << Disp << "(%" << getRegisterName(Length);
214 O << ",%" << getRegisterName(Base);
218 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
220 printAddress(MI->getOperand(OpNum).getReg(),
221 MI->getOperand(OpNum + 1).getImm(),
222 MI->getOperand(OpNum + 2).getReg(), O);
225 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
227 static const char *const CondNames[] = {
228 "o", "h", "nle", "l", "nhe", "lh", "ne",
229 "e", "nlh", "he", "nl", "le", "nh", "no"
231 uint64_t Imm = MI->getOperand(OpNum).getImm();
232 assert(Imm > 0 && Imm < 15 && "Invalid condition");
233 O << CondNames[Imm - 1];