text: //===-- 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.
  //
  //===----------------------------------------------------------------------===//
  
  #include "SystemZInstPrinter.h"
  #include "llvm/MC/MCExpr.h"
  #include "llvm/MC/MCInstrInfo.h"
  #include "llvm/Support/raw_ostream.h"
  
  using namespace llvm;
  
  #define DEBUG_TYPE "asm-printer"
  
  #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::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];
  }
  