1fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===//
2fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//
3fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//                     The LLVM Compiler Infrastructure
4fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//
5fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner// This file is distributed under the University of Illinois Open Source
6fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner// License. See LICENSE.TXT for details.
7fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//
8fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//===----------------------------------------------------------------------===//
9fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//
10fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner// This file includes code for rendering MCInst instances as AT&T-style
11fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner// assembly.
12fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//
13fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner//===----------------------------------------------------------------------===//
14fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner
15fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner#define DEBUG_TYPE "asm-printer"
16cae05cb324031b16a71c56a2a01b489a7c28d365Chris Lattner#include "X86ATTInstPrinter.h"
176aa928d57a73a557d838f62af84e929bed0f276eChris Lattner#include "X86InstComments.h"
18ed5e3552147830159a1d48d067dfbb49ac9cccfdEvan Cheng#include "MCTargetDesc/X86MCTargetDesc.h"
19fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner#include "llvm/MC/MCInst.h"
20af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h"
218c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h"
227c0b3c1fb6395475e262d66ee403645f0c67dee2Craig Topper#include "llvm/MC/MCInstrInfo.h"
23cef670a3a3fd448edfb38d8b513f5aa775257352Benjamin Kramer#include "llvm/MC/MCRegisterInfo.h"
24ab7c09b6b6f4516a631fd6788918c237c83939afTorok Edwin#include "llvm/Support/ErrorHandling.h"
255d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner#include "llvm/Support/Format.h"
2671847813bc419f7a0667468136a07429c6d9f164David Greene#include "llvm/Support/FormattedStream.h"
2744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling#include <map>
28fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattnerusing namespace llvm;
29fadc83c699d16e07747b1ceca7fbb01390fdcb74Chris Lattner
30d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner// Include the auto-generated portion of the assembly writer.
3144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling#define PRINT_ALIAS_INSTR
32d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner#include "X86GenAsmWriter.inc"
3344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling
34cde4ce411b1ace4a80ea1dd38df97e8508aed0c9Rafael Espindolavoid X86ATTInstPrinter::printRegName(raw_ostream &OS,
35cde4ce411b1ace4a80ea1dd38df97e8508aed0c9Rafael Espindola                                     unsigned RegNo) const {
36cde4ce411b1ace4a80ea1dd38df97e8508aed0c9Rafael Espindola  OS << '%' << getRegisterName(RegNo);
376e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola}
386e032942cf58d1c41f88609a1cec74eb74940ecdRafael Espindola
3998c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Andersonvoid X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
4098c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                                  StringRef Annot) {
41721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher  // Try to print any aliases first.
42721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher  if (!printAliasInstr(MI, OS))
43c6df9883da99915d1cfa491b381ffa703c61ed90Bill Wendling    printInstruction(MI, OS);
446aa928d57a73a557d838f62af84e929bed0f276eChris Lattner
45b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby  // Next always print the annotation.
46b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby  printAnnotation(OS, Annot);
47b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby
486aa928d57a73a557d838f62af84e929bed0f276eChris Lattner  // If verbose assembly is enabled, we can print some informative comments.
49b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby  if (CommentStream)
506aa928d57a73a557d838f62af84e929bed0f276eChris Lattner    EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
5135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner}
5244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling
5335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
5435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                   raw_ostream &O) {
55c12430644a9f49a056286f8ebe0e55ccc23bdde0Chris Lattner  switch (MI->getOperand(Op).getImm()) {
566d1263acb9704b38a8d90fd6ce94f49193cd4ddeCraig Topper  default: llvm_unreachable("Invalid ssecc argument!");
57f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    0: O << "eq"; break;
58f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    1: O << "lt"; break;
59f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    2: O << "le"; break;
60f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    3: O << "unord"; break;
61f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    4: O << "neq"; break;
62f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    5: O << "nlt"; break;
63f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    6: O << "nle"; break;
64f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    7: O << "ord"; break;
65f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    8: O << "eq_uq"; break;
66f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case    9: O << "nge"; break;
67f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case  0xa: O << "ngt"; break;
68f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case  0xb: O << "false"; break;
69f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case  0xc: O << "neq_oq"; break;
70f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case  0xd: O << "ge"; break;
71f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case  0xe: O << "gt"; break;
72f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case  0xf: O << "true"; break;
73f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x10: O << "eq_os"; break;
74f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x11: O << "lt_oq"; break;
75f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x12: O << "le_oq"; break;
76f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x13: O << "unord_s"; break;
77f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x14: O << "neq_us"; break;
78f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x15: O << "nlt_uq"; break;
79f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x16: O << "nle_uq"; break;
80f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x17: O << "ord_s"; break;
81f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x18: O << "eq_us"; break;
82f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x19: O << "nge_uq"; break;
83f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x1a: O << "ngt_uq"; break;
84f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x1b: O << "false_os"; break;
85f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x1c: O << "neq_os"; break;
86f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x1d: O << "ge_oq"; break;
87f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x1e: O << "gt_oq"; break;
88f602040c4900d89bbf55478420769e36604588fbElena Demikhovsky  case 0x1f: O << "true_us"; break;
89d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner  }
90d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner}
91d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner
927680e733415e01a30183a73bfbe16f7829439db7Chris Lattner/// print_pcrel_imm - This is used to print an immediate value that ends up
93ffc0574a12fb2c8cc1b76dfebf21bccd879f5de2Chris Lattner/// being encoded as a pc-relative value (e.g. for jumps and calls).  These
94ffc0574a12fb2c8cc1b76dfebf21bccd879f5de2Chris Lattner/// print slightly differently than normal immediates.  For example, a $ is not
95ffc0574a12fb2c8cc1b76dfebf21bccd879f5de2Chris Lattner/// emitted.
9635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo,
9735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O) {
987680e733415e01a30183a73bfbe16f7829439db7Chris Lattner  const MCOperand &Op = MI->getOperand(OpNo);
997680e733415e01a30183a73bfbe16f7829439db7Chris Lattner  if (Op.isImm())
100b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    O << Op.getImm();
101f92c95f3070f2f797987d2b753780a3a5e482351Chris Lattner  else {
102f92c95f3070f2f797987d2b753780a3a5e482351Chris Lattner    assert(Op.isExpr() && "unknown pcrel immediate operand");
103b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    // If a symbolic branch target was added as a constant expression then print
104b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    // that address in hex.
105b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
106b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    int64_t Address;
107b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
108b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      O << "0x";
109b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      O.write_hex(Address);
110b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    }
111b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    else {
112b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      // Otherwise, just print the expression.
113b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      O << *Op.getExpr();
114b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    }
115f92c95f3070f2f797987d2b753780a3a5e482351Chris Lattner  }
1167680e733415e01a30183a73bfbe16f7829439db7Chris Lattner}
1177680e733415e01a30183a73bfbe16f7829439db7Chris Lattner
11835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
11935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O) {
120f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  const MCOperand &Op = MI->getOperand(OpNo);
121f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  if (Op.isReg()) {
122c510f4cb6ef524800ff010ddb0551384bd38b1c1Chris Lattner    O << '%' << getRegisterName(Op.getReg());
123f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  } else if (Op.isImm()) {
124d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby    // Print X86 immediates as signed values.
125d5705fe50d58dd2b686b26d1683315f785246ce0Kevin Enderby    O << '$' << (int64_t)Op.getImm();
1265d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner
1275d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner    if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
12841a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer      *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());
1295d672cfab096390690a1a5f33b0057c4cf252c55Chris Lattner
130f92c95f3070f2f797987d2b753780a3a5e482351Chris Lattner  } else {
131f92c95f3070f2f797987d2b753780a3a5e482351Chris Lattner    assert(Op.isExpr() && "unknown operand kind in printOperand");
1328cb9a3b13f3226b7e741768b69d26ecd6b5231f1Chris Lattner    O << '$' << *Op.getExpr();
133f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  }
134d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner}
135d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner
136599b531a960833719f607d66c97871f1f5ad12c0Chris Lattnervoid X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
137599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner                                          raw_ostream &O) {
138f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  const MCOperand &BaseReg  = MI->getOperand(Op);
139f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  const MCOperand &IndexReg = MI->getOperand(Op+2);
140f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  const MCOperand &DispSpec = MI->getOperand(Op+3);
141599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner  const MCOperand &SegReg = MI->getOperand(Op+4);
142599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner
143599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner  // If this has a segment register, print it.
144599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner  if (SegReg.getReg()) {
145599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner    printOperand(MI, Op+4, O);
146599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner    O << ':';
147599b531a960833719f607d66c97871f1f5ad12c0Chris Lattner  }
148f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner
149f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  if (DispSpec.isImm()) {
150f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner    int64_t DispVal = DispSpec.getImm();
151f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner    if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
152f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner      O << DispVal;
153f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  } else {
1543de47b8a85a186bac4ae6dbebf555a8363b176c5Chris Lattner    assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
1558cb9a3b13f3226b7e741768b69d26ecd6b5231f1Chris Lattner    O << *DispSpec.getExpr();
156f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  }
157f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner
158f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  if (IndexReg.getReg() || BaseReg.getReg()) {
159f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner    O << '(';
160f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner    if (BaseReg.getReg())
16135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, Op, O);
162f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner
163f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner    if (IndexReg.getReg()) {
164f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner      O << ',';
16535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, Op+2, O);
1667f8217f64bc6efabc680f4ffff77e199f6c53103Chris Lattner      unsigned ScaleVal = MI->getOperand(Op+1).getImm();
1677f8217f64bc6efabc680f4ffff77e199f6c53103Chris Lattner      if (ScaleVal != 1)
168f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner        O << ',' << ScaleVal;
169f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner    }
170f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner    O << ')';
171f38c03af2a142db2777ce839026706969f3aeaa9Chris Lattner  }
172d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner}
173