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"
17using namespace llvm;
18
19MCInstPrinter::~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.
24StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
25  return MII.getName(Opcode);
26}
27
28void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
29  llvm_unreachable("Target should implement this");
30}
31
32void 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.
46StringRef MCInstPrinter::markup(StringRef s) const {
47  if (getUseMarkup())
48    return s;
49  else
50    return "";
51}
52StringRef 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.
60static 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
72format_object1<int64_t> MCInstPrinter::formatDec(const int64_t Value) const {
73  return format("%" PRId64, Value);
74}
75
76format_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
99format_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