X86ATTInstPrinter.cpp revision 249423
150477Speter//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===//
22729Sdfr//
32729Sdfr//                     The LLVM Compiler Infrastructure
42729Sdfr//
52729Sdfr// This file is distributed under the University of Illinois Open Source
62729Sdfr// License. See LICENSE.TXT for details.
72729Sdfr//
82729Sdfr//===----------------------------------------------------------------------===//
92729Sdfr//
102729Sdfr// This file includes code for rendering MCInst instances as AT&T-style
112729Sdfr// assembly.
122729Sdfr//
132729Sdfr//===----------------------------------------------------------------------===//
142729Sdfr
152729Sdfr#define DEBUG_TYPE "asm-printer"
162729Sdfr#include "X86ATTInstPrinter.h"
172729Sdfr#include "MCTargetDesc/X86BaseInfo.h"
182729Sdfr#include "MCTargetDesc/X86MCTargetDesc.h"
192729Sdfr#include "X86InstComments.h"
202729Sdfr#include "llvm/MC/MCAsmInfo.h"
212729Sdfr#include "llvm/MC/MCExpr.h"
2259839Speter#include "llvm/MC/MCInst.h"
2359839Speter#include "llvm/MC/MCInstrInfo.h"
242729Sdfr#include "llvm/MC/MCRegisterInfo.h"
252729Sdfr#include "llvm/Support/ErrorHandling.h"
2611626Sbde#include "llvm/Support/Format.h"
272729Sdfr#include "llvm/Support/FormattedStream.h"
282729Sdfr#include <map>
2982607Sdillonusing namespace llvm;
3082607Sdillon
312729Sdfr// Include the auto-generated portion of the assembly writer.
3269449Salfred#define PRINT_ALIAS_INSTR
3311626Sbde#include "X86GenAsmWriter.inc"
3459839Speter
3559839Spetervoid X86ATTInstPrinter::printRegName(raw_ostream &OS,
3668024Srwatson                                     unsigned RegNo) const {
372729Sdfr  OS << markup("<reg:")
3859839Speter     << '%' << getRegisterName(RegNo)
3959839Speter     << markup(">");
4092723Salfred}
4192723Salfred
4292723Salfredvoid X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
4310358Sjulian                                  StringRef Annot) {
442729Sdfr  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
452729Sdfr  uint64_t TSFlags = Desc.TSFlags;
462729Sdfr
4792723Salfred  if (TSFlags & X86II::LOCK)
482729Sdfr    OS << "\tlock\n";
4911626Sbde
5012819Sphk  // Try to print any aliases first.
5111626Sbde  if (!printAliasInstr(MI, OS))
5211626Sbde    printInstruction(MI, OS);
5311626Sbde
542729Sdfr  // Next always print the annotation.
5559839Speter  printAnnotation(OS, Annot);
5659839Speter
5759839Speter  // If verbose assembly is enabled, we can print some informative comments.
5859839Speter  if (CommentStream)
5959839Speter    EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
6059839Speter}
6159839Speter
6259839Spetervoid X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
6359839Speter                                   raw_ostream &O) {
6459839Speter  int64_t Imm = MI->getOperand(Op).getImm() & 0xf;
6559839Speter  switch (Imm) {
6659839Speter  default: llvm_unreachable("Invalid ssecc argument!");
6759839Speter  case    0: O << "eq"; break;
6859839Speter  case    1: O << "lt"; break;
6959839Speter  case    2: O << "le"; break;
7059839Speter  case    3: O << "unord"; break;
7159839Speter  case    4: O << "neq"; break;
7259839Speter  case    5: O << "nlt"; break;
7359839Speter  case    6: O << "nle"; break;
7459839Speter  case    7: O << "ord"; break;
7559839Speter  case    8: O << "eq_uq"; break;
7659839Speter  case    9: O << "nge"; break;
7759839Speter  case  0xa: O << "ngt"; break;
7859839Speter  case  0xb: O << "false"; break;
7959839Speter  case  0xc: O << "neq_oq"; break;
8059839Speter  case  0xd: O << "ge"; break;
8159839Speter  case  0xe: O << "gt"; break;
8259839Speter  case  0xf: O << "true"; break;
8359839Speter  }
8459839Speter}
8559839Speter
8659839Spetervoid X86ATTInstPrinter::printAVXCC(const MCInst *MI, unsigned Op,
8759839Speter                                   raw_ostream &O) {
8859839Speter  int64_t Imm = MI->getOperand(Op).getImm() & 0x1f;
8959839Speter  switch (Imm) {
9059839Speter  default: llvm_unreachable("Invalid avxcc argument!");
9159839Speter  case    0: O << "eq"; break;
9259839Speter  case    1: O << "lt"; break;
9359839Speter  case    2: O << "le"; break;
9459839Speter  case    3: O << "unord"; break;
9559839Speter  case    4: O << "neq"; break;
9659839Speter  case    5: O << "nlt"; break;
9759839Speter  case    6: O << "nle"; break;
9859839Speter  case    7: O << "ord"; break;
9959839Speter  case    8: O << "eq_uq"; break;
10059839Speter  case    9: O << "nge"; break;
10159839Speter  case  0xa: O << "ngt"; break;
10259839Speter  case  0xb: O << "false"; break;
10359839Speter  case  0xc: O << "neq_oq"; break;
10459839Speter  case  0xd: O << "ge"; break;
10559839Speter  case  0xe: O << "gt"; break;
10659839Speter  case  0xf: O << "true"; break;
10759839Speter  case 0x10: O << "eq_os"; break;
10859839Speter  case 0x11: O << "lt_oq"; break;
10959839Speter  case 0x12: O << "le_oq"; break;
11059839Speter  case 0x13: O << "unord_s"; break;
11159839Speter  case 0x14: O << "neq_us"; break;
11259839Speter  case 0x15: O << "nlt_uq"; break;
11359839Speter  case 0x16: O << "nle_uq"; break;
11459839Speter  case 0x17: O << "ord_s"; break;
11559839Speter  case 0x18: O << "eq_us"; break;
11659839Speter  case 0x19: O << "nge_uq"; break;
11759839Speter  case 0x1a: O << "ngt_uq"; break;
11859839Speter  case 0x1b: O << "false_os"; break;
11959839Speter  case 0x1c: O << "neq_os"; break;
12059839Speter  case 0x1d: O << "ge_oq"; break;
12159839Speter  case 0x1e: O << "gt_oq"; break;
12212819Sphk  case 0x1f: O << "true_us"; break;
12312819Sphk  }
12459839Speter}
12559839Speter
12659839Speter/// printPCRelImm - This is used to print an immediate value that ends up
12759839Speter/// being encoded as a pc-relative value (e.g. for jumps and calls).  These
12859839Speter/// print slightly differently than normal immediates.  For example, a $ is not
1292729Sdfr/// emitted.
13059839Spetervoid X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
13169449Salfred                                      raw_ostream &O) {
1322729Sdfr  const MCOperand &Op = MI->getOperand(OpNo);
1332729Sdfr  if (Op.isImm())
1342729Sdfr    O << formatImm(Op.getImm());
13583765Smr  else {
13683765Smr    assert(Op.isExpr() && "unknown pcrel immediate operand");
13783765Smr    // If a symbolic branch target was added as a constant expression then print
13883765Smr    // that address in hex.
13983765Smr    const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
14059839Speter    int64_t Address;
14159839Speter    if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
14259839Speter      O << "0x";
14359839Speter      O.write_hex(Address);
14459839Speter    }
14559839Speter    else {
14659839Speter      // Otherwise, just print the expression.
14759839Speter      O << *Op.getExpr();
14859839Speter    }
14959839Speter  }
15059839Speter}
15159839Speter
15259839Spetervoid X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1532729Sdfr                                     raw_ostream &O) {
1542729Sdfr  const MCOperand &Op = MI->getOperand(OpNo);
1552729Sdfr  if (Op.isReg()) {
1562729Sdfr    printRegName(O, Op.getReg());
1572729Sdfr  } else if (Op.isImm()) {
1582729Sdfr    // Print X86 immediates as signed values.
1592729Sdfr    O << markup("<imm:")
1602729Sdfr      << '$' << formatImm((int64_t)Op.getImm())
1612729Sdfr      << markup(">");
1622729Sdfr
1632729Sdfr    if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
1642729Sdfr      *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());
1652729Sdfr
1662729Sdfr  } else {
1672729Sdfr    assert(Op.isExpr() && "unknown operand kind in printOperand");
1682729Sdfr    O << markup("<imm:")
1692729Sdfr      << '$' << *Op.getExpr()
1702729Sdfr      << markup(">");
1712729Sdfr  }
1722729Sdfr}
1732729Sdfr
1742729Sdfrvoid X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
1752729Sdfr                                          raw_ostream &O) {
1762729Sdfr  const MCOperand &BaseReg  = MI->getOperand(Op);
1772729Sdfr  const MCOperand &IndexReg = MI->getOperand(Op+2);
1782729Sdfr  const MCOperand &DispSpec = MI->getOperand(Op+3);
1792729Sdfr  const MCOperand &SegReg = MI->getOperand(Op+4);
1802729Sdfr
1812729Sdfr  O << markup("<mem:");
1822729Sdfr
1832729Sdfr  // If this has a segment register, print it.
1842729Sdfr  if (SegReg.getReg()) {
1852729Sdfr    printOperand(MI, Op+4, O);
1862729Sdfr    O << ':';
1872729Sdfr  }
1882729Sdfr
1892729Sdfr  if (DispSpec.isImm()) {
1902729Sdfr    int64_t DispVal = DispSpec.getImm();
1912729Sdfr    if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
1922729Sdfr      O << formatImm(DispVal);
1932729Sdfr  } else {
1942729Sdfr    assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
1952729Sdfr    O << *DispSpec.getExpr();
1962729Sdfr  }
1972729Sdfr
1982729Sdfr  if (IndexReg.getReg() || BaseReg.getReg()) {
1992729Sdfr    O << '(';
2002729Sdfr    if (BaseReg.getReg())
20166085Speter      printOperand(MI, Op, O);
2022729Sdfr
2032729Sdfr    if (IndexReg.getReg()) {
2042729Sdfr      O << ',';
20569449Salfred      printOperand(MI, Op+2, O);
20669449Salfred      unsigned ScaleVal = MI->getOperand(Op+1).getImm();
20769449Salfred      if (ScaleVal != 1) {
20869449Salfred        O << ','
20969449Salfred	  << markup("<imm:")
21069449Salfred          << ScaleVal // never printed in hex.
21169449Salfred	  << markup(">");
21269449Salfred      }
21369449Salfred    }
21469449Salfred    O << ')';
21569449Salfred  }
21669449Salfred
21769449Salfred  O << markup(">");
21869449Salfred}
21969449Salfred