diff options
Diffstat (limited to 'llvm/lib/Target/ARC/MCTargetDesc')
-rw-r--r-- | llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp | 179 | ||||
-rw-r--r-- | llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h | 45 | ||||
-rw-r--r-- | llvm/lib/Target/ARC/MCTargetDesc/ARCMCTargetDesc.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARC/MCTargetDesc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/Target/ARC/MCTargetDesc/LLVMBuild.txt | 2 |
5 files changed, 227 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp new file mode 100644 index 00000000000..e3e0ea48995 --- /dev/null +++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.cpp @@ -0,0 +1,179 @@ +//===- ARCInstPrinter.cpp - ARC MCInst to assembly syntax -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +#include "ARCGenAsmWriter.inc" + +template <class T> +static const char *BadConditionCode(T cc) { + LLVM_DEBUG(dbgs() << "Unknown condition code passed: " << cc << "\n"); + return "{unknown-cc}"; +} + +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"; + } + return BadConditionCode(BRCC); +} + +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::VS: + return "vs"; + case ARCCC::VC: + return "vc"; + 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"; + } + return BadConditionCode(CC); +} + +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 *CE = dyn_cast<MCConstantExpr>(Expr)) { + OS << "0x"; + OS.write_hex(CE->getValue()); + return; + } + + 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()); +} diff --git a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h new file mode 100644 index 00000000000..5ea58407f9e --- /dev/null +++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h @@ -0,0 +1,45 @@ +//===- ARCInstPrinter.h - Convert ARC MCInst to assembly syntax -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains the declaration of the ARCInstPrinter class, +/// which is used to print ARC MCInst to a .s file. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_ARC_INSTPRINTER_ARCINSTPRINTER_H +#define LLVM_LIB_TARGET_ARC_INSTPRINTER_ARCINSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { + +class ARCInstPrinter : public MCInstPrinter { +public: + ARCInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI) {} + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); + + void printRegName(raw_ostream &OS, unsigned RegNo) const override; + void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, + const MCSubtargetInfo &STI) override; + +private: + void printMemOperandRI(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum, + raw_ostream &O); +}; +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_ARC_INSTPRINTER_ARCINSTPRINTER_H diff --git a/llvm/lib/Target/ARC/MCTargetDesc/ARCMCTargetDesc.cpp b/llvm/lib/Target/ARC/MCTargetDesc/ARCMCTargetDesc.cpp index 07713024809..5739866993b 100644 --- a/llvm/lib/Target/ARC/MCTargetDesc/ARCMCTargetDesc.cpp +++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCMCTargetDesc.cpp @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// #include "ARCMCTargetDesc.h" +#include "ARCInstPrinter.h" #include "ARCMCAsmInfo.h" #include "ARCTargetStreamer.h" -#include "InstPrinter/ARCInstPrinter.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" diff --git a/llvm/lib/Target/ARC/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/ARC/MCTargetDesc/CMakeLists.txt index 243198d253f..108fb93cafa 100644 --- a/llvm/lib/Target/ARC/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/ARC/MCTargetDesc/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMARCDesc + ARCInstPrinter.cpp ARCMCTargetDesc.cpp ARCMCAsmInfo.cpp ) diff --git a/llvm/lib/Target/ARC/MCTargetDesc/LLVMBuild.txt b/llvm/lib/Target/ARC/MCTargetDesc/LLVMBuild.txt index 6abf96e066e..5d2e0e6face 100644 --- a/llvm/lib/Target/ARC/MCTargetDesc/LLVMBuild.txt +++ b/llvm/lib/Target/ARC/MCTargetDesc/LLVMBuild.txt @@ -18,5 +18,5 @@ type = Library name = ARCDesc parent = ARC -required_libraries = MC Support ARCAsmPrinter ARCInfo +required_libraries = MC Support ARCInfo add_to_library_groups = ARC |