X86ATTInstPrinter.cpp revision cde4ce411b1ace4a80ea1dd38df97e8508aed0c9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file includes code for rendering MCInst instances as AT&T-style
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// assembly.
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===//
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DEBUG_TYPE "asm-printer"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "X86ATTInstPrinter.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "X86InstComments.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "X86Subtarget.h"
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/MC/MCInst.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/MC/MCAsmInfo.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/MC/MCExpr.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/ErrorHandling.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/Format.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/FormattedStream.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "X86GenInstrNames.inc"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Include the auto-generated portion of the assembly writer.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GET_INSTRUCTION_NAME
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define PRINT_ALIAS_INSTR
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "X86GenRegisterNames.inc"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "X86GenAsmWriter.inc"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef PRINT_ALIAS_INSTR
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GET_INSTRUCTION_NAME
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)X86ATTInstPrinter::X86ATTInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : MCInstPrinter(MAI) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the set of available features.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  setAvailableFeatures(ComputeAvailableFeatures(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &TM.getSubtarget<X86Subtarget>()));
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void X86ATTInstPrinter::printRegName(raw_ostream &OS,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     unsigned RegNo) const {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OS << '%' << getRegisterName(RegNo);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Try to print any aliases first.
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!printAliasInstr(MI, OS))
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    printInstruction(MI, OS);
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If verbose assembly is enabled, we can print some informative comments.
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (CommentStream)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return getInstructionName(Opcode);
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   raw_ostream &O) {
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (MI->getOperand(Op).getImm()) {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  default: assert(0 && "Invalid ssecc argument!");
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case 0: O << "eq"; break;
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case 1: O << "lt"; break;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case 2: O << "le"; break;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  case 3: O << "unord"; break;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  case 4: O << "neq"; break;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  case 5: O << "nlt"; break;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  case 6: O << "nle"; break;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  case 7: O << "ord"; break;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// print_pcrel_imm - This is used to print an immediate value that ends up
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// being encoded as a pc-relative value (e.g. for jumps and calls).  These
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// print slightly differently than normal immediates.  For example, a $ is not
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// emitted.
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo,
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                        raw_ostream &O) {
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const MCOperand &Op = MI->getOperand(OpNo);
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (Op.isImm())
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Print this as a signed 32-bit value.
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    O << (int)Op.getImm();
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else {
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    assert(Op.isExpr() && "unknown pcrel immediate operand");
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    O << *Op.getExpr();
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     raw_ostream &O) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const MCOperand &Op = MI->getOperand(OpNo);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Op.isReg()) {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    O << '%' << getRegisterName(Op.getReg());
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (Op.isImm()) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    O << '$' << Op.getImm();
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm());
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assert(Op.isExpr() && "unknown operand kind in printOperand");
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    O << '$' << *Op.getExpr();
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          raw_ostream &O) {
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const MCOperand &BaseReg  = MI->getOperand(Op);
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const MCOperand &IndexReg = MI->getOperand(Op+2);
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const MCOperand &DispSpec = MI->getOperand(Op+3);
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const MCOperand &SegReg = MI->getOperand(Op+4);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If this has a segment register, print it.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (SegReg.getReg()) {
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    printOperand(MI, Op+4, O);
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    O << ':';
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (DispSpec.isImm()) {
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64_t DispVal = DispSpec.getImm();
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      O << DispVal;
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    O << *DispSpec.getExpr();
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (IndexReg.getReg() || BaseReg.getReg()) {
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    O << '(';
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (BaseReg.getReg())
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      printOperand(MI, Op, O);
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IndexReg.getReg()) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      O << ',';
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      printOperand(MI, Op+2, O);
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      unsigned ScaleVal = MI->getOperand(Op+1).getImm();
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (ScaleVal != 1)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        O << ',' << ScaleVal;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    O << ')';
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)