//===-- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax ===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "asm-printer" #include "SystemZInstPrinter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; #include "SystemZGenAsmWriter.inc" void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp, unsigned Index, raw_ostream &O) { O << Disp; if (Base) { O << '('; if (Index) O << '%' << getRegisterName(Index) << ','; O << '%' << getRegisterName(Base) << ')'; } else assert(!Index && "Shouldn't have an index without a base"); } void SystemZInstPrinter::printOperand(const MCOperand &MO, raw_ostream &O) { if (MO.isReg()) O << '%' << getRegisterName(MO.getReg()); else if (MO.isImm()) O << MO.getImm(); else if (MO.isExpr()) O << *MO.getExpr(); else llvm_unreachable("Invalid operand"); } void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) { printInstruction(MI, O); printAnnotation(O, Annot); } void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { O << '%' << getRegisterName(RegNo); } void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isUInt<4>(Value) && "Invalid u4imm argument"); O << Value; } void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isUInt<6>(Value) && "Invalid u6imm argument"); O << Value; } void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isInt<8>(Value) && "Invalid s8imm argument"); O << Value; } void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isUInt<8>(Value) && "Invalid u8imm argument"); O << Value; } void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isInt<16>(Value) && "Invalid s16imm argument"); O << Value; } void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isUInt<16>(Value) && "Invalid u16imm argument"); O << Value; } void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isInt<32>(Value) && "Invalid s32imm argument"); O << Value; } void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { int64_t Value = MI->getOperand(OpNum).getImm(); assert(isUInt<32>(Value) && "Invalid u32imm argument"); O << Value; } void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum, raw_ostream &O) { uint64_t Value = MI->getOperand(OpNum).getImm(); assert(Value < 16 && "Invalid access register number"); O << "%a" << (unsigned int)Value; } void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum, raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); if (MO.isImm()) { O << "0x"; O.write_hex(MO.getImm()); } else O << *MO.getExpr(); } void SystemZInstPrinter::printCallOperand(const MCInst *MI, int OpNum, raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNum); if (MO.isImm()) { O << "0x"; O.write_hex(MO.getImm()); } else { O << *MO.getExpr(); O << "@PLT"; } } void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum, raw_ostream &O) { printOperand(MI->getOperand(OpNum), O); } void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O) { printAddress(MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1).getImm(), 0, O); } void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O) { printAddress(MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1).getImm(), MI->getOperand(OpNum + 2).getReg(), O); } void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O) { unsigned Base = MI->getOperand(OpNum).getReg(); uint64_t Disp = MI->getOperand(OpNum + 1).getImm(); uint64_t Length = MI->getOperand(OpNum + 2).getImm(); O << Disp << '(' << Length; if (Base) O << ",%" << getRegisterName(Base); O << ')'; } void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum, raw_ostream &O) { static const char *const CondNames[] = { "o", "h", "nle", "l", "nhe", "lh", "ne", "e", "nlh", "he", "nl", "le", "nh", "no" }; uint64_t Imm = MI->getOperand(OpNum).getImm(); assert(Imm > 0 && Imm < 15 && "Invalid condition"); O << CondNames[Imm - 1]; }