llvm.org GIT mirror llvm / release_35 lib / Target / X86 / InstPrinter / X86ATTInstPrinter.cpp
release_35

Tree @release_35 (Download .tar.gz)

X86ATTInstPrinter.cpp @release_35

fadc83c
 
 
 
 
 
 
 
 
 
 
 
 
 
cae05cb
4e9485d
ed5e355
d04a8d4
af76e59
8c2eebe
d04a8d4
7c0b3c1
cef670a
ab7c09b
5d672cf
7184781
44dcfd3
fadc83c
 
42e8630
 
d5fb790
44dcfd3
d5fb790
44dcfd3
cde4ce4
 
e1d4a88
 
 
6e03294
 
98c5dda
 
4e9485d
 
 
 
 
 
721ef66
 
c6df988
5bd1b81
b80d571
 
 
6aa928d
b80d571
6aa928d
35c33bd
44dcfd3
35c33bd
 
ac0740f
 
6d1263a
f602040
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ac0740f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f602040
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d5fb790
 
 
3062a31
 
1f044d4
3062a31
 
 
 
 
 
 
35c6889
ffc0574
 
 
35c6889
 
7680e73
 
14ccc90
f92c95f
 
b80d571
 
 
 
 
44c8e34
b80d571
 
 
 
 
f92c95f
7680e73
 
35c33bd
 
f38c03a
 
e1d4a88
f38c03a
d5705fe
e1d4a88
14ccc90
e1d4a88
5bd1b81
5d672cf
41a9649
5bd1b81
f92c95f
 
e1d4a88
 
 
f38c03a
d5fb790
 
599b531
 
7e18b99
 
 
 
5bd1b81
e1d4a88
3ed0316
599b531
 
7e18b99
599b531
 
5bd1b81
f38c03a
 
 
14ccc90
f38c03a
3de47b8
8cb9a3b
f38c03a
5bd1b81
f38c03a
 
 
7e18b99
5bd1b81
f38c03a
 
7e18b99
 
3ed0316
e1d4a88
5bd1b81
14ccc90
5bd1b81
3ed0316
f38c03a
 
 
3ed0316
e1d4a88
d5fb790
a4959f3
db9fa46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ccbfd5b
 
 
 
 
 
 
 
 
 
 
a4959f3
 
 
85026d9
a4959f3
 
 
85026d9
 
 
 
 
 
a4959f3
 
 
 
 
 
 
 
 
//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file includes code for rendering MCInst instances as AT&T-style
// assembly.
//
//===----------------------------------------------------------------------===//

#include "X86ATTInstPrinter.h"
#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "X86InstComments.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include <map>
using namespace llvm;

#define DEBUG_TYPE "asm-printer"

// Include the auto-generated portion of the assembly writer.
#define PRINT_ALIAS_INSTR
#include "X86GenAsmWriter.inc"

void X86ATTInstPrinter::printRegName(raw_ostream &OS,
                                     unsigned RegNo) const {
  OS << markup("<reg:")
     << '%' << getRegisterName(RegNo)
     << markup(">");
}

void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
                                  StringRef Annot) {
  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
  uint64_t TSFlags = Desc.TSFlags;

  if (TSFlags & X86II::LOCK)
    OS << "\tlock\n";

  // Try to print any aliases first.
  if (!printAliasInstr(MI, OS))
    printInstruction(MI, OS);

  // Next always print the annotation.
  printAnnotation(OS, Annot);

  // If verbose assembly is enabled, we can print some informative comments.
  if (CommentStream)
    EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
}

void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
                                   raw_ostream &O) {
  int64_t Imm = MI->getOperand(Op).getImm() & 0xf;
  switch (Imm) {
  default: llvm_unreachable("Invalid ssecc argument!");
  case    0: O << "eq"; break;
  case    1: O << "lt"; break;
  case    2: O << "le"; break;
  case    3: O << "unord"; break;
  case    4: O << "neq"; break;
  case    5: O << "nlt"; break;
  case    6: O << "nle"; break;
  case    7: O << "ord"; break;
  case    8: O << "eq_uq"; break;
  case    9: O << "nge"; break;
  case  0xa: O << "ngt"; break;
  case  0xb: O << "false"; break;
  case  0xc: O << "neq_oq"; break;
  case  0xd: O << "ge"; break;
  case  0xe: O << "gt"; break;
  case  0xf: O << "true"; break;
  }
}

void X86ATTInstPrinter::printAVXCC(const MCInst *MI, unsigned Op,
                                   raw_ostream &O) {
  int64_t Imm = MI->getOperand(Op).getImm() & 0x1f;
  switch (Imm) {
  default: llvm_unreachable("Invalid avxcc argument!");
  case    0: O << "eq"; break;
  case    1: O << "lt"; break;
  case    2: O << "le"; break;
  case    3: O << "unord"; break;
  case    4: O << "neq"; break;
  case    5: O << "nlt"; break;
  case    6: O << "nle"; break;
  case    7: O << "ord"; break;
  case    8: O << "eq_uq"; break;
  case    9: O << "nge"; break;
  case  0xa: O << "ngt"; break;
  case  0xb: O << "false"; break;
  case  0xc: O << "neq_oq"; break;
  case  0xd: O << "ge"; break;
  case  0xe: O << "gt"; break;
  case  0xf: O << "true"; break;
  case 0x10: O << "eq_os"; break;
  case 0x11: O << "lt_oq"; break;
  case 0x12: O << "le_oq"; break;
  case 0x13: O << "unord_s"; break;
  case 0x14: O << "neq_us"; break;
  case 0x15: O << "nlt_uq"; break;
  case 0x16: O << "nle_uq"; break;
  case 0x17: O << "ord_s"; break;
  case 0x18: O << "eq_us"; break;
  case 0x19: O << "nge_uq"; break;
  case 0x1a: O << "ngt_uq"; break;
  case 0x1b: O << "false_os"; break;
  case 0x1c: O << "neq_os"; break;
  case 0x1d: O << "ge_oq"; break;
  case 0x1e: O << "gt_oq"; break;
  case 0x1f: O << "true_us"; break;
  }
}

void X86ATTInstPrinter::printRoundingControl(const MCInst *MI, unsigned Op,
                                   raw_ostream &O) {
  int64_t Imm = MI->getOperand(Op).getImm() & 0x3;
  switch (Imm) {
  case 0: O << "{rn-sae}"; break;
  case 1: O << "{rd-sae}"; break;
  case 2: O << "{ru-sae}"; break;
  case 3: O << "{rz-sae}"; break;
  }
}
/// printPCRelImm - This is used to print an immediate value that ends up
/// being encoded as a pc-relative value (e.g. for jumps and calls).  These
/// print slightly differently than normal immediates.  For example, a $ is not
/// emitted.
void X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
                                      raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNo);
  if (Op.isImm())
    O << formatImm(Op.getImm());
  else {
    assert(Op.isExpr() && "unknown pcrel immediate operand");
    // If a symbolic branch target was added as a constant expression then print
    // that address in hex.
    const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
    int64_t Address;
    if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
      O << formatHex((uint64_t)Address);
    }
    else {
      // Otherwise, just print the expression.
      O << *Op.getExpr();
    }
  }
}

void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
                                     raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNo);
  if (Op.isReg()) {
    printRegName(O, Op.getReg());
  } else if (Op.isImm()) {
    // Print X86 immediates as signed values.
    O << markup("<imm:")
      << '$' << formatImm((int64_t)Op.getImm())
      << markup(">");

    if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
      *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());

  } else {
    assert(Op.isExpr() && "unknown operand kind in printOperand");
    O << markup("<imm:")
      << '$' << *Op.getExpr()
      << markup(">");
  }
}

void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
                                          raw_ostream &O) {
  const MCOperand &BaseReg  = MI->getOperand(Op+X86::AddrBaseReg);
  const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
  const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
  const MCOperand &SegReg = MI->getOperand(Op+X86::AddrSegmentReg);

  O << markup("<mem:");

  // If this has a segment register, print it.
  if (SegReg.getReg()) {
    printOperand(MI, Op+X86::AddrSegmentReg, O);
    O << ':';
  }

  if (DispSpec.isImm()) {
    int64_t DispVal = DispSpec.getImm();
    if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
      O << formatImm(DispVal);
  } else {
    assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
    O << *DispSpec.getExpr();
  }

  if (IndexReg.getReg() || BaseReg.getReg()) {
    O << '(';
    if (BaseReg.getReg())
      printOperand(MI, Op+X86::AddrBaseReg, O);

    if (IndexReg.getReg()) {
      O << ',';
      printOperand(MI, Op+X86::AddrIndexReg, O);
      unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
      if (ScaleVal != 1) {
        O << ','
          << markup("<imm:")
          << ScaleVal // never printed in hex.
          << markup(">");
      }
    }
    O << ')';
  }

  O << markup(">");
}

void X86ATTInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op,
                                    raw_ostream &O) {
  const MCOperand &SegReg = MI->getOperand(Op+1);

  O << markup("<mem:");

  // If this has a segment register, print it.
  if (SegReg.getReg()) {
    printOperand(MI, Op+1, O);
    O << ':';
  }

  O << "(";
  printOperand(MI, Op, O);
  O << ")";

  O << markup(">");
}

void X86ATTInstPrinter::printDstIdx(const MCInst *MI, unsigned Op,
                                    raw_ostream &O) {
  O << markup("<mem:");

  O << "%es:(";
  printOperand(MI, Op, O);
  O << ")";

  O << markup(">");
}

void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
                                       raw_ostream &O) {
  const MCOperand &DispSpec = MI->getOperand(Op);
  const MCOperand &SegReg = MI->getOperand(Op+1);

  O << markup("<mem:");

  // If this has a segment register, print it.
  if (SegReg.getReg()) {
    printOperand(MI, Op+1, O);
    O << ':';
  }

  if (DispSpec.isImm()) {
    O << formatImm(DispSpec.getImm());
  } else {
    assert(DispSpec.isExpr() && "non-immediate displacement?");
    O << *DispSpec.getExpr();
  }

  O << markup(">");
}