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 #include "X86ATTInstPrinter.h" 16 #include "MCTargetDesc/X86BaseInfo.h" 17 #include "X86InstComments.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCInstrInfo.h" 21 #include "llvm/MC/MCSubtargetInfo.h" 22 #include "llvm/Support/Casting.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/Format.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include <cassert> 27 #include <cinttypes> 28 #include <cstdint> 29 30 using namespace llvm; 31 32 #define DEBUG_TYPE "asm-printer" 33 34 // Include the auto-generated portion of the assembly writer. 35 #define PRINT_ALIAS_INSTR 36 #include "X86GenAsmWriter.inc" 37 38 void X86ATTInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 39 OS << markup("<reg:") << '%' << getRegisterName(RegNo) << markup(">"); 40 } 41 42 void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 43 StringRef Annot, const MCSubtargetInfo &STI) { 44 // If verbose assembly is enabled, we can print some informative comments. 45 if (CommentStream) 46 HasCustomInstComment = EmitAnyX86InstComments(MI, *CommentStream, MII); 47 48 printInstFlags(MI, OS); 49 50 // Output CALLpcrel32 as "callq" in 64-bit mode. 51 // In Intel annotation it's always emitted as "call". 52 // 53 // TODO: Probably this hack should be redesigned via InstAlias in 54 // InstrInfo.td as soon as Requires clause is supported properly 55 // for InstAlias. 56 if (MI->getOpcode() == X86::CALLpcrel32 && 57 (STI.getFeatureBits()[X86::Mode64Bit])) { 58 OS << "\tcallq\t"; 59 printPCRelImm(MI, 0, OS); 60 } 61 // data16 and data32 both have the same encoding of 0x66. While data32 is 62 // valid only in 16 bit systems, data16 is valid in the rest. 63 // There seems to be some lack of support of the Requires clause that causes 64 // 0x66 to be interpreted as "data16" by the asm printer. 65 // Thus we add an adjustment here in order to print the "right" instruction. 66 else if (MI->getOpcode() == X86::DATA16_PREFIX && 67 STI.getFeatureBits()[X86::Mode16Bit]) { 68 OS << "\tdata32"; 69 } 70 // Try to print any aliases first. 71 else if (!printAliasInstr(MI, OS)) 72 printInstruction(MI, OS); 73 74 // Next always print the annotation. 75 printAnnotation(OS, Annot); 76 } 77 78 void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 79 raw_ostream &O) { 80 const MCOperand &Op = MI->getOperand(OpNo); 81 if (Op.isReg()) { 82 printRegName(O, Op.getReg()); 83 } else if (Op.isImm()) { 84 // Print immediates as signed values. 85 int64_t Imm = Op.getImm(); 86 O << markup("<imm:") << '$' << formatImm(Imm) << markup(">"); 87 88 // TODO: This should be in a helper function in the base class, so it can 89 // be used by other printers. 90 91 // If there are no instruction-specific comments, add a comment clarifying 92 // the hex value of the immediate operand when it isn't in the range 93 // [-256,255]. 94 if (CommentStream && !HasCustomInstComment && (Imm > 255 || Imm < -256)) { 95 // Don't print unnecessary hex sign bits. 96 if (Imm == (int16_t)(Imm)) 97 *CommentStream << format("imm = 0x%" PRIX16 "\n", (uint16_t)Imm); 98 else if (Imm == (int32_t)(Imm)) 99 *CommentStream << format("imm = 0x%" PRIX32 "\n", (uint32_t)Imm); 100 else 101 *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Imm); 102 } 103 } else { 104 assert(Op.isExpr() && "unknown operand kind in printOperand"); 105 O << markup("<imm:") << '$'; 106 Op.getExpr()->print(O, &MAI); 107 O << markup(">"); 108 } 109 } 110 111 void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 112 raw_ostream &O) { 113 const MCOperand &BaseReg = MI->getOperand(Op + X86::AddrBaseReg); 114 const MCOperand &IndexReg = MI->getOperand(Op + X86::AddrIndexReg); 115 const MCOperand &DispSpec = MI->getOperand(Op + X86::AddrDisp); 116 117 O << markup("<mem:"); 118 119 // If this has a segment register, print it. 120 printOptionalSegReg(MI, Op + X86::AddrSegmentReg, O); 121 122 if (DispSpec.isImm()) { 123 int64_t DispVal = DispSpec.getImm(); 124 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 125 O << formatImm(DispVal); 126 } else { 127 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 128 DispSpec.getExpr()->print(O, &MAI); 129 } 130 131 if (IndexReg.getReg() || BaseReg.getReg()) { 132 O << '('; 133 if (BaseReg.getReg()) 134 printOperand(MI, Op + X86::AddrBaseReg, O); 135 136 if (IndexReg.getReg()) { 137 O << ','; 138 printOperand(MI, Op + X86::AddrIndexReg, O); 139 unsigned ScaleVal = MI->getOperand(Op + X86::AddrScaleAmt).getImm(); 140 if (ScaleVal != 1) { 141 O << ',' << markup("<imm:") << ScaleVal // never printed in hex. 142 << markup(">"); 143 } 144 } 145 O << ')'; 146 } 147 148 O << markup(">"); 149 } 150 151 void X86ATTInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op, 152 raw_ostream &O) { 153 O << markup("<mem:"); 154 155 // If this has a segment register, print it. 156 printOptionalSegReg(MI, Op + 1, O); 157 158 O << "("; 159 printOperand(MI, Op, O); 160 O << ")"; 161 162 O << markup(">"); 163 } 164 165 void X86ATTInstPrinter::printDstIdx(const MCInst *MI, unsigned Op, 166 raw_ostream &O) { 167 O << markup("<mem:"); 168 169 O << "%es:("; 170 printOperand(MI, Op, O); 171 O << ")"; 172 173 O << markup(">"); 174 } 175 176 void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op, 177 raw_ostream &O) { 178 const MCOperand &DispSpec = MI->getOperand(Op); 179 180 O << markup("<mem:"); 181 182 // If this has a segment register, print it. 183 printOptionalSegReg(MI, Op + 1, O); 184 185 if (DispSpec.isImm()) { 186 O << formatImm(DispSpec.getImm()); 187 } else { 188 assert(DispSpec.isExpr() && "non-immediate displacement?"); 189 DispSpec.getExpr()->print(O, &MAI); 190 } 191 192 O << markup(">"); 193 } 194 195 void X86ATTInstPrinter::printU8Imm(const MCInst *MI, unsigned Op, 196 raw_ostream &O) { 197 if (MI->getOperand(Op).isExpr()) 198 return printOperand(MI, Op, O); 199 200 O << markup("<imm:") << '$' << formatImm(MI->getOperand(Op).getImm() & 0xff) 201 << markup(">"); 202 } 203