| Sid Manning | 7da3f9a | 2014-10-03 13:18:11 +0000 | [diff] [blame^] | 1 | //===-- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions ------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "Hexagon.h" |
| 11 | #include "MCTargetDesc/HexagonBaseInfo.h" |
| 12 | #include "MCTargetDesc/HexagonMCCodeEmitter.h" |
| 13 | #include "MCTargetDesc/HexagonMCTargetDesc.h" |
| 14 | #include "MCTargetDesc/HexagonMCInst.h" |
| 15 | #include "llvm/ADT/Statistic.h" |
| 16 | #include "llvm/MC/MCCodeEmitter.h" |
| 17 | #include "llvm/MC/MCContext.h" |
| 18 | #include "llvm/MC/MCExpr.h" |
| 19 | #include "llvm/MC/MCInst.h" |
| 20 | #include "llvm/MC/MCInstrInfo.h" |
| 21 | #include "llvm/MC/MCRegisterInfo.h" |
| 22 | #include "llvm/MC/MCSubtargetInfo.h" |
| 23 | #include "llvm/Support/Debug.h" |
| 24 | #include "llvm/Support/raw_ostream.h" |
| 25 | |
| 26 | #define DEBUG_TYPE "mccodeemitter" |
| 27 | |
| 28 | using namespace llvm; |
| 29 | using namespace Hexagon; |
| 30 | |
| 31 | STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); |
| 32 | |
| 33 | namespace { |
| 34 | /// \brief 10.6 Instruction Packets |
| 35 | /// \brief Possible values for instruction packet parse field. |
| 36 | enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 }; |
| 37 | /// \brief Returns the packet bits based on instruction position. |
| 38 | uint32_t getPacketBits(HexagonMCInst const &HMI) { |
| 39 | unsigned const ParseFieldOffset = 14; |
| 40 | ParseField Field = HMI.isPacketEnd() ? ParseField::end : ParseField::last0; |
| 41 | return static_cast <uint32_t> (Field) << ParseFieldOffset; |
| 42 | } |
| 43 | void emitLittleEndian(uint64_t Binary, raw_ostream &OS) { |
| 44 | OS << static_cast<uint8_t>((Binary >> 0x00) & 0xff); |
| 45 | OS << static_cast<uint8_t>((Binary >> 0x08) & 0xff); |
| 46 | OS << static_cast<uint8_t>((Binary >> 0x10) & 0xff); |
| 47 | OS << static_cast<uint8_t>((Binary >> 0x18) & 0xff); |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII, |
| 52 | MCSubtargetInfo const &aMST, |
| 53 | MCContext &aMCT) |
| 54 | : MST(aMST), MCT(aMCT) {} |
| 55 | |
| 56 | void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS, |
| 57 | SmallVectorImpl<MCFixup> &Fixups, |
| 58 | MCSubtargetInfo const &STI) const { |
| 59 | HexagonMCInst const &HMB = static_cast<HexagonMCInst const &>(MI); |
| 60 | uint64_t Binary = getBinaryCodeForInstr(HMB, Fixups, STI) | getPacketBits(HMB); |
| 61 | assert(HMB.getDesc().getSize() == 4 && "All instructions should be 32bit"); |
| 62 | emitLittleEndian(Binary, OS); |
| 63 | ++MCNumEmitted; |
| 64 | } |
| 65 | |
| 66 | unsigned |
| 67 | HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO, |
| 68 | SmallVectorImpl<MCFixup> &Fixups, |
| 69 | MCSubtargetInfo const &STI) const { |
| 70 | if (MO.isReg()) |
| 71 | return MCT.getRegisterInfo()->getEncodingValue(MO.getReg()); |
| 72 | if (MO.isImm()) |
| 73 | return static_cast<unsigned>(MO.getImm()); |
| 74 | llvm_unreachable("Only Immediates and Registers implemented right now"); |
| 75 | } |
| 76 | |
| 77 | MCSubtargetInfo const &HexagonMCCodeEmitter::getSubtargetInfo() const { |
| 78 | return MST; |
| 79 | } |
| 80 | |
| 81 | MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII, |
| 82 | MCRegisterInfo const &MRI, |
| 83 | MCSubtargetInfo const &MST, |
| 84 | MCContext &MCT) { |
| 85 | return new HexagonMCCodeEmitter(MII, MST, MCT); |
| 86 | } |
| 87 | |
| 88 | #include "HexagonGenMCCodeEmitter.inc" |