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