diff options
Diffstat (limited to 'llvm/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp b/llvm/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp new file mode 100644 index 00000000000..d4f1046db12 --- /dev/null +++ b/llvm/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp @@ -0,0 +1,166 @@ +//===- ARCInstPrinter.cpp - ARC MCInst to assembly syntax -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an ARC MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#include "ARCInstPrinter.h" +#include "MCTargetDesc/ARCInfo.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +#include "ARCGenAsmWriter.inc" + +static const char *ARCBRCondCodeToString(ARCCC::BRCondCode BRCC) { + switch (BRCC) { + case ARCCC::BREQ: + return "eq"; + case ARCCC::BRNE: + return "ne"; + case ARCCC::BRLT: + return "lt"; + case ARCCC::BRGE: + return "ge"; + case ARCCC::BRLO: + return "lo"; + case ARCCC::BRHS: + return "hs"; + default: + llvm_unreachable("Unhandled ARCCC::BRCondCode"); + } +} + +static const char *ARCCondCodeToString(ARCCC::CondCode CC) { + switch (CC) { + case ARCCC::EQ: + return "eq"; + case ARCCC::NE: + return "ne"; + case ARCCC::P: + return "p"; + case ARCCC::N: + return "n"; + case ARCCC::HS: + return "hs"; + case ARCCC::LO: + return "lo"; + case ARCCC::GT: + return "gt"; + case ARCCC::GE: + return "ge"; + case ARCCC::LT: + return "lt"; + case ARCCC::LE: + return "le"; + case ARCCC::HI: + return "hi"; + case ARCCC::LS: + return "ls"; + case ARCCC::PNZ: + return "pnz"; + case ARCCC::AL: + return "al"; + case ARCCC::NZ: + return "nz"; + case ARCCC::Z: + return "z"; + } + llvm_unreachable("Unhandled ARCCC::CondCode"); +} + +void ARCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { + OS << StringRef(getRegisterName(RegNo)).lower(); +} + +void ARCInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot, const MCSubtargetInfo &STI) { + printInstruction(MI, O); + printAnnotation(O, Annot); +} + +static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI, + raw_ostream &OS) { + int Offset = 0; + const MCSymbolRefExpr *SRE; + + if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr)) { + SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS()); + const auto *CE = dyn_cast<MCConstantExpr>(BE->getRHS()); + assert(SRE && CE && "Binary expression must be sym+const."); + Offset = CE->getValue(); + } else { + SRE = dyn_cast<MCSymbolRefExpr>(Expr); + assert(SRE && "Unexpected MCExpr type."); + } + assert(SRE->getKind() == MCSymbolRefExpr::VK_None); + + // Symbols are prefixed with '@' + OS << '@'; + SRE->getSymbol().print(OS, MAI); + + if (Offset) { + if (Offset > 0) + OS << '+'; + OS << Offset; + } +} + +void ARCInstPrinter::printOperand(const MCInst *MI, unsigned OpNum, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNum); + if (Op.isReg()) { + printRegName(O, Op.getReg()); + return; + } + + if (Op.isImm()) { + O << Op.getImm(); + return; + } + + assert(Op.isExpr() && "unknown operand kind in printOperand"); + printExpr(Op.getExpr(), &MAI, O); +} + +void ARCInstPrinter::printMemOperandRI(const MCInst *MI, unsigned OpNum, + raw_ostream &O) { + const MCOperand &base = MI->getOperand(OpNum); + const MCOperand &offset = MI->getOperand(OpNum + 1); + assert(base.isReg() && "Base should be register."); + assert(offset.isImm() && "Offset should be immediate."); + printRegName(O, base.getReg()); + O << "," << offset.getImm(); +} + +void ARCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, + raw_ostream &O) { + + const MCOperand &Op = MI->getOperand(OpNum); + assert(Op.isImm() && "Predicate operand is immediate."); + O << ARCCondCodeToString((ARCCC::CondCode)Op.getImm()); +} + +void ARCInstPrinter::printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNum); + assert(Op.isImm() && "Predicate operand is immediate."); + O << ARCBRCondCodeToString((ARCCC::BRCondCode)Op.getImm()); +} |