LLVM API Documentation
00001 //===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file includes code for rendering MCInst instances as AT&T-style 00011 // assembly. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "X86ATTInstPrinter.h" 00016 #include "MCTargetDesc/X86BaseInfo.h" 00017 #include "MCTargetDesc/X86MCTargetDesc.h" 00018 #include "X86InstComments.h" 00019 #include "llvm/MC/MCAsmInfo.h" 00020 #include "llvm/MC/MCExpr.h" 00021 #include "llvm/MC/MCInst.h" 00022 #include "llvm/MC/MCInstrInfo.h" 00023 #include "llvm/MC/MCRegisterInfo.h" 00024 #include "llvm/Support/ErrorHandling.h" 00025 #include "llvm/Support/Format.h" 00026 #include "llvm/Support/FormattedStream.h" 00027 #include <map> 00028 using namespace llvm; 00029 00030 #define DEBUG_TYPE "asm-printer" 00031 00032 // Include the auto-generated portion of the assembly writer. 00033 #define PRINT_ALIAS_INSTR 00034 #include "X86GenAsmWriter.inc" 00035 00036 void X86ATTInstPrinter::printRegName(raw_ostream &OS, 00037 unsigned RegNo) const { 00038 OS << markup("<reg:") 00039 << '%' << getRegisterName(RegNo) 00040 << markup(">"); 00041 } 00042 00043 void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 00044 StringRef Annot) { 00045 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 00046 uint64_t TSFlags = Desc.TSFlags; 00047 00048 // If verbose assembly is enabled, we can print some informative comments. 00049 if (CommentStream) 00050 HasCustomInstComment = 00051 EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); 00052 00053 if (TSFlags & X86II::LOCK) 00054 OS << "\tlock\n"; 00055 00056 // Output CALLpcrel32 as "callq" in 64-bit mode. 00057 // In Intel annotation it's always emitted as "call". 00058 // 00059 // TODO: Probably this hack should be redesigned via InstAlias in 00060 // InstrInfo.td as soon as Requires clause is supported properly 00061 // for InstAlias. 00062 if (MI->getOpcode() == X86::CALLpcrel32 && 00063 (getAvailableFeatures() & X86::Mode64Bit) != 0) { 00064 OS << "\tcallq\t"; 00065 printPCRelImm(MI, 0, OS); 00066 } 00067 // Try to print any aliases first. 00068 else if (!printAliasInstr(MI, OS)) 00069 printInstruction(MI, OS); 00070 00071 // Next always print the annotation. 00072 printAnnotation(OS, Annot); 00073 } 00074 00075 void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op, 00076 raw_ostream &O) { 00077 int64_t Imm = MI->getOperand(Op).getImm() & 0xf; 00078 switch (Imm) { 00079 default: llvm_unreachable("Invalid ssecc argument!"); 00080 case 0: O << "eq"; break; 00081 case 1: O << "lt"; break; 00082 case 2: O << "le"; break; 00083 case 3: O << "unord"; break; 00084 case 4: O << "neq"; break; 00085 case 5: O << "nlt"; break; 00086 case 6: O << "nle"; break; 00087 case 7: O << "ord"; break; 00088 case 8: O << "eq_uq"; break; 00089 case 9: O << "nge"; break; 00090 case 0xa: O << "ngt"; break; 00091 case 0xb: O << "false"; break; 00092 case 0xc: O << "neq_oq"; break; 00093 case 0xd: O << "ge"; break; 00094 case 0xe: O << "gt"; break; 00095 case 0xf: O << "true"; break; 00096 } 00097 } 00098 00099 void X86ATTInstPrinter::printAVXCC(const MCInst *MI, unsigned Op, 00100 raw_ostream &O) { 00101 int64_t Imm = MI->getOperand(Op).getImm() & 0x1f; 00102 switch (Imm) { 00103 default: llvm_unreachable("Invalid avxcc argument!"); 00104 case 0: O << "eq"; break; 00105 case 1: O << "lt"; break; 00106 case 2: O << "le"; break; 00107 case 3: O << "unord"; break; 00108 case 4: O << "neq"; break; 00109 case 5: O << "nlt"; break; 00110 case 6: O << "nle"; break; 00111 case 7: O << "ord"; break; 00112 case 8: O << "eq_uq"; break; 00113 case 9: O << "nge"; break; 00114 case 0xa: O << "ngt"; break; 00115 case 0xb: O << "false"; break; 00116 case 0xc: O << "neq_oq"; break; 00117 case 0xd: O << "ge"; break; 00118 case 0xe: O << "gt"; break; 00119 case 0xf: O << "true"; break; 00120 case 0x10: O << "eq_os"; break; 00121 case 0x11: O << "lt_oq"; break; 00122 case 0x12: O << "le_oq"; break; 00123 case 0x13: O << "unord_s"; break; 00124 case 0x14: O << "neq_us"; break; 00125 case 0x15: O << "nlt_uq"; break; 00126 case 0x16: O << "nle_uq"; break; 00127 case 0x17: O << "ord_s"; break; 00128 case 0x18: O << "eq_us"; break; 00129 case 0x19: O << "nge_uq"; break; 00130 case 0x1a: O << "ngt_uq"; break; 00131 case 0x1b: O << "false_os"; break; 00132 case 0x1c: O << "neq_os"; break; 00133 case 0x1d: O << "ge_oq"; break; 00134 case 0x1e: O << "gt_oq"; break; 00135 case 0x1f: O << "true_us"; break; 00136 } 00137 } 00138 00139 void X86ATTInstPrinter::printRoundingControl(const MCInst *MI, unsigned Op, 00140 raw_ostream &O) { 00141 int64_t Imm = MI->getOperand(Op).getImm() & 0x3; 00142 switch (Imm) { 00143 case 0: O << "{rn-sae}"; break; 00144 case 1: O << "{rd-sae}"; break; 00145 case 2: O << "{ru-sae}"; break; 00146 case 3: O << "{rz-sae}"; break; 00147 } 00148 } 00149 /// printPCRelImm - This is used to print an immediate value that ends up 00150 /// being encoded as a pc-relative value (e.g. for jumps and calls). These 00151 /// print slightly differently than normal immediates. For example, a $ is not 00152 /// emitted. 00153 void X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo, 00154 raw_ostream &O) { 00155 const MCOperand &Op = MI->getOperand(OpNo); 00156 if (Op.isImm()) 00157 O << formatImm(Op.getImm()); 00158 else { 00159 assert(Op.isExpr() && "unknown pcrel immediate operand"); 00160 // If a symbolic branch target was added as a constant expression then print 00161 // that address in hex. 00162 const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr()); 00163 int64_t Address; 00164 if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) { 00165 O << formatHex((uint64_t)Address); 00166 } 00167 else { 00168 // Otherwise, just print the expression. 00169 O << *Op.getExpr(); 00170 } 00171 } 00172 } 00173 00174 void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 00175 raw_ostream &O) { 00176 const MCOperand &Op = MI->getOperand(OpNo); 00177 if (Op.isReg()) { 00178 printRegName(O, Op.getReg()); 00179 } else if (Op.isImm()) { 00180 // Print X86 immediates as signed values. 00181 O << markup("<imm:") 00182 << '$' << formatImm((int64_t)Op.getImm()) 00183 << markup(">"); 00184 00185 // If there are no instruction-specific comments, add a comment clarifying 00186 // the hex value of the immediate operand when it isn't in the range 00187 // [-256,255]. 00188 if (CommentStream && !HasCustomInstComment && 00189 (Op.getImm() > 255 || Op.getImm() < -256)) 00190 *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm()); 00191 00192 } else { 00193 assert(Op.isExpr() && "unknown operand kind in printOperand"); 00194 O << markup("<imm:") 00195 << '$' << *Op.getExpr() 00196 << markup(">"); 00197 } 00198 } 00199 00200 void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 00201 raw_ostream &O) { 00202 const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); 00203 const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); 00204 const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); 00205 const MCOperand &SegReg = MI->getOperand(Op+X86::AddrSegmentReg); 00206 00207 O << markup("<mem:"); 00208 00209 // If this has a segment register, print it. 00210 if (SegReg.getReg()) { 00211 printOperand(MI, Op+X86::AddrSegmentReg, O); 00212 O << ':'; 00213 } 00214 00215 if (DispSpec.isImm()) { 00216 int64_t DispVal = DispSpec.getImm(); 00217 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 00218 O << formatImm(DispVal); 00219 } else { 00220 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 00221 O << *DispSpec.getExpr(); 00222 } 00223 00224 if (IndexReg.getReg() || BaseReg.getReg()) { 00225 O << '('; 00226 if (BaseReg.getReg()) 00227 printOperand(MI, Op+X86::AddrBaseReg, O); 00228 00229 if (IndexReg.getReg()) { 00230 O << ','; 00231 printOperand(MI, Op+X86::AddrIndexReg, O); 00232 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); 00233 if (ScaleVal != 1) { 00234 O << ',' 00235 << markup("<imm:") 00236 << ScaleVal // never printed in hex. 00237 << markup(">"); 00238 } 00239 } 00240 O << ')'; 00241 } 00242 00243 O << markup(">"); 00244 } 00245 00246 void X86ATTInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op, 00247 raw_ostream &O) { 00248 const MCOperand &SegReg = MI->getOperand(Op+1); 00249 00250 O << markup("<mem:"); 00251 00252 // If this has a segment register, print it. 00253 if (SegReg.getReg()) { 00254 printOperand(MI, Op+1, O); 00255 O << ':'; 00256 } 00257 00258 O << "("; 00259 printOperand(MI, Op, O); 00260 O << ")"; 00261 00262 O << markup(">"); 00263 } 00264 00265 void X86ATTInstPrinter::printDstIdx(const MCInst *MI, unsigned Op, 00266 raw_ostream &O) { 00267 O << markup("<mem:"); 00268 00269 O << "%es:("; 00270 printOperand(MI, Op, O); 00271 O << ")"; 00272 00273 O << markup(">"); 00274 } 00275 00276 void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op, 00277 raw_ostream &O) { 00278 const MCOperand &DispSpec = MI->getOperand(Op); 00279 const MCOperand &SegReg = MI->getOperand(Op+1); 00280 00281 O << markup("<mem:"); 00282 00283 // If this has a segment register, print it. 00284 if (SegReg.getReg()) { 00285 printOperand(MI, Op+1, O); 00286 O << ':'; 00287 } 00288 00289 if (DispSpec.isImm()) { 00290 O << formatImm(DispSpec.getImm()); 00291 } else { 00292 assert(DispSpec.isExpr() && "non-immediate displacement?"); 00293 O << *DispSpec.getExpr(); 00294 } 00295 00296 O << markup(">"); 00297 }