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 #define DEBUG_TYPE "asm-printer" 11 12 #include "SystemZInstPrinter.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCInstrInfo.h" 15 #include "llvm/Support/raw_ostream.h" 16 17 using namespace llvm; 18 19 #include "SystemZGenAsmWriter.inc" 20 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 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 44 void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 45 StringRef Annot) { 46 printInstruction(MI, O); 47 printAnnotation(O, Annot); 48 } 49 50 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { 51 O << '%' << getRegisterName(RegNo); 52 } 53 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 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 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 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 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 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 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 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 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 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 127 void SystemZInstPrinter::printCallOperand(const MCInst *MI, int OpNum, 128 raw_ostream &O) { 129 const MCOperand &MO = MI->getOperand(OpNum); 130 if (MO.isImm()) { 131 O << "0x"; 132 O.write_hex(MO.getImm()); 133 } else { 134 O << *MO.getExpr(); 135 O << "@PLT"; 136 } 137 } 138 139 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum, 140 raw_ostream &O) { 141 printOperand(MI->getOperand(OpNum), O); 142 } 143 144 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum, 145 raw_ostream &O) { 146 printAddress(MI->getOperand(OpNum).getReg(), 147 MI->getOperand(OpNum + 1).getImm(), 0, O); 148 } 149 150 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum, 151 raw_ostream &O) { 152 printAddress(MI->getOperand(OpNum).getReg(), 153 MI->getOperand(OpNum + 1).getImm(), 154 MI->getOperand(OpNum + 2).getReg(), O); 155 } 156 157 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum, 158 raw_ostream &O) { 159 unsigned Base = MI->getOperand(OpNum).getReg(); 160 uint64_t Disp = MI->getOperand(OpNum + 1).getImm(); 161 uint64_t Length = MI->getOperand(OpNum + 2).getImm(); 162 O << Disp << '(' << Length; 163 if (Base) 164 O << ",%" << getRegisterName(Base); 165 O << ')'; 166 } 167 168 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum, 169 raw_ostream &O) { 170 static const char *const CondNames[] = { 171 "o", "h", "nle", "l", "nhe", "lh", "ne", 172 "e", "nlh", "he", "nl", "le", "nh", "no" 173 }; 174 uint64_t Imm = MI->getOperand(OpNum).getImm(); 175 assert(Imm > 0 && Imm < 15 && "Invalid condition"); 176 O << CondNames[Imm - 1]; 177 } 178