//===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This class prints an PPC MCInst to a .s file.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/PPCInstPrinter.h"
#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "PPCInstrInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "asm-printer"

// FIXME: Once the integrated assembler supports full register names, tie this
// to the verbose-asm setting.
static cl::opt<bool>
FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
             cl::desc("Use full register names when printing assembly"));

// Useful for testing purposes. Prints vs{31-63} as v{0-31} respectively.
static cl::opt<bool>
ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false),
             cl::desc("Prints full register names with vs{31-63} as v{0-31}"));

// Prints full register names with percent symbol.
static cl::opt<bool>
FullRegNamesWithPercent("ppc-reg-with-percent-prefix", cl::Hidden,
                        cl::init(false),
                        cl::desc("Prints full register names with percent"));

#define PRINT_ALIAS_INSTR
#include "PPCGenAsmWriter.inc"

void PPCInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
  const char *RegName = getRegisterName(Reg);
  OS << RegName;
}

void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                               StringRef Annot, const MCSubtargetInfo &STI,
                               raw_ostream &O) {
  // Customize printing of the addis instruction on AIX. When an operand is a
  // symbol reference, the instruction syntax is changed to look like a load
  // operation, i.e:
  //     Transform:  addis $rD, $rA, $src --> addis $rD, $src($rA).
  if (TT.isOSAIX() &&
      (MI->getOpcode() == PPC::ADDIS8 || MI->getOpcode() == PPC::ADDIS) &&
      MI->getOperand(2).isExpr()) {
    assert((MI->getOperand(0).isReg() && MI->getOperand(1).isReg()) &&
           "The first and the second operand of an addis instruction"
           " should be registers.");

    assert(isa<MCSymbolRefExpr>(MI->getOperand(2).getExpr()) &&
           "The third operand of an addis instruction should be a symbol "
           "reference expression if it is an expression at all.");

    O << "\taddis ";
    printOperand(MI, 0, STI, O);
    O << ", ";
    printOperand(MI, 2, STI, O);
    O << "(";
    printOperand(MI, 1, STI, O);
    O << ")";
    return;
  }

  // Check if the last operand is an expression with the variant kind
  // VK_PPC_PCREL_OPT. If this is the case then this is a linker optimization
  // relocation and the .reloc directive needs to be added.
  unsigned LastOp = MI->getNumOperands() - 1;
  if (MI->getNumOperands() > 1) {
    const MCOperand &Operand = MI->getOperand(LastOp);
    if (Operand.isExpr()) {
      const MCExpr *Expr = Operand.getExpr();
      const MCSymbolRefExpr *SymExpr =
          static_cast<const MCSymbolRefExpr *>(Expr);

      if (SymExpr && SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT) {
        const MCSymbol &Symbol = SymExpr->getSymbol();
        if (MI->getOpcode() == PPC::PLDpc) {
          printInstruction(MI, Address, STI, O);
          O << "\n";
          Symbol.print(O, &MAI);
          O << ":";
          return;
        } else {
          O << "\t.reloc ";
          Symbol.print(O, &MAI);
          O << "-8,R_PPC64_PCREL_OPT,.-(";
          Symbol.print(O, &MAI);
          O << "-8)\n";
        }
      }
    }
  }

  // Check for slwi/srwi mnemonics.
  if (MI->getOpcode() == PPC::RLWINM) {
    unsigned char SH = MI->getOperand(2).getImm();
    unsigned char MB = MI->getOperand(3).getImm();
    unsigned char ME = MI->getOperand(4).getImm();
    bool useSubstituteMnemonic = false;
    if (SH <= 31 && MB == 0 && ME == (31-SH)) {
      O << "\tslwi "; useSubstituteMnemonic = true;
    }
    if (SH <= 31 && MB == (32-SH) && ME == 31) {
      O << "\tsrwi "; useSubstituteMnemonic = true;
      SH = 32-SH;
    }
    if (useSubstituteMnemonic) {
      printOperand(MI, 0, STI, O);
      O << ", ";
      printOperand(MI, 1, STI, O);
      O << ", " << (unsigned int)SH;

      printAnnotation(O, Annot);
      return;
    }
  }

  if (MI->getOpcode() == PPC::RLDICR ||
      MI->getOpcode() == PPC::RLDICR_32) {
    unsigned char SH = MI->getOperand(2).getImm();
    unsigned char ME = MI->getOperand(3).getImm();
    // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
    if (63-SH == ME) {
      O << "\tsldi ";
      printOperand(MI, 0, STI, O);
      O << ", ";
      printOperand(MI, 1, STI, O);
      O << ", " << (unsigned int)SH;
      printAnnotation(O, Annot);
      return;
    }
  }

  // dcbt[st] is printed manually here because:
  //  1. The assembly syntax is different between embedded and server targets
  //  2. We must print the short mnemonics for TH == 0 because the
  //     embedded/server syntax default will not be stable across assemblers
  //  The syntax for dcbt is:
  //    dcbt ra, rb, th [server]
  //    dcbt th, ra, rb [embedded]
  //  where th can be omitted when it is 0. dcbtst is the same.
  // On AIX, only emit the extended mnemonics for dcbt and dcbtst if
  // the "modern assembler" is available.
  if ((MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) &&
      (!TT.isOSAIX() || STI.getFeatureBits()[PPC::FeatureModernAIXAs])) {
    unsigned char TH = MI->getOperand(0).getImm();
    O << "\tdcbt";
    if (MI->getOpcode() == PPC::DCBTST)
      O << "st";
    if (TH == 16)
      O << "t";
    O << " ";

    bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE];
    if (IsBookE && TH != 0 && TH != 16)
      O << (unsigned int) TH << ", ";

    printOperand(MI, 1, STI, O);
    O << ", ";
    printOperand(MI, 2, STI, O);

    if (!IsBookE && TH != 0 && TH != 16)
      O << ", " << (unsigned int) TH;

    printAnnotation(O, Annot);
    return;
  }

  if (MI->getOpcode() == PPC::DCBF) {
    unsigned char L = MI->getOperand(0).getImm();
    if (!L || L == 1 || L == 3 || L == 4 || L == 6) {
      O << "\tdcb";
      if (L != 6)
        O << "f";
      if (L == 1)
        O << "l";
      if (L == 3)
        O << "lp";
      if (L == 4)
        O << "ps";
      if (L == 6)
        O << "stps";
      O << " ";

      printOperand(MI, 1, STI, O);
      O << ", ";
      printOperand(MI, 2, STI, O);

      printAnnotation(O, Annot);
      return;
    }
  }

  if (!printAliasInstr(MI, Address, STI, O))
    printInstruction(MI, Address, STI, O);
  printAnnotation(O, Annot);
}

