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 
getOImmOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const26 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 
encodeInstruction(const MCInst & MI,raw_ostream & OS,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const34 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
getMachineOpValue(const MCInst & MI,const MCOperand & MO,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const52 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 
getTargetFixup(const MCExpr * Expr) const65 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 
createCSKYMCCodeEmitter(const MCInstrInfo & MCII,const MCRegisterInfo & MRI,MCContext & Ctx)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