HexagonMCCodeEmitter.cpp revision 4c5e43da7792f75567b693105cc53e3f1992ad98
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/HexagonMCInstrInfo.h" 14#include "MCTargetDesc/HexagonMCTargetDesc.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 28using namespace llvm; 29using namespace Hexagon; 30 31STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 32 33namespace { 34/// \brief 10.6 Instruction Packets 35/// Possible values for instruction packet parse field. 36enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 }; 37/// \brief Returns the packet bits based on instruction position. 38uint32_t getPacketBits(MCInst const &HMI) { 39 unsigned const ParseFieldOffset = 14; 40 ParseField Field = HexagonMCInstrInfo::isPacketEnd(HMI) ? ParseField::end : ParseField::last0; 41 return static_cast <uint32_t> (Field) << ParseFieldOffset; 42} 43void 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 51HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII, 52 MCContext &aMCT) 53 : MCT(aMCT), MCII(aMII) {} 54 55void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS, 56 SmallVectorImpl<MCFixup> &Fixups, 57 MCSubtargetInfo const &STI) const { 58 uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI) | getPacketBits(MI); 59 assert(HexagonMCInstrInfo::getDesc(MCII, MI).getSize() == 4 && 60 "All instructions should be 32bit"); 61 (void)&MCII; 62 emitLittleEndian(Binary, OS); 63 ++MCNumEmitted; 64} 65 66unsigned 67HexagonMCCodeEmitter::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 77MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII, 78 MCRegisterInfo const &MRI, 79 MCContext &MCT) { 80 return new HexagonMCCodeEmitter(MII, MCT); 81} 82 83#include "HexagonGenMCCodeEmitter.inc" 84