diff options
Diffstat (limited to 'lib/Target/Hexagon/MCTargetDesc')
15 files changed, 731 insertions, 24 deletions
diff --git a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt index eeef3ef..2a6124e 100644 --- a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt @@ -1,5 +1,11 @@ add_llvm_library(LLVMHexagonDesc + HexagonAsmBackend.cpp + HexagonELFObjectWriter.cpp + HexagonInstPrinter.cpp HexagonMCAsmInfo.cpp + HexagonMCCodeEmitter.cpp HexagonMCInst.cpp HexagonMCTargetDesc.cpp ) + +add_dependencies(LLVMHexagonDesc HexagonCommonTableGen) diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp new file mode 100644 index 0000000..bdccf88 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -0,0 +1,74 @@ +//===-- HexagonAsmBackend.cpp - Hexagon Assembler Backend -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "HexagonMCTargetDesc.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCELFObjectWriter.h" + +using namespace llvm; + +namespace { + +class HexagonAsmBackend : public MCAsmBackend { +public: + HexagonAsmBackend(Target const & /*T*/) {} + + unsigned getNumFixupKinds() const override { return 0; } + + void applyFixup(MCFixup const & /*Fixup*/, char * /*Data*/, + unsigned /*DataSize*/, uint64_t /*Value*/, + bool /*IsPCRel*/) const override { + return; + } + + bool mayNeedRelaxation(MCInst const & /*Inst*/) const override { + return false; + } + + bool fixupNeedsRelaxation(MCFixup const & /*Fixup*/, uint64_t /*Value*/, + MCRelaxableFragment const * /*DF*/, + MCAsmLayout const & /*Layout*/) const override { + llvm_unreachable("fixupNeedsRelaxation() unimplemented"); + } + + void relaxInstruction(MCInst const & /*Inst*/, + MCInst & /*Res*/) const override { + llvm_unreachable("relaxInstruction() unimplemented"); + } + + bool writeNopData(uint64_t /*Count*/, + MCObjectWriter * /*OW*/) const override { + return true; + } +}; +} // end anonymous namespace + +namespace { +class ELFHexagonAsmBackend : public HexagonAsmBackend { + uint8_t OSABI; + +public: + ELFHexagonAsmBackend(Target const &T, uint8_t OSABI) + : HexagonAsmBackend(T), OSABI(OSABI) {} + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + StringRef CPU("HexagonV4"); + return createHexagonELFObjectWriter(OS, OSABI, CPU); + } +}; +} // end anonymous namespace + +namespace llvm { +MCAsmBackend *createHexagonAsmBackend(Target const &T, + MCRegisterInfo const & /*MRI*/, + StringRef TT, StringRef /*CPU*/) { + uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); + return new ELFHexagonAsmBackend(T, OSABI); +} +} diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h index f8be77c..c0a3fae 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h @@ -14,12 +14,14 @@ // //===----------------------------------------------------------------------===// -#ifndef HEXAGONBASEINFO_H -#define HEXAGONBASEINFO_H +#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H +#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H #include "HexagonMCTargetDesc.h" #include "llvm/Support/ErrorHandling.h" +#include <stdint.h> + namespace llvm { /// HexagonII - This namespace holds all of the target specific flags that @@ -189,6 +191,15 @@ namespace HexagonII { MO_GPREL }; + enum class InstParseBits : uint32_t { + INST_PARSE_MASK = 0x0000c000, + INST_PARSE_PACKET_END = 0x0000c000, + INST_PARSE_LOOP_END = 0x00008000, + INST_PARSE_NOT_END = 0x00004000, + INST_PARSE_DUPLEX = 0x00000000, + INST_PARSE_EXTENDER = 0x00000000 + }; + } // End namespace HexagonII. } // End namespace llvm. diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp new file mode 100644 index 0000000..56c9dc7 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp @@ -0,0 +1,62 @@ +//===-- HexagonELFObjectWriter.cpp - Hexagon Target Descriptions ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Hexagon.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "hexagon-elf-writer" + +using namespace llvm; +using namespace Hexagon; + +namespace { + +class HexagonELFObjectWriter : public MCELFObjectTargetWriter { +private: + StringRef CPU; + +public: + HexagonELFObjectWriter(uint8_t OSABI, StringRef C); + + virtual unsigned GetRelocType(MCValue const &Target, MCFixup const &Fixup, + bool IsPCRel) const override; +}; +} + +HexagonELFObjectWriter::HexagonELFObjectWriter(uint8_t OSABI, StringRef C) + : MCELFObjectTargetWriter(/*Is64bit*/ false, OSABI, ELF::EM_HEXAGON, + /*HasRelocationAddend*/ true), + CPU(C) {} + +unsigned HexagonELFObjectWriter::GetRelocType(MCValue const &/*Target*/, + MCFixup const &Fixup, + bool IsPCRel) const { + unsigned Type = (unsigned)ELF::R_HEX_NONE; + llvm::MCFixupKind Kind = Fixup.getKind(); + + switch (Kind) { + default: + DEBUG(dbgs() << "unrecognized relocation " << Fixup.getKind() << "\n"); + llvm_unreachable("Unimplemented Fixup kind!"); + break; + case FK_Data_4: + Type = (IsPCRel) ? ELF::R_HEX_32_PCREL : ELF::R_HEX_32; + break; + } + return Type; +} + +MCObjectWriter *llvm::createHexagonELFObjectWriter(raw_ostream &OS, + uint8_t OSABI, + StringRef CPU) { + MCELFObjectTargetWriter *MOTW = new HexagonELFObjectWriter(OSABI, CPU); + return createELFObjectWriter(MOTW, OS, /*IsLittleEndian*/ true); +}
\ No newline at end of file diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp new file mode 100644 index 0000000..1fd8d70 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp @@ -0,0 +1,254 @@ +//===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===// +// +// 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 Hexagon MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#include "HexagonAsmPrinter.h" +#include "Hexagon.h" +#include "HexagonInstPrinter.h" +#include "MCTargetDesc/HexagonMCInst.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +#define GET_INSTRUCTION_NAME +#include "HexagonGenAsmWriter.inc" + +const char HexagonInstPrinter::PacketPadding = '\t'; +// Return the minimum value that a constant extendable operand can have +// without being extended. +static int getMinValue(uint64_t TSFlags) { + unsigned isSigned = + (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; + unsigned bits = + (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; + + if (isSigned) + return -1U << (bits - 1); + + return 0; +} + +// Return the maximum value that a constant extendable operand can have +// without being extended. +static int getMaxValue(uint64_t TSFlags) { + unsigned isSigned = + (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; + unsigned bits = + (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; + + if (isSigned) + return ~(-1U << (bits - 1)); + + return ~(-1U << bits); +} + +// Return true if the instruction must be extended. +static bool isExtended(uint64_t TSFlags) { + return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; +} + +// Currently just used in an assert statement +static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED; +// Return true if the instruction may be extended based on the operand value. +static bool isExtendable(uint64_t TSFlags) { + return (TSFlags >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; +} + +StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { + return MII.getName(Opcode); +} + +StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { + return getRegisterName(RegNo); +} + +void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot) { + printInst((const HexagonMCInst*)(MI), O, Annot); +} + +void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O, + StringRef Annot) { + const char startPacket = '{', + endPacket = '}'; + // TODO: add outer HW loop when it's supported too. + if (MI->getOpcode() == Hexagon::ENDLOOP0) { + // Ending a harware loop is different from ending an regular packet. + assert(MI->isPacketEnd() && "Loop-end must also end the packet"); + + if (MI->isPacketStart()) { + // There must be a packet to end a loop. + // FIXME: when shuffling is always run, this shouldn't be needed. + HexagonMCInst Nop; + StringRef NoAnnot; + + Nop.setOpcode (Hexagon::NOP); + Nop.setPacketStart (MI->isPacketStart()); + printInst (&Nop, O, NoAnnot); + } + + // Close the packet. + if (MI->isPacketEnd()) + O << PacketPadding << endPacket; + + printInstruction(MI, O); + } + else { + // Prefix the insn opening the packet. + if (MI->isPacketStart()) + O << PacketPadding << startPacket << '\n'; + + printInstruction(MI, O); + + // Suffix the insn closing the packet. + if (MI->isPacketEnd()) + // Suffix the packet in a new line always, since the GNU assembler has + // issues with a closing brace on the same line as CONST{32,64}. + O << '\n' << PacketPadding << endPacket; + } + + printAnnotation(O, Annot); +} + +void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + + if (MO.isReg()) { + O << getRegisterName(MO.getReg()); + } else if(MO.isExpr()) { + O << *MO.getExpr(); + } else if(MO.isImm()) { + printImmOperand(MI, OpNo, O); + } else { + llvm_unreachable("Unknown operand"); + } +} + +void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + + if(MO.isExpr()) { + O << *MO.getExpr(); + } else if(MO.isImm()) { + O << MI->getOperand(OpNo).getImm(); + } else { + llvm_unreachable("Unknown operand"); + } +} + +void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand &MO = MI->getOperand(OpNo); + const MCInstrDesc &MII = getMII().get(MI->getOpcode()); + + assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) && + "Expecting an extendable operand"); + + if (MO.isExpr() || isExtended(MII.TSFlags)) { + O << "#"; + } else if (MO.isImm()) { + int ImmValue = MO.getImm(); + if (ImmValue < getMinValue(MII.TSFlags) || + ImmValue > getMaxValue(MII.TSFlags)) + O << "#"; + } + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, + unsigned OpNo, raw_ostream &O) const { + O << MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + O << -MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + O << -1; +} + +void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO0 = MI->getOperand(OpNo); + const MCOperand& MO1 = MI->getOperand(OpNo + 1); + + O << getRegisterName(MO0.getReg()); + O << " + #" << MO1.getImm(); +} + +void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO0 = MI->getOperand(OpNo); + const MCOperand& MO1 = MI->getOperand(OpNo + 1); + + O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm(); +} + +void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + // Branches can take an immediate operand. This is used by the branch + // selection pass to print $+8, an eight byte displacement from the PC. + llvm_unreachable("Unknown branch operand."); +} + +void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo, + raw_ostream &O, bool hi) const { + assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand"); + + O << '#' << (hi ? "HI" : "LO") << "(#"; + printOperand(MI, OpNo, O); + O << ')'; +} diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h new file mode 100644 index 0000000..55ae95c --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h @@ -0,0 +1,87 @@ +//===-- HexagonInstPrinter.h - Convert Hexagon MCInst to assembly syntax --===// +// +// 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 Hexagon MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H +#define LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.h" + +namespace llvm { + class HexagonMCInst; + + class HexagonInstPrinter : public MCInstPrinter { + public: + explicit HexagonInstPrinter(const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI), MII(MII) {} + + void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) override; + void printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot); + virtual StringRef getOpcodeName(unsigned Opcode) const; + void printInstruction(const MCInst *MI, raw_ostream &O); + StringRef getRegName(unsigned RegNo) const; + static const char *getRegisterName(unsigned RegNo); + + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printUnsignedImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const; + void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printFrameIndexOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const; + void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printCallOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printAbsAddrOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printPredicateOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printGlobalOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printJumpTable(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + + void printConstantPool(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const; + + void printSymbolHi(const MCInst *MI, unsigned OpNo, raw_ostream &O) const + { printSymbol(MI, OpNo, O, true); } + void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O) const + { printSymbol(MI, OpNo, O, false); } + + const MCInstrInfo &getMII() const { + return MII; + } + + protected: + void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) + const; + + static const char PacketPadding; + + private: + const MCInstrInfo &MII; + + }; + +} // end namespace llvm + +#endif diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp index 141e514..ad5e0fb 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp @@ -24,7 +24,6 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(StringRef TT) { Data64bitsDirective = nullptr; // .xword is only supported by V9. ZeroDirective = "\t.skip\t"; CommentString = "//"; - HasLEB128 = true; LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment; InlineAsmStart = "# InlineAsm Start"; diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h index 953d804..ab18f0b 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef HexagonMCASMINFO_H -#define HexagonMCASMINFO_H +#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCASMINFO_H +#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCASMINFO_H #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCAsmInfoELF.h" diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp new file mode 100644 index 0000000..4471977 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -0,0 +1,88 @@ +//===-- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Hexagon.h" +#include "MCTargetDesc/HexagonBaseInfo.h" +#include "MCTargetDesc/HexagonMCCodeEmitter.h" +#include "MCTargetDesc/HexagonMCTargetDesc.h" +#include "MCTargetDesc/HexagonMCInst.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "mccodeemitter" + +using namespace llvm; +using namespace Hexagon; + +STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); + +namespace { +/// \brief 10.6 Instruction Packets +/// Possible values for instruction packet parse field. +enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 }; +/// \brief Returns the packet bits based on instruction position. +uint32_t getPacketBits(HexagonMCInst const &HMI) { + unsigned const ParseFieldOffset = 14; + ParseField Field = HMI.isPacketEnd() ? ParseField::end : ParseField::last0; + return static_cast <uint32_t> (Field) << ParseFieldOffset; +} +void emitLittleEndian(uint64_t Binary, raw_ostream &OS) { + OS << static_cast<uint8_t>((Binary >> 0x00) & 0xff); + OS << static_cast<uint8_t>((Binary >> 0x08) & 0xff); + OS << static_cast<uint8_t>((Binary >> 0x10) & 0xff); + OS << static_cast<uint8_t>((Binary >> 0x18) & 0xff); +} +} + +HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII, + MCSubtargetInfo const &aMST, + MCContext &aMCT) + : MST(aMST), MCT(aMCT) {} + +void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS, + SmallVectorImpl<MCFixup> &Fixups, + MCSubtargetInfo const &STI) const { + HexagonMCInst const &HMB = static_cast<HexagonMCInst const &>(MI); + uint64_t Binary = getBinaryCodeForInstr(HMB, Fixups, STI) | getPacketBits(HMB); + assert(HMB.getDesc().getSize() == 4 && "All instructions should be 32bit"); + emitLittleEndian(Binary, OS); + ++MCNumEmitted; +} + +unsigned +HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO, + SmallVectorImpl<MCFixup> &Fixups, + MCSubtargetInfo const &STI) const { + if (MO.isReg()) + return MCT.getRegisterInfo()->getEncodingValue(MO.getReg()); + if (MO.isImm()) + return static_cast<unsigned>(MO.getImm()); + llvm_unreachable("Only Immediates and Registers implemented right now"); +} + +MCSubtargetInfo const &HexagonMCCodeEmitter::getSubtargetInfo() const { + return MST; +} + +MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII, + MCRegisterInfo const &MRI, + MCSubtargetInfo const &MST, + MCContext &MCT) { + return new HexagonMCCodeEmitter(MII, MST, MCT); +} + +#include "HexagonGenMCCodeEmitter.inc" diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h new file mode 100644 index 0000000..96048ad --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h @@ -0,0 +1,60 @@ +//===-- HexagonMCCodeEmitter.h - Hexagon Target Descriptions ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Definition for classes that emit Hexagon machine code from MCInsts +/// +//===----------------------------------------------------------------------===// + +#ifndef HEXAGONMCCODEEMITTER_H +#define HEXAGONMCCODEEMITTER_H + +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +class HexagonMCCodeEmitter : public MCCodeEmitter { + MCSubtargetInfo const &MST; + MCContext &MCT; + +public: + HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCSubtargetInfo const &aMST, + MCContext &aMCT); + + MCSubtargetInfo const &getSubtargetInfo() const; + + void EncodeInstruction(MCInst const &MI, raw_ostream &OS, + SmallVectorImpl<MCFixup> &Fixups, + MCSubtargetInfo const &STI) const override; + + // \brief TableGen'erated function for getting the + // binary encoding for an instruction. + uint64_t getBinaryCodeForInstr(MCInst const &MI, + SmallVectorImpl<MCFixup> &Fixups, + MCSubtargetInfo const &STI) const; + + /// \brief Return binary encoding of operand. + unsigned getMachineOpValue(MCInst const &MI, MCOperand const &MO, + SmallVectorImpl<MCFixup> &Fixups, + MCSubtargetInfo const &STI) const; + +private: + HexagonMCCodeEmitter(HexagonMCCodeEmitter const &) LLVM_DELETED_FUNCTION; + void operator=(HexagonMCCodeEmitter const &) LLVM_DELETED_FUNCTION; +}; // class HexagonMCCodeEmitter + +} // namespace llvm + +#endif /* HEXAGONMCCODEEMITTER_H */ diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp index 9260b4a..c842b9b 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp @@ -20,8 +20,9 @@ using namespace llvm; // Return the slots used by the insn. unsigned HexagonMCInst::getUnits(const HexagonTargetMachine* TM) const { - const HexagonInstrInfo* QII = TM->getInstrInfo(); - const InstrItineraryData* II = TM->getInstrItineraryData(); + const HexagonInstrInfo *QII = TM->getSubtargetImpl()->getInstrInfo(); + const InstrItineraryData *II = + TM->getSubtargetImpl()->getInstrItineraryData(); const InstrStage* IS = II->beginStage(QII->get(this->getOpcode()).getSchedClass()); @@ -154,7 +155,7 @@ int HexagonMCInst::getMinValue(void) const { & HexagonII::ExtentBitsMask; if (isSigned) // if value is signed - return -1 << (bits - 1); + return -1U << (bits - 1); else return 0; } @@ -169,7 +170,7 @@ int HexagonMCInst::getMaxValue(void) const { & HexagonII::ExtentBitsMask; if (isSigned) // if value is signed - return ~(-1 << (bits - 1)); + return ~(-1U << (bits - 1)); else - return ~(-1 << bits); + return ~(-1U << bits); } diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h index 3c52d45..90fbbf3 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef HEXAGONMCINST_H -#define HEXAGONMCINST_H +#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINST_H +#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINST_H #include "HexagonTargetMachine.h" #include "llvm/MC/MCInst.h" diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 581674d..14ddd9d 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -13,8 +13,9 @@ #include "HexagonMCTargetDesc.h" #include "HexagonMCAsmInfo.h" -#include "InstPrinter/HexagonInstPrinter.h" +#include "MCTargetDesc/HexagonInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" @@ -46,9 +47,17 @@ static MCRegisterInfo *createHexagonMCRegisterInfo(StringRef TT) { return X; } -static MCSubtargetInfo *createHexagonMCSubtargetInfo(StringRef TT, - StringRef CPU, - StringRef FS) { +static MCStreamer * +createHexagonELFStreamer(MCContext &Context, MCAsmBackend &MAB, + raw_ostream &OS, MCCodeEmitter *CE, + bool RelaxAll) { + MCELFStreamer *ES = new MCELFStreamer(Context, MAB, OS, CE); + return ES; +} + + +static MCSubtargetInfo * +createHexagonMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { MCSubtargetInfo *X = new MCSubtargetInfo(); InitHexagonMCSubtargetInfo(X, TT, CPU, FS); return X; @@ -59,22 +68,40 @@ static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, MCAsmInfo *MAI = new HexagonMCAsmInfo(TT); // VirtualFP = (R30 + #0). - MCCFIInstruction Inst = MCCFIInstruction::createDefCfa( - nullptr, Hexagon::R30, 0); + MCCFIInstruction Inst = + MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0); MAI->addInitialFrameState(Inst); return MAI; } +static MCStreamer *createMCStreamer(Target const &T, StringRef TT, + MCContext &Context, MCAsmBackend &MAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + MCSubtargetInfo const &STI, bool RelaxAll) { + MCStreamer *ES = createHexagonELFStreamer(Context, MAB, OS, Emitter, RelaxAll); + new MCTargetStreamer(*ES); + return ES; +} + + static MCCodeGenInfo *createHexagonMCCodeGenInfo(StringRef TT, Reloc::Model RM, - CodeModel::Model CM, - CodeGenOpt::Level OL) { + CodeModel::Model CM, + CodeGenOpt::Level OL) { MCCodeGenInfo *X = new MCCodeGenInfo(); // For the time being, use static relocations, since there's really no // support for PIC yet. X->InitMCCodeGenInfo(Reloc::Static, CM, OL); return X; } +static MCInstPrinter *createHexagonMCInstPrinter(const Target &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI) { + return new HexagonInstPrinter(MAI, MII, MRI); +} // Force static initialization. extern "C" void LLVMInitializeHexagonTargetMC() { @@ -86,7 +113,8 @@ extern "C" void LLVMInitializeHexagonTargetMC() { createHexagonMCCodeGenInfo); // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget, createHexagonMCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget, + createHexagonMCInstrInfo); // Register the MC register info. TargetRegistry::RegisterMCRegInfo(TheHexagonTarget, @@ -95,4 +123,19 @@ extern "C" void LLVMInitializeHexagonTargetMC() { // Register the MC subtarget info. TargetRegistry::RegisterMCSubtargetInfo(TheHexagonTarget, createHexagonMCSubtargetInfo); + + // Register the MC Code Emitter + TargetRegistry::RegisterMCCodeEmitter(TheHexagonTarget, + createHexagonMCCodeEmitter); + + // Register the MC Inst Printer + TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget, + createHexagonMCInstPrinter); + + // Register the asm backend + TargetRegistry::RegisterMCAsmBackend(TheHexagonTarget, + createHexagonAsmBackend); + + // Register the obj streamer + TargetRegistry::RegisterMCObjectStreamer(TheHexagonTarget, createMCStreamer); } diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h index 2238b1a..02fd516 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h @@ -11,15 +11,37 @@ // //===----------------------------------------------------------------------===// -#ifndef HEXAGONMCTARGETDESC_H -#define HEXAGONMCTARGETDESC_H +#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H +#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H + +#include <cstdint> namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; +class MCObjectWriter; +class MCRegisterInfo; class MCSubtargetInfo; class Target; +class StringRef; +class raw_ostream; extern Target TheHexagonTarget; +MCCodeEmitter *createHexagonMCCodeEmitter(MCInstrInfo const &MCII, + MCRegisterInfo const &MRI, + MCSubtargetInfo const &MST, + MCContext &MCT); + +MCAsmBackend *createHexagonAsmBackend(Target const &T, + MCRegisterInfo const &MRI, StringRef TT, + StringRef CPU); + +MCObjectWriter *createHexagonELFObjectWriter(raw_ostream &OS, uint8_t OSABI, + StringRef CPU); + } // End llvm namespace // Define symbolic names for Hexagon registers. This defines a mapping from diff --git a/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt b/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt index 73c7e01..f559a21 100644 --- a/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt +++ b/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = HexagonDesc parent = Hexagon -required_libraries = HexagonInfo MC +required_libraries = HexagonInfo MC Support add_to_library_groups = Hexagon |