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