1249259Sdim//===-- XCoreInstPrinter.cpp - Convert XCore MCInst to assembly syntax ----===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim// This class prints an XCore MCInst to a .s file.
11249259Sdim//
12249259Sdim//===----------------------------------------------------------------------===//
13249259Sdim
14249259Sdim#define DEBUG_TYPE "asm-printer"
15249259Sdim#include "XCoreInstPrinter.h"
16249259Sdim#include "llvm/ADT/StringExtras.h"
17249259Sdim#include "llvm/MC/MCExpr.h"
18249259Sdim#include "llvm/MC/MCInst.h"
19249259Sdim#include "llvm/MC/MCInstrInfo.h"
20249259Sdim#include "llvm/MC/MCSymbol.h"
21249259Sdim#include "llvm/Support/ErrorHandling.h"
22249259Sdim#include "llvm/Support/raw_ostream.h"
23249259Sdimusing namespace llvm;
24249259Sdim
25249259Sdim#include "XCoreGenAsmWriter.inc"
26249259Sdim
27249259Sdimvoid XCoreInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
28249259Sdim  OS << StringRef(getRegisterName(RegNo)).lower();
29249259Sdim}
30249259Sdim
31249259Sdimvoid XCoreInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
32249259Sdim                                 StringRef Annot) {
33249259Sdim  printInstruction(MI, O);
34249259Sdim  printAnnotation(O, Annot);
35249259Sdim}
36249259Sdim
37249259Sdimvoid XCoreInstPrinter::
38249259SdimprintInlineJT(const MCInst *MI, int opNum, raw_ostream &O) {
39249259Sdim  report_fatal_error("can't handle InlineJT");
40249259Sdim}
41249259Sdim
42249259Sdimvoid XCoreInstPrinter::
43249259SdimprintInlineJT32(const MCInst *MI, int opNum, raw_ostream &O) {
44249259Sdim  report_fatal_error("can't handle InlineJT32");
45249259Sdim}
46249259Sdim
47249259Sdimstatic void printExpr(const MCExpr *Expr, raw_ostream &OS) {
48249259Sdim  int Offset = 0;
49249259Sdim  const MCSymbolRefExpr *SRE;
50249259Sdim
51249259Sdim  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
52249259Sdim    SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
53249259Sdim    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(BE->getRHS());
54249259Sdim    assert(SRE && CE && "Binary expression must be sym+const.");
55249259Sdim    Offset = CE->getValue();
56249259Sdim  } else {
57249259Sdim    SRE = dyn_cast<MCSymbolRefExpr>(Expr);
58249259Sdim    assert(SRE && "Unexpected MCExpr type.");
59249259Sdim  }
60249259Sdim  assert(SRE->getKind() == MCSymbolRefExpr::VK_None);
61249259Sdim
62249259Sdim  OS << SRE->getSymbol();
63249259Sdim
64249259Sdim  if (Offset) {
65249259Sdim    if (Offset > 0)
66249259Sdim      OS << '+';
67249259Sdim    OS << Offset;
68249259Sdim  }
69249259Sdim}
70249259Sdim
71249259Sdimvoid XCoreInstPrinter::
72249259SdimprintOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
73249259Sdim  const MCOperand &Op = MI->getOperand(OpNo);
74249259Sdim  if (Op.isReg()) {
75249259Sdim    printRegName(O, Op.getReg());
76249259Sdim    return;
77249259Sdim  }
78249259Sdim
79249259Sdim  if (Op.isImm()) {
80249259Sdim    O << Op.getImm();
81249259Sdim    return;
82249259Sdim  }
83249259Sdim
84249259Sdim  assert(Op.isExpr() && "unknown operand kind in printOperand");
85249259Sdim  printExpr(Op.getExpr(), O);
86249259Sdim}
87