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#include "XCoreInstPrinter.h"
15249259Sdim#include "llvm/ADT/StringExtras.h"
16249259Sdim#include "llvm/MC/MCExpr.h"
17249259Sdim#include "llvm/MC/MCInst.h"
18249259Sdim#include "llvm/MC/MCInstrInfo.h"
19249259Sdim#include "llvm/MC/MCSymbol.h"
20249259Sdim#include "llvm/Support/ErrorHandling.h"
21249259Sdim#include "llvm/Support/raw_ostream.h"
22249259Sdimusing namespace llvm;
23249259Sdim
24276479Sdim#define DEBUG_TYPE "asm-printer"
25276479Sdim
26249259Sdim#include "XCoreGenAsmWriter.inc"
27249259Sdim
28249259Sdimvoid XCoreInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
29249259Sdim  OS << StringRef(getRegisterName(RegNo)).lower();
30249259Sdim}
31249259Sdim
32249259Sdimvoid XCoreInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
33288943Sdim                                 StringRef Annot, const MCSubtargetInfo &STI) {
34249259Sdim  printInstruction(MI, O);
35249259Sdim  printAnnotation(O, Annot);
36249259Sdim}
37249259Sdim
38249259Sdimvoid XCoreInstPrinter::
39249259SdimprintInlineJT(const MCInst *MI, int opNum, raw_ostream &O) {
40249259Sdim  report_fatal_error("can't handle InlineJT");
41249259Sdim}
42249259Sdim
43249259Sdimvoid XCoreInstPrinter::
44249259SdimprintInlineJT32(const MCInst *MI, int opNum, raw_ostream &O) {
45249259Sdim  report_fatal_error("can't handle InlineJT32");
46249259Sdim}
47249259Sdim
48288943Sdimstatic void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,
49288943Sdim                      raw_ostream &OS) {
50249259Sdim  int Offset = 0;
51249259Sdim  const MCSymbolRefExpr *SRE;
52249259Sdim
53249259Sdim  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
54249259Sdim    SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
55249259Sdim    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(BE->getRHS());
56249259Sdim    assert(SRE && CE && "Binary expression must be sym+const.");
57249259Sdim    Offset = CE->getValue();
58249259Sdim  } else {
59249259Sdim    SRE = dyn_cast<MCSymbolRefExpr>(Expr);
60249259Sdim    assert(SRE && "Unexpected MCExpr type.");
61249259Sdim  }
62249259Sdim  assert(SRE->getKind() == MCSymbolRefExpr::VK_None);
63249259Sdim
64288943Sdim  SRE->getSymbol().print(OS, MAI);
65249259Sdim
66249259Sdim  if (Offset) {
67249259Sdim    if (Offset > 0)
68249259Sdim      OS << '+';
69249259Sdim    OS << Offset;
70249259Sdim  }
71249259Sdim}
72249259Sdim
73249259Sdimvoid XCoreInstPrinter::
74249259SdimprintOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
75249259Sdim  const MCOperand &Op = MI->getOperand(OpNo);
76249259Sdim  if (Op.isReg()) {
77249259Sdim    printRegName(O, Op.getReg());
78249259Sdim    return;
79249259Sdim  }
80249259Sdim
81249259Sdim  if (Op.isImm()) {
82249259Sdim    O << Op.getImm();
83249259Sdim    return;
84249259Sdim  }
85249259Sdim
86249259Sdim  assert(Op.isExpr() && "unknown operand kind in printOperand");
87288943Sdim  printExpr(Op.getExpr(), &MAI, O);
88249259Sdim}
89