void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O,
                                           const char *Modifier) {
  unsigned Code = MI->getOperand(OpNo).getImm();

  if (StringRef(Modifier) == "cc") {
    switch ((PPC::Predicate)Code) {
    case PPC::PRED_LT_MINUS:
    case PPC::PRED_LT_PLUS:
    case PPC::PRED_LT:
      O << "lt";
      return;
    case PPC::PRED_LE_MINUS:
    case PPC::PRED_LE_PLUS:
    case PPC::PRED_LE:
      O << "le";
      return;
    case PPC::PRED_EQ_MINUS:
    case PPC::PRED_EQ_PLUS:
    case PPC::PRED_EQ:
      O << "eq";
      return;
    case PPC::PRED_GE_MINUS:
    case PPC::PRED_GE_PLUS:
    case PPC::PRED_GE:
      O << "ge";
      return;
    case PPC::PRED_GT_MINUS:
    case PPC::PRED_GT_PLUS:
    case PPC::PRED_GT:
      O << "gt";
      return;
    case PPC::PRED_NE_MINUS:
    case PPC::PRED_NE_PLUS:
    case PPC::PRED_NE:
      O << "ne";
      return;
    case PPC::PRED_UN_MINUS:
    case PPC::PRED_UN_PLUS:
    case PPC::PRED_UN:
      O << "un";
      return;
    case PPC::PRED_NU_MINUS:
    case PPC::PRED_NU_PLUS:
    case PPC::PRED_NU:
      O << "nu";
      return;
    case PPC::PRED_BIT_SET:
    case PPC::PRED_BIT_UNSET:
      llvm_unreachable("Invalid use of bit predicate code");
    }
    llvm_unreachable("Invalid predicate code");
  }

  if (StringRef(Modifier) == "pm") {
    switch ((PPC::Predicate)Code) {
    case PPC::PRED_LT:
    case PPC::PRED_LE:
    case PPC::PRED_EQ:
    case PPC::PRED_GE:
    case PPC::PRED_GT:
    case PPC::PRED_NE:
    case PPC::PRED_UN:
    case PPC::PRED_NU:
      return;
    case PPC::PRED_LT_MINUS:
    case PPC::PRED_LE_MINUS:
    case PPC::PRED_EQ_MINUS:
    case PPC::PRED_GE_MINUS:
    case PPC::PRED_GT_MINUS:
    case PPC::PRED_NE_MINUS:
    case PPC::PRED_UN_MINUS:
    case PPC::PRED_NU_MINUS:
      O << "-";
      return;
    case PPC::PRED_LT_PLUS:
    case PPC::PRED_LE_PLUS:
    case PPC::PRED_EQ_PLUS:
    case PPC::PRED_GE_PLUS:
    case PPC::PRED_GT_PLUS:
    case PPC::PRED_NE_PLUS:
    case PPC::PRED_UN_PLUS:
    case PPC::PRED_NU_PLUS:
      O << "+";
      return;
    case PPC::PRED_BIT_SET:
    case PPC::PRED_BIT_UNSET:
      llvm_unreachable("Invalid use of bit predicate code");
    }
    llvm_unreachable("Invalid predicate code");
  }

  assert(StringRef(Modifier) == "reg" &&
         "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
  printOperand(MI, OpNo + 1, STI, O);
}

void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned Code = MI->getOperand(OpNo).getImm();
  if (Code == 2)
    O << "-";
  else if (Code == 3)
    O << "+";
}

