Home | History | Annotate | Download | only in InstPrinter
      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 #define DEBUG_TYPE "asm-printer"
     16 #include "X86ATTInstPrinter.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/Format.h"
     24 #include "llvm/Support/FormattedStream.h"
     25 #include <map>
     26 using namespace llvm;
     27 
     28 // Include the auto-generated portion of the assembly writer.
     29 #define GET_INSTRUCTION_NAME
     30 #define PRINT_ALIAS_INSTR
     31 #include "X86GenAsmWriter.inc"
     32 
     33 X86ATTInstPrinter::X86ATTInstPrinter(const MCAsmInfo &MAI)
     34   : MCInstPrinter(MAI) {
     35 }
     36 
     37 void X86ATTInstPrinter::printRegName(raw_ostream &OS,
     38                                      unsigned RegNo) const {
     39   OS << '%' << getRegisterName(RegNo);
     40 }
     41 
     42 void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
     43                                   StringRef Annot) {
     44   // Try to print any aliases first.
     45   if (!printAliasInstr(MI, OS))
     46     printInstruction(MI, OS);
     47 
     48   // If verbose assembly is enabled, we can print some informative comments.
     49   if (CommentStream) {
     50     printAnnotation(OS, Annot);
     51     EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
     52   }
     53 }
     54 
     55 StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const {
     56   return getInstructionName(Opcode);
     57 }
     58 
     59 void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
     60                                    raw_ostream &O) {
     61   switch (MI->getOperand(Op).getImm()) {
     62   default: assert(0 && "Invalid ssecc argument!");
     63   case 0: O << "eq"; break;
     64   case 1: O << "lt"; break;
     65   case 2: O << "le"; break;
     66   case 3: O << "unord"; break;
     67   case 4: O << "neq"; break;
     68   case 5: O << "nlt"; break;
     69   case 6: O << "nle"; break;
     70   case 7: O << "ord"; break;
     71   }
     72 }
     73 
     74 /// print_pcrel_imm - This is used to print an immediate value that ends up
     75 /// being encoded as a pc-relative value (e.g. for jumps and calls).  These
     76 /// print slightly differently than normal immediates.  For example, a $ is not
     77 /// emitted.
     78 void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo,
     79                                         raw_ostream &O) {
     80   const MCOperand &Op = MI->getOperand(OpNo);
     81   if (Op.isImm())
     82     // Print this as a signed 32-bit value.
     83     O << (int)Op.getImm();
     84   else {
     85     assert(Op.isExpr() && "unknown pcrel immediate operand");
     86     O << *Op.getExpr();
     87   }
     88 }
     89 
     90 void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     91                                      raw_ostream &O) {
     92   const MCOperand &Op = MI->getOperand(OpNo);
     93   if (Op.isReg()) {
     94     O << '%' << getRegisterName(Op.getReg());
     95   } else if (Op.isImm()) {
     96     // Print X86 immediates as signed values.
     97     O << '$' << (int64_t)Op.getImm();
     98 
     99     if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
    100       *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm());
    101 
    102   } else {
    103     assert(Op.isExpr() && "unknown operand kind in printOperand");
    104     O << '$' << *Op.getExpr();
    105   }
    106 }
    107 
    108 void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
    109                                           raw_ostream &O) {
    110   const MCOperand &BaseReg  = MI->getOperand(Op);
    111   const MCOperand &IndexReg = MI->getOperand(Op+2);
    112   const MCOperand &DispSpec = MI->getOperand(Op+3);
    113   const MCOperand &SegReg = MI->getOperand(Op+4);
    114 
    115   // If this has a segment register, print it.
    116   if (SegReg.getReg()) {
    117     printOperand(MI, Op+4, O);
    118     O << ':';
    119   }
    120 
    121   if (DispSpec.isImm()) {
    122     int64_t DispVal = DispSpec.getImm();
    123     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
    124       O << DispVal;
    125   } else {
    126     assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
    127     O << *DispSpec.getExpr();
    128   }
    129 
    130   if (IndexReg.getReg() || BaseReg.getReg()) {
    131     O << '(';
    132     if (BaseReg.getReg())
    133       printOperand(MI, Op, O);
    134 
    135     if (IndexReg.getReg()) {
    136       O << ',';
    137       printOperand(MI, Op+2, O);
    138       unsigned ScaleVal = MI->getOperand(Op+1).getImm();
    139       if (ScaleVal != 1)
    140         O << ',' << ScaleVal;
    141     }
    142     O << ')';
    143   }
    144 }
    145