1 //===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the CSKYMCCodeEmitter class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "CSKYMCCodeEmitter.h" 14 #include "MCTargetDesc/CSKYMCTargetDesc.h" 15 #include "llvm/ADT/Statistic.h" 16 #include "llvm/MC/MCInstBuilder.h" 17 #include "llvm/MC/MCInstrInfo.h" 18 #include "llvm/Support/EndianStream.h" 19 20 using namespace llvm; 21 22 #define DEBUG_TYPE "csky-mccode-emitter" 23 24 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 25 26 unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx, 27 SmallVectorImpl<MCFixup> &Fixups, 28 const MCSubtargetInfo &STI) const { 29 const MCOperand &MO = MI.getOperand(Idx); 30 assert(MO.isImm() && "Unexpected MO type."); 31 return MO.getImm() - 1; 32 } 33 34 void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 35 SmallVectorImpl<MCFixup> &Fixups, 36 const MCSubtargetInfo &STI) const { 37 const MCInstrDesc &Desc = MII.get(MI.getOpcode()); 38 unsigned Size = Desc.getSize(); 39 uint32_t Bin = getBinaryCodeForInstr(MI, Fixups, STI); 40 41 uint16_t LO16 = static_cast<uint16_t>(Bin); 42 uint16_t HI16 = static_cast<uint16_t>(Bin >> 16); 43 44 if (Size == 4) 45 support::endian::write<uint16_t>(OS, HI16, support::little); 46 47 support::endian::write<uint16_t>(OS, LO16, support::little); 48 ++MCNumEmitted; // Keep track of the # of mi's emitted. 49 } 50 51 unsigned 52 CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 53 SmallVectorImpl<MCFixup> &Fixups, 54 const MCSubtargetInfo &STI) const { 55 if (MO.isReg()) 56 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 57 58 if (MO.isImm()) 59 return static_cast<unsigned>(MO.getImm()); 60 61 llvm_unreachable("Unhandled expression!"); 62 return 0; 63 } 64 65 MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const { 66 const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr); 67 68 switch (CSKYExpr->getKind()) { 69 default: 70 llvm_unreachable("Unhandled fixup kind!"); 71 case CSKYMCExpr::VK_CSKY_ADDR: 72 return MCFixupKind(CSKY::fixup_csky_addr32); 73 } 74 } 75 76 MCCodeEmitter *llvm::createCSKYMCCodeEmitter(const MCInstrInfo &MCII, 77 const MCRegisterInfo &MRI, 78 MCContext &Ctx) { 79 return new CSKYMCCodeEmitter(Ctx, MCII); 80 } 81 82 #include "CSKYGenMCCodeEmitter.inc" 83