Home | History | Annotate | Download | only in MC
      1 //===-- MCInstPrinter.cpp - Convert an MCInst to target assembly syntax ---===//
      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 #include "llvm/MC/MCInstPrinter.h"
     11 #include "llvm/ADT/StringRef.h"
     12 #include "llvm/MC/MCAsmInfo.h"
     13 #include "llvm/MC/MCInstrInfo.h"
     14 #include "llvm/Support/ErrorHandling.h"
     15 #include "llvm/Support/Format.h"
     16 #include "llvm/Support/raw_ostream.h"
     17 using namespace llvm;
     18 
     19 MCInstPrinter::~MCInstPrinter() {
     20 }
     21 
     22 /// getOpcodeName - Return the name of the specified opcode enum (e.g.
     23 /// "MOV32ri") or empty if we can't resolve it.
     24 StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
     25   return MII.getName(Opcode);
     26 }
     27 
     28 void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
     29   llvm_unreachable("Target should implement this");
     30 }
     31 
     32 void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) {
     33   if (!Annot.empty()) {
     34     if (CommentStream) {
     35       (*CommentStream) << Annot;
     36       // By definition (see MCInstPrinter.h), CommentStream must end with
     37       // a newline after each comment.
     38       if (Annot.back() != '\n')
     39         (*CommentStream) << '\n';
     40     } else
     41       OS << " " << MAI.getCommentString() << " " << Annot;
     42   }
     43 }
     44 
     45 /// Utility functions to make adding mark ups simpler.
     46 StringRef MCInstPrinter::markup(StringRef s) const {
     47   if (getUseMarkup())
     48     return s;
     49   else
     50     return "";
     51 }
     52 StringRef MCInstPrinter::markup(StringRef a, StringRef b) const {
     53   if (getUseMarkup())
     54     return a;
     55   else
     56     return b;
     57 }
     58 
     59 // For asm-style hex (e.g. 0ffh) the first digit always has to be a number.
     60 static bool needsLeadingZero(uint64_t Value)
     61 {
     62   while(Value)
     63   {
     64     uint64_t digit = (Value >> 60) & 0xf;
     65     if (digit != 0)
     66       return (digit >= 0xa);
     67     Value <<= 4;
     68   }
     69   return false;
     70 }
     71 
     72 format_object1<int64_t> MCInstPrinter::formatDec(const int64_t Value) const {
     73   return format("%" PRId64, Value);
     74 }
     75 
     76 format_object1<int64_t> MCInstPrinter::formatHex(const int64_t Value) const {
     77   switch(PrintHexStyle) {
     78   case HexStyle::C:
     79     if (Value < 0)
     80       return format("-0x%" PRIx64, -Value);
     81     else
     82       return format("0x%" PRIx64, Value);
     83   case HexStyle::Asm:
     84     if (Value < 0) {
     85       if (needsLeadingZero((uint64_t)(-Value)))
     86         return format("-0%" PRIx64 "h", -Value);
     87       else
     88         return format("-%" PRIx64 "h", -Value);
     89     } else {
     90       if (needsLeadingZero((uint64_t)(Value)))
     91         return format("0%" PRIx64 "h", Value);
     92       else
     93         return format("%" PRIx64 "h", Value);
     94     }
     95   }
     96   llvm_unreachable("unsupported print style");
     97 }
     98 
     99 format_object1<uint64_t> MCInstPrinter::formatHex(const uint64_t Value) const {
    100   switch(PrintHexStyle) {
    101   case HexStyle::C:
    102      return format("0x%" PRIx64, Value);
    103   case HexStyle::Asm:
    104     if (needsLeadingZero(Value))
    105       return format("0%" PRIx64 "h", Value);
    106     else
    107       return format("%" PRIx64 "h", Value);
    108   }
    109   llvm_unreachable("unsupported print style");
    110 }
    111