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 "MCTargetDesc/X86MCTargetDesc.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 <map> 26 using namespace llvm; 27 28 // Include the auto-generated portion of the assembly writer. 29 #define GET_INSTRUCTION_NAME 30 #define PRINT_ALIAS_INSTR 31 #include "X86GenAsmWriter.inc" 32 33 X86ATTInstPrinter::X86ATTInstPrinter(const MCAsmInfo &MAI) 34 : MCInstPrinter(MAI) { 35 } 36 37 void X86ATTInstPrinter::printRegName(raw_ostream &OS, 38 unsigned RegNo) const { 39 OS << '%' << getRegisterName(RegNo); 40 } 41 42 void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 43 StringRef Annot) { 44 // Try to print any aliases first. 45 if (!printAliasInstr(MI, OS)) 46 printInstruction(MI, OS); 47 48 // If verbose assembly is enabled, we can print some informative comments. 49 if (CommentStream) { 50 printAnnotation(OS, Annot); 51 EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); 52 } 53 } 54 55 StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const { 56 return getInstructionName(Opcode); 57 } 58 59 void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op, 60 raw_ostream &O) { 61 switch (MI->getOperand(Op).getImm()) { 62 default: assert(0 && "Invalid ssecc argument!"); 63 case 0: O << "eq"; break; 64 case 1: O << "lt"; break; 65 case 2: O << "le"; break; 66 case 3: O << "unord"; break; 67 case 4: O << "neq"; break; 68 case 5: O << "nlt"; break; 69 case 6: O << "nle"; break; 70 case 7: O << "ord"; break; 71 } 72 } 73 74 /// print_pcrel_imm - This is used to print an immediate value that ends up 75 /// being encoded as a pc-relative value (e.g. for jumps and calls). These 76 /// print slightly differently than normal immediates. For example, a $ is not 77 /// emitted. 78 void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo, 79 raw_ostream &O) { 80 const MCOperand &Op = MI->getOperand(OpNo); 81 if (Op.isImm()) 82 // Print this as a signed 32-bit value. 83 O << (int)Op.getImm(); 84 else { 85 assert(Op.isExpr() && "unknown pcrel immediate operand"); 86 O << *Op.getExpr(); 87 } 88 } 89 90 void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 91 raw_ostream &O) { 92 const MCOperand &Op = MI->getOperand(OpNo); 93 if (Op.isReg()) { 94 O << '%' << getRegisterName(Op.getReg()); 95 } else if (Op.isImm()) { 96 // Print X86 immediates as signed values. 97 O << '$' << (int64_t)Op.getImm(); 98 99 if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256)) 100 *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm()); 101 102 } else { 103 assert(Op.isExpr() && "unknown operand kind in printOperand"); 104 O << '$' << *Op.getExpr(); 105 } 106 } 107 108 void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 109 raw_ostream &O) { 110 const MCOperand &BaseReg = MI->getOperand(Op); 111 const MCOperand &IndexReg = MI->getOperand(Op+2); 112 const MCOperand &DispSpec = MI->getOperand(Op+3); 113 const MCOperand &SegReg = MI->getOperand(Op+4); 114 115 // If this has a segment register, print it. 116 if (SegReg.getReg()) { 117 printOperand(MI, Op+4, O); 118 O << ':'; 119 } 120 121 if (DispSpec.isImm()) { 122 int64_t DispVal = DispSpec.getImm(); 123 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 124 O << DispVal; 125 } else { 126 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 127 O << *DispSpec.getExpr(); 128 } 129 130 if (IndexReg.getReg() || BaseReg.getReg()) { 131 O << '('; 132 if (BaseReg.getReg()) 133 printOperand(MI, Op, O); 134 135 if (IndexReg.getReg()) { 136 O << ','; 137 printOperand(MI, Op+2, O); 138 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 139 if (ScaleVal != 1) 140 O << ',' << ScaleVal; 141 } 142 O << ')'; 143 } 144 } 145