void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 1 && "Invalid u1imm argument!");
  O << (unsigned int)Value;
}

void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 3 && "Invalid u2imm argument!");
  O << (unsigned int)Value;
}

void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 8 && "Invalid u3imm argument!");
  O << (unsigned int)Value;
}

void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 15 && "Invalid u4imm argument!");
  O << (unsigned int)Value;
}

void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  int Value = MI->getOperand(OpNo).getImm();
  Value = SignExtend32<5>(Value);
  O << (int)Value;
}

void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value == 0 && "Operand must be zero");
  O << (unsigned int)Value;
}

void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 31 && "Invalid u5imm argument!");
  O << (unsigned int)Value;
}

void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 63 && "Invalid u6imm argument!");
  O << (unsigned int)Value;
}

void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned int Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 127 && "Invalid u7imm argument!");
  O << (unsigned int)Value;
}

// Operands of BUILD_VECTOR are signed and we use this to print operands
// of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
// print as unsigned.
void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  unsigned char Value = MI->getOperand(OpNo).getImm();
  O << (unsigned int)Value;
}

void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  unsigned short Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 1023 && "Invalid u10imm argument!");
  O << (unsigned short)Value;
}

void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  unsigned short Value = MI->getOperand(OpNo).getImm();
  assert(Value <= 4095 && "Invalid u12imm argument!");
  O << (unsigned short)Value;
}

void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  if (MI->getOperand(OpNo).isImm())
    O << (short)MI->getOperand(OpNo).getImm();
  else
    printOperand(MI, OpNo, STI, O);
}

void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  if (MI->getOperand(OpNo).isImm()) {
    long long Value = MI->getOperand(OpNo).getImm();
    assert(isInt<34>(Value) && "Invalid s34imm argument!");
    O << (long long)Value;
  }
  else
    printOperand(MI, OpNo, STI, O);
}

void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  if (MI->getOperand(OpNo).isImm())
    O << (unsigned short)MI->getOperand(OpNo).getImm();
  else
    printOperand(MI, OpNo, STI, O);
}

void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
                                        unsigned OpNo,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  if (!MI->getOperand(OpNo).isImm())
    return printOperand(MI, OpNo, STI, O);
  int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
  if (PrintBranchImmAsAddress) {
    uint64_t Target = Address + Imm;
    if (!TT.isPPC64())
      Target &= 0xffffffff;
    O << formatHex(Target);
  } else {
    // Branches can take an immediate operand. This is used by the branch
    // selection pass to print, for example `.+8` (for ELF) or `$+8` (for AIX)
    // to express an eight byte displacement from the program counter.
    if (!TT.isOSAIX())
      O << ".";
    else
      O << "$";

    if (Imm >= 0)
      O << "+";
    O << Imm;
  }
}

void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  if (!MI->getOperand(OpNo).isImm())
    return printOperand(MI, OpNo, STI, O);

  O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
}

void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
                                 const MCSubtargetInfo &STI, raw_ostream &O) {
  unsigned CCReg = MI->getOperand(OpNo).getReg();
  unsigned RegNo;
  switch (CCReg) {
  default: llvm_unreachable("Unknown CR register");
  case PPC::CR0: RegNo = 0; break;
  case PPC::CR1: RegNo = 1; break;
  case PPC::CR2: RegNo = 2; break;
  case PPC::CR3: RegNo = 3; break;
  case PPC::CR4: RegNo = 4; break;
  case PPC::CR5: RegNo = 5; break;
  case PPC::CR6: RegNo = 6; break;
  case PPC::CR7: RegNo = 7; break;
  }
  O << (0x80 >> RegNo);
}

void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
                                    const MCSubtargetInfo &STI,
                                    raw_ostream &O) {
  printS16ImmOperand(MI, OpNo, STI, O);
  O << '(';
  if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
    O << "0";
  else
    printOperand(MI, OpNo + 1, STI, O);
  O << ')';
}

void PPCInstPrinter::printMemRegImmHash(const MCInst *MI, unsigned OpNo,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  O << MI->getOperand(OpNo).getImm();
  O << '(';
  printOperand(MI, OpNo + 1, STI, O);
  O << ')';
}

