1 //===-- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax ===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "SystemZInstPrinter.h"
11 #include "llvm/MC/MCExpr.h"
12 #include "llvm/MC/MCInstrInfo.h"
13 #include "llvm/Support/raw_ostream.h"
14
15 using namespace llvm;
16
17 #define DEBUG_TYPE "asm-printer"
18
19 #include "SystemZGenAsmWriter.inc"
20
printAddress(unsigned Base,int64_t Disp,unsigned Index,raw_ostream & O)21 void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
22 unsigned Index, raw_ostream &O) {
23 O << Disp;
24 if (Base) {
25 O << '(';
26 if (Index)
27 O << '%' << getRegisterName(Index) << ',';
28 O << '%' << getRegisterName(Base) << ')';
29 } else
30 assert(!Index && "Shouldn't have an index without a base");
31 }
32
printOperand(const MCOperand & MO,raw_ostream & O)33 void SystemZInstPrinter::printOperand(const MCOperand &MO, raw_ostream &O) {
34 if (MO.isReg())
35 O << '%' << getRegisterName(MO.getReg());
36 else if (MO.isImm())
37 O << MO.getImm();
38 else if (MO.isExpr())
39 O << *MO.getExpr();
40 else
41 llvm_unreachable("Invalid operand");
42 }
43
printInst(const MCInst * MI,raw_ostream & O,StringRef Annot)44 void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
45 StringRef Annot) {
46 printInstruction(MI, O);
47 printAnnotation(O, Annot);
48 }
49
printRegName(raw_ostream & O,unsigned RegNo) const50 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
51 O << '%' << getRegisterName(RegNo);
52 }
53
printU4ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)54 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
55 raw_ostream &O) {
56 int64_t Value = MI->getOperand(OpNum).getImm();
57 assert(isUInt<4>(Value) && "Invalid u4imm argument");
58 O << Value;
59 }
60
printU6ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)61 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
62 raw_ostream &O) {
63 int64_t Value = MI->getOperand(OpNum).getImm();
64 assert(isUInt<6>(Value) && "Invalid u6imm argument");
65 O << Value;
66 }
67
printS8ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)68 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
69 raw_ostream &O) {
70 int64_t Value = MI->getOperand(OpNum).getImm();
71 assert(isInt<8>(Value) && "Invalid s8imm argument");
72 O << Value;
73 }
74
printU8ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)75 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
76 raw_ostream &O) {
77 int64_t Value = MI->getOperand(OpNum).getImm();
78 assert(isUInt<8>(Value) && "Invalid u8imm argument");
79 O << Value;
80 }
81
printS16ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)82 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
83 raw_ostream &O) {
84 int64_t Value = MI->getOperand(OpNum).getImm();
85 assert(isInt<16>(Value) && "Invalid s16imm argument");
86 O << Value;
87 }
88
printU16ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)89 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
90 raw_ostream &O) {
91 int64_t Value = MI->getOperand(OpNum).getImm();
92 assert(isUInt<16>(Value) && "Invalid u16imm argument");
93 O << Value;
94 }
95
printS32ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)96 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
97 raw_ostream &O) {
98 int64_t Value = MI->getOperand(OpNum).getImm();
99 assert(isInt<32>(Value) && "Invalid s32imm argument");
100 O << Value;
101 }
102
printU32ImmOperand(const MCInst * MI,int OpNum,raw_ostream & O)103 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
104 raw_ostream &O) {
105 int64_t Value = MI->getOperand(OpNum).getImm();
106 assert(isUInt<32>(Value) && "Invalid u32imm argument");
107 O << Value;
108 }
109
printAccessRegOperand(const MCInst * MI,int OpNum,raw_ostream & O)110 void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum,
111 raw_ostream &O) {
112 uint64_t Value = MI->getOperand(OpNum).getImm();
113 assert(Value < 16 && "Invalid access register number");
114 O << "%a" << (unsigned int)Value;
115 }
116
printPCRelOperand(const MCInst * MI,int OpNum,raw_ostream & O)117 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
118 raw_ostream &O) {
119 const MCOperand &MO = MI->getOperand(OpNum);
120 if (MO.isImm()) {
121 O << "0x";
122 O.write_hex(MO.getImm());
123 } else
124 O << *MO.getExpr();
125 }
126
printOperand(const MCInst * MI,int OpNum,raw_ostream & O)127 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
128 raw_ostream &O) {
129 printOperand(MI->getOperand(OpNum), O);
130 }
131
printBDAddrOperand(const MCInst * MI,int OpNum,raw_ostream & O)132 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
133 raw_ostream &O) {
134 printAddress(MI->getOperand(OpNum).getReg(),
135 MI->getOperand(OpNum + 1).getImm(), 0, O);
136 }
137
printBDXAddrOperand(const MCInst * MI,int OpNum,raw_ostream & O)138 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
139 raw_ostream &O) {
140 printAddress(MI->getOperand(OpNum).getReg(),
141 MI->getOperand(OpNum + 1).getImm(),
142 MI->getOperand(OpNum + 2).getReg(), O);
143 }
144
printBDLAddrOperand(const MCInst * MI,int OpNum,raw_ostream & O)145 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
146 raw_ostream &O) {
147 unsigned Base = MI->getOperand(OpNum).getReg();
148 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
149 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
150 O << Disp << '(' << Length;
151 if (Base)
152 O << ",%" << getRegisterName(Base);
153 O << ')';
154 }
155
printCond4Operand(const MCInst * MI,int OpNum,raw_ostream & O)156 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
157 raw_ostream &O) {
158 static const char *const CondNames[] = {
159 "o", "h", "nle", "l", "nhe", "lh", "ne",
160 "e", "nlh", "he", "nl", "le", "nh", "no"
161 };
162 uint64_t Imm = MI->getOperand(OpNum).getImm();
163 assert(Imm > 0 && Imm < 15 && "Invalid condition");
164 O << CondNames[Imm - 1];
165 }
166