X86IntelInstPrinter.cpp revision 218893
1//===-- X86IntelInstPrinter.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 "X86IntelInstPrinter.h" 17#include "X86InstComments.h" 18#include "llvm/MC/MCInst.h" 19#include "llvm/MC/MCAsmInfo.h" 20#include "llvm/MC/MCExpr.h" 21#include "llvm/Support/ErrorHandling.h" 22#include "llvm/Support/FormattedStream.h" 23#include "X86GenInstrNames.inc" 24#include <cctype> 25using namespace llvm; 26 27// Include the auto-generated portion of the assembly writer. 28#define GET_INSTRUCTION_NAME 29#include "X86GenAsmWriter1.inc" 30 31void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) { 32 printInstruction(MI, OS); 33 34 // If verbose assembly is enabled, we can print some informative comments. 35 if (CommentStream) 36 EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); 37} 38StringRef X86IntelInstPrinter::getOpcodeName(unsigned Opcode) const { 39 return getInstructionName(Opcode); 40} 41 42void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op, 43 raw_ostream &O) { 44 switch (MI->getOperand(Op).getImm()) { 45 default: assert(0 && "Invalid ssecc argument!"); 46 case 0: O << "eq"; break; 47 case 1: O << "lt"; break; 48 case 2: O << "le"; break; 49 case 3: O << "unord"; break; 50 case 4: O << "neq"; break; 51 case 5: O << "nlt"; break; 52 case 6: O << "nle"; break; 53 case 7: O << "ord"; break; 54 } 55} 56 57/// print_pcrel_imm - This is used to print an immediate value that ends up 58/// being encoded as a pc-relative value. 59void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo, 60 raw_ostream &O) { 61 const MCOperand &Op = MI->getOperand(OpNo); 62 if (Op.isImm()) 63 O << Op.getImm(); 64 else { 65 assert(Op.isExpr() && "unknown pcrel immediate operand"); 66 O << *Op.getExpr(); 67 } 68} 69 70static void PrintRegName(raw_ostream &O, StringRef RegName) { 71 for (unsigned i = 0, e = RegName.size(); i != e; ++i) 72 O << (char)toupper(RegName[i]); 73} 74 75void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 76 raw_ostream &O) { 77 const MCOperand &Op = MI->getOperand(OpNo); 78 if (Op.isReg()) { 79 PrintRegName(O, getRegisterName(Op.getReg())); 80 } else if (Op.isImm()) { 81 O << Op.getImm(); 82 } else { 83 assert(Op.isExpr() && "unknown operand kind in printOperand"); 84 O << *Op.getExpr(); 85 } 86} 87 88void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 89 raw_ostream &O) { 90 const MCOperand &BaseReg = MI->getOperand(Op); 91 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 92 const MCOperand &IndexReg = MI->getOperand(Op+2); 93 const MCOperand &DispSpec = MI->getOperand(Op+3); 94 const MCOperand &SegReg = MI->getOperand(Op+4); 95 96 // If this has a segment register, print it. 97 if (SegReg.getReg()) { 98 printOperand(MI, Op+4, O); 99 O << ':'; 100 } 101 102 O << '['; 103 104 bool NeedPlus = false; 105 if (BaseReg.getReg()) { 106 printOperand(MI, Op, O); 107 NeedPlus = true; 108 } 109 110 if (IndexReg.getReg()) { 111 if (NeedPlus) O << " + "; 112 if (ScaleVal != 1) 113 O << ScaleVal << '*'; 114 printOperand(MI, Op+2, O); 115 NeedPlus = true; 116 } 117 118 119 if (!DispSpec.isImm()) { 120 if (NeedPlus) O << " + "; 121 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 122 O << *DispSpec.getExpr(); 123 } else { 124 int64_t DispVal = DispSpec.getImm(); 125 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { 126 if (NeedPlus) { 127 if (DispVal > 0) 128 O << " + "; 129 else { 130 O << " - "; 131 DispVal = -DispVal; 132 } 133 } 134 O << DispVal; 135 } 136 } 137 138 O << ']'; 139} 140