X86ATTInstPrinter.cpp revision 221345
1//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file includes code for rendering MCInst instances as AT&T-style 11// assembly. 12// 13//===----------------------------------------------------------------------===// 14 15#define DEBUG_TYPE "asm-printer" 16#include "X86ATTInstPrinter.h" 17#include "X86InstComments.h" 18#include "X86Subtarget.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/MC/MCAsmInfo.h" 21#include "llvm/MC/MCExpr.h" 22#include "llvm/Support/ErrorHandling.h" 23#include "llvm/Support/Format.h" 24#include "llvm/Support/FormattedStream.h" 25#include "X86GenInstrNames.inc" 26#include <map> 27using namespace llvm; 28 29// Include the auto-generated portion of the assembly writer. 30#define GET_INSTRUCTION_NAME 31#define PRINT_ALIAS_INSTR 32#include "X86GenRegisterNames.inc" 33#include "X86GenAsmWriter.inc" 34#undef PRINT_ALIAS_INSTR 35#undef GET_INSTRUCTION_NAME 36 37X86ATTInstPrinter::X86ATTInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) 38 : MCInstPrinter(MAI) { 39 // Initialize the set of available features. 40 setAvailableFeatures(ComputeAvailableFeatures( 41 &TM.getSubtarget<X86Subtarget>())); 42} 43 44void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) { 45 // Try to print any aliases first. 46 if (!printAliasInstr(MI, OS)) 47 printInstruction(MI, OS); 48 49 // If verbose assembly is enabled, we can print some informative comments. 50 if (CommentStream) 51 EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); 52} 53 54StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const { 55 return getInstructionName(Opcode); 56} 57 58void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op, 59 raw_ostream &O) { 60 switch (MI->getOperand(Op).getImm()) { 61 default: assert(0 && "Invalid ssecc argument!"); 62 case 0: O << "eq"; break; 63 case 1: O << "lt"; break; 64 case 2: O << "le"; break; 65 case 3: O << "unord"; break; 66 case 4: O << "neq"; break; 67 case 5: O << "nlt"; break; 68 case 6: O << "nle"; break; 69 case 7: O << "ord"; break; 70 } 71} 72 73/// print_pcrel_imm - This is used to print an immediate value that ends up 74/// being encoded as a pc-relative value (e.g. for jumps and calls). These 75/// print slightly differently than normal immediates. For example, a $ is not 76/// emitted. 77void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo, 78 raw_ostream &O) { 79 const MCOperand &Op = MI->getOperand(OpNo); 80 if (Op.isImm()) 81 // Print this as a signed 32-bit value. 82 O << (int)Op.getImm(); 83 else { 84 assert(Op.isExpr() && "unknown pcrel immediate operand"); 85 O << *Op.getExpr(); 86 } 87} 88 89void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 90 raw_ostream &O) { 91 const MCOperand &Op = MI->getOperand(OpNo); 92 if (Op.isReg()) { 93 O << '%' << getRegisterName(Op.getReg()); 94 } else if (Op.isImm()) { 95 O << '$' << Op.getImm(); 96 97 if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256)) 98 *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm()); 99 100 } else { 101 assert(Op.isExpr() && "unknown operand kind in printOperand"); 102 O << '$' << *Op.getExpr(); 103 } 104} 105 106void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 107 raw_ostream &O) { 108 const MCOperand &BaseReg = MI->getOperand(Op); 109 const MCOperand &IndexReg = MI->getOperand(Op+2); 110 const MCOperand &DispSpec = MI->getOperand(Op+3); 111 const MCOperand &SegReg = MI->getOperand(Op+4); 112 113 // If this has a segment register, print it. 114 if (SegReg.getReg()) { 115 printOperand(MI, Op+4, O); 116 O << ':'; 117 } 118 119 if (DispSpec.isImm()) { 120 int64_t DispVal = DispSpec.getImm(); 121 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 122 O << DispVal; 123 } else { 124 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 125 O << *DispSpec.getExpr(); 126 } 127 128 if (IndexReg.getReg() || BaseReg.getReg()) { 129 O << '('; 130 if (BaseReg.getReg()) 131 printOperand(MI, Op, O); 132 133 if (IndexReg.getReg()) { 134 O << ','; 135 printOperand(MI, Op+2, O); 136 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 137 if (ScaleVal != 1) 138 O << ',' << ScaleVal; 139 } 140 O << ')'; 141 } 142} 143