void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  printS34ImmOperand(MI, OpNo, STI, O);
  O << '(';
  printImmZeroOperand(MI, OpNo + 1, STI, O);
  O << ')';
}

void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo,
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &O) {
  printS34ImmOperand(MI, OpNo, STI, O);
  O << '(';
  printOperand(MI, OpNo + 1, STI, O);
  O << ')';
}

void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
                                    const MCSubtargetInfo &STI,
                                    raw_ostream &O) {
  // When used as the base register, r0 reads constant zero rather than
  // the value contained in the register.  For this reason, the darwin
  // assembler requires that we print r0 as 0 (no r) when used as the base.
  if (MI->getOperand(OpNo).getReg() == PPC::R0)
    O << "0";
  else
    printOperand(MI, OpNo, STI, O);
  O << ", ";
  printOperand(MI, OpNo + 1, STI, O);
}

void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
                                  const MCSubtargetInfo &STI, raw_ostream &O) {
  // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
  // come at the _end_ of the expression.
  const MCOperand &Op = MI->getOperand(OpNo);
  const MCSymbolRefExpr *RefExp = nullptr;
  const MCConstantExpr *ConstExp = nullptr;
  if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Op.getExpr())) {
    RefExp = cast<MCSymbolRefExpr>(BinExpr->getLHS());
    ConstExp = cast<MCConstantExpr>(BinExpr->getRHS());
  } else
    RefExp = cast<MCSymbolRefExpr>(Op.getExpr());

  O << RefExp->getSymbol().getName();
  // The variant kind VK_PPC_NOTOC needs to be handled as a special case
  // because we do not want the assembly to print out the @notoc at the
  // end like __tls_get_addr(x@tlsgd)@notoc. Instead we want it to look
  // like __tls_get_addr@notoc(x@tlsgd).
  if (RefExp->getKind() == MCSymbolRefExpr::VK_PPC_NOTOC)
    O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
  O << '(';
  printOperand(MI, OpNo + 1, STI, O);
  O << ')';
  if (RefExp->getKind() != MCSymbolRefExpr::VK_None &&
      RefExp->getKind() != MCSymbolRefExpr::VK_PPC_NOTOC)
    O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
  if (ConstExp != nullptr)
    O << '+' << ConstExp->getValue();
}

/// showRegistersWithPercentPrefix - Check if this register name should be
/// printed with a percentage symbol as prefix.
bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const {
  if (!FullRegNamesWithPercent || TT.getOS() == Triple::AIX)
    return false;

  switch (RegName[0]) {
  default:
    return false;
  case 'r':
  case 'f':
  case 'q':
  case 'v':
  case 'c':
    return true;
  }
}

/// getVerboseConditionalRegName - This method expands the condition register
/// when requested explicitly or targetting Darwin.
const char *PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum,
                                                       unsigned RegEncoding)
                                                       const {
  if (!FullRegNames)
    return nullptr;
  if (RegNum < PPC::CR0EQ || RegNum > PPC::CR7UN)
    return nullptr;
  const char *CRBits[] = {
    "lt", "gt", "eq", "un",
    "4*cr1+lt", "4*cr1+gt", "4*cr1+eq", "4*cr1+un",
    "4*cr2+lt", "4*cr2+gt", "4*cr2+eq", "4*cr2+un",
    "4*cr3+lt", "4*cr3+gt", "4*cr3+eq", "4*cr3+un",
    "4*cr4+lt", "4*cr4+gt", "4*cr4+eq", "4*cr4+un",
    "4*cr5+lt", "4*cr5+gt", "4*cr5+eq", "4*cr5+un",
    "4*cr6+lt", "4*cr6+gt", "4*cr6+eq", "4*cr6+un",
    "4*cr7+lt", "4*cr7+gt", "4*cr7+eq", "4*cr7+un"
  };
  return CRBits[RegEncoding];
}

// showRegistersWithPrefix - This method determines whether registers
// should be number-only or include the prefix.
bool PPCInstPrinter::showRegistersWithPrefix() const {
  return FullRegNamesWithPercent || FullRegNames;
}

void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
                                  const MCSubtargetInfo &STI, raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNo);
  if (Op.isReg()) {
    unsigned Reg = Op.getReg();
    if (!ShowVSRNumsAsVR)
      Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()),
                                              Reg, OpNo);

    const char *RegName;
    RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg));
    if (RegName == nullptr)
     RegName = getRegisterName(Reg);
    if (showRegistersWithPercentPrefix(RegName))
      O << "%";
    if (!showRegistersWithPrefix())
      RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);

    O << RegName;
    return;
  }

  if (Op.isImm()) {
    O << Op.getImm();
    return;
  }

  assert(Op.isExpr() && "unknown operand kind in printOperand");
  Op.getExpr()->print(O, &MAI);
}
