X86ATTInstPrinter.cpp revision 218885
1218885Sdim//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file includes code for rendering MCInst instances as AT&T-style 11218885Sdim// assembly. 12218885Sdim// 13218885Sdim//===----------------------------------------------------------------------===// 14218885Sdim 15218885Sdim#define DEBUG_TYPE "asm-printer" 16218885Sdim#include "X86ATTInstPrinter.h" 17218885Sdim#include "X86InstComments.h" 18218885Sdim#include "llvm/MC/MCInst.h" 19218885Sdim#include "llvm/MC/MCAsmInfo.h" 20218885Sdim#include "llvm/MC/MCExpr.h" 21218885Sdim#include "llvm/Support/ErrorHandling.h" 22218885Sdim#include "llvm/Support/Format.h" 23218885Sdim#include "llvm/Support/FormattedStream.h" 24218885Sdim#include "X86GenInstrNames.inc" 25218885Sdimusing namespace llvm; 26218885Sdim 27218885Sdim// Include the auto-generated portion of the assembly writer. 28218885Sdim#define GET_INSTRUCTION_NAME 29218885Sdim#include "X86GenAsmWriter.inc" 30218885Sdim 31218885Sdimvoid X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) { 32218885Sdim printInstruction(MI, OS); 33218885Sdim 34218885Sdim // If verbose assembly is enabled, we can print some informative comments. 35218885Sdim if (CommentStream) 36218885Sdim EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); 37218885Sdim} 38218885SdimStringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const { 39218885Sdim return getInstructionName(Opcode); 40218885Sdim} 41218885Sdim 42218885Sdim 43218885Sdimvoid X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op, 44218885Sdim raw_ostream &O) { 45218885Sdim switch (MI->getOperand(Op).getImm()) { 46218885Sdim default: assert(0 && "Invalid ssecc argument!"); 47218885Sdim case 0: O << "eq"; break; 48218885Sdim case 1: O << "lt"; break; 49218885Sdim case 2: O << "le"; break; 50218885Sdim case 3: O << "unord"; break; 51218885Sdim case 4: O << "neq"; break; 52218885Sdim case 5: O << "nlt"; break; 53218885Sdim case 6: O << "nle"; break; 54218885Sdim case 7: O << "ord"; break; 55218885Sdim } 56218885Sdim} 57218885Sdim 58218885Sdim/// print_pcrel_imm - This is used to print an immediate value that ends up 59218885Sdim/// being encoded as a pc-relative value (e.g. for jumps and calls). These 60218885Sdim/// print slightly differently than normal immediates. For example, a $ is not 61218885Sdim/// emitted. 62218885Sdimvoid X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo, 63218885Sdim raw_ostream &O) { 64218885Sdim const MCOperand &Op = MI->getOperand(OpNo); 65218885Sdim if (Op.isImm()) 66218885Sdim // Print this as a signed 32-bit value. 67218885Sdim O << (int)Op.getImm(); 68218885Sdim else { 69218885Sdim assert(Op.isExpr() && "unknown pcrel immediate operand"); 70218885Sdim O << *Op.getExpr(); 71218885Sdim } 72218885Sdim} 73218885Sdim 74218885Sdimvoid X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 75218885Sdim raw_ostream &O) { 76218885Sdim const MCOperand &Op = MI->getOperand(OpNo); 77218885Sdim if (Op.isReg()) { 78218885Sdim O << '%' << getRegisterName(Op.getReg()); 79218885Sdim } else if (Op.isImm()) { 80218885Sdim O << '$' << Op.getImm(); 81218885Sdim 82218885Sdim if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256)) 83218885Sdim *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm()); 84218885Sdim 85218885Sdim } else { 86218885Sdim assert(Op.isExpr() && "unknown operand kind in printOperand"); 87218885Sdim O << '$' << *Op.getExpr(); 88218885Sdim } 89218885Sdim} 90218885Sdim 91218885Sdimvoid X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 92218885Sdim raw_ostream &O) { 93218885Sdim const MCOperand &BaseReg = MI->getOperand(Op); 94218885Sdim const MCOperand &IndexReg = MI->getOperand(Op+2); 95218885Sdim const MCOperand &DispSpec = MI->getOperand(Op+3); 96218885Sdim const MCOperand &SegReg = MI->getOperand(Op+4); 97218885Sdim 98218885Sdim // If this has a segment register, print it. 99218885Sdim if (SegReg.getReg()) { 100218885Sdim printOperand(MI, Op+4, O); 101218885Sdim O << ':'; 102218885Sdim } 103218885Sdim 104218885Sdim if (DispSpec.isImm()) { 105218885Sdim int64_t DispVal = DispSpec.getImm(); 106218885Sdim if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 107218885Sdim O << DispVal; 108218885Sdim } else { 109218885Sdim assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 110218885Sdim O << *DispSpec.getExpr(); 111218885Sdim } 112218885Sdim 113218885Sdim if (IndexReg.getReg() || BaseReg.getReg()) { 114218885Sdim O << '('; 115218885Sdim if (BaseReg.getReg()) 116218885Sdim printOperand(MI, Op, O); 117218885Sdim 118218885Sdim if (IndexReg.getReg()) { 119218885Sdim O << ','; 120218885Sdim printOperand(MI, Op+2, O); 121218885Sdim unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 122218885Sdim if (ScaleVal != 1) 123218885Sdim O << ',' << ScaleVal; 124218885Sdim } 125218885Sdim O << ')'; 126218885Sdim } 127218885Sdim} 128