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 "CSKYMCExpr.h" 15 #include "MCTargetDesc/CSKYMCTargetDesc.h" 16 #include "llvm/ADT/Statistic.h" 17 #include "llvm/MC/MCInstBuilder.h" 18 #include "llvm/MC/MCInstrInfo.h" 19 #include "llvm/Support/EndianStream.h" 20 21 using namespace llvm; 22 23 #define DEBUG_TYPE "csky-mccode-emitter" 24 25 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 26 27 unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx, 28 SmallVectorImpl<MCFixup> &Fixups, 29 const MCSubtargetInfo &STI) const { 30 const MCOperand &MO = MI.getOperand(Idx); 31 assert(MO.isImm() && "Unexpected MO type."); 32 return MO.getImm() - 1; 33 } 34 35 unsigned 36 CSKYMCCodeEmitter::getImmOpValueIDLY(const MCInst &MI, unsigned Idx, 37 SmallVectorImpl<MCFixup> &Fixups, 38 const MCSubtargetInfo &STI) const { 39 const MCOperand &MO = MI.getOperand(Idx); 40 assert(MO.isImm() && "Unexpected MO type."); 41 42 auto V = (MO.getImm() <= 3) ? 4 : MO.getImm(); 43 return V - 1; 44 } 45 46 unsigned 47 CSKYMCCodeEmitter::getImmOpValueMSBSize(const MCInst &MI, unsigned Idx, 48 SmallVectorImpl<MCFixup> &Fixups, 49 const MCSubtargetInfo &STI) const { 50 const MCOperand &MSB = MI.getOperand(Idx); 51 const MCOperand &LSB = MI.getOperand(Idx + 1); 52 assert(MSB.isImm() && LSB.isImm() && "Unexpected MO type."); 53 54 return MSB.getImm() - LSB.getImm(); 55 } 56 57 static void writeData(uint32_t Bin, unsigned Size, raw_ostream &OS) { 58 uint16_t LO16 = static_cast<uint16_t>(Bin); 59 uint16_t HI16 = static_cast<uint16_t>(Bin >> 16); 60 61 if (Size == 4) 62 support::endian::write<uint16_t>(OS, HI16, support::little); 63 64 support::endian::write<uint16_t>(OS, LO16, support::little); 65 } 66 67 void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 68 SmallVectorImpl<MCFixup> &Fixups, 69 const MCSubtargetInfo &STI) const { 70 const MCInstrDesc &Desc = MII.get(MI.getOpcode()); 71 unsigned Size = Desc.getSize(); 72 73 ++MCNumEmitted; 74 75 uint32_t Bin = getBinaryCodeForInstr(MI, Fixups, STI); 76 77 uint16_t LO16 = static_cast<uint16_t>(Bin); 78 uint16_t HI16 = static_cast<uint16_t>(Bin >> 16); 79 80 if (Size == 4) 81 support::endian::write<uint16_t>(OS, HI16, support::little); 82 83 support::endian::write<uint16_t>(OS, LO16, support::little); 84 } 85 86 unsigned 87 CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 88 SmallVectorImpl<MCFixup> &Fixups, 89 const MCSubtargetInfo &STI) const { 90 if (MO.isReg()) 91 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 92 93 if (MO.isImm()) 94 return static_cast<unsigned>(MO.getImm()); 95 96 llvm_unreachable("Unhandled expression!"); 97 return 0; 98 } 99 100 unsigned 101 CSKYMCCodeEmitter::getRegSeqImmOpValue(const MCInst &MI, unsigned Idx, 102 SmallVectorImpl<MCFixup> &Fixups, 103 const MCSubtargetInfo &STI) const { 104 assert(MI.getOperand(Idx).isReg() && "Unexpected MO type."); 105 assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type."); 106 107 unsigned Ry = MI.getOperand(Idx).getReg(); 108 unsigned Rz = MI.getOperand(Idx + 1).getImm(); 109 110 unsigned Imm = Ctx.getRegisterInfo()->getEncodingValue(Rz) - 111 Ctx.getRegisterInfo()->getEncodingValue(Ry); 112 113 return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm); 114 } 115 116 unsigned 117 CSKYMCCodeEmitter::getRegisterSeqOpValue(const MCInst &MI, unsigned Op, 118 SmallVectorImpl<MCFixup> &Fixups, 119 const MCSubtargetInfo &STI) const { 120 unsigned Reg1 = 121 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op).getReg()); 122 unsigned Reg2 = 123 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op + 1).getReg()); 124 125 unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1); 126 127 return Binary; 128 } 129 130 unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx, 131 SmallVectorImpl<MCFixup> &Fixups, 132 const MCSubtargetInfo &STI) const { 133 if (MI.getOperand(Idx).getImm() == 16) 134 return 0; 135 else if (MI.getOperand(Idx).getImm() == 24) 136 return 1; 137 else if (MI.getOperand(Idx).getImm() == 32) 138 return 2; 139 else if (MI.getOperand(Idx).getImm() == 40) 140 return 3; 141 else 142 assert(0); 143 } 144 145 MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const { 146 const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr); 147 148 switch (CSKYExpr->getKind()) { 149 default: 150 llvm_unreachable("Unhandled fixup kind!"); 151 case CSKYMCExpr::VK_CSKY_ADDR: 152 return MCFixupKind(CSKY::fixup_csky_addr32); 153 case CSKYMCExpr::VK_CSKY_ADDR_HI16: 154 return MCFixupKind(CSKY::fixup_csky_addr_hi16); 155 case CSKYMCExpr::VK_CSKY_ADDR_LO16: 156 return MCFixupKind(CSKY::fixup_csky_addr_lo16); 157 case CSKYMCExpr::VK_CSKY_GOT: 158 return MCFixupKind(CSKY::fixup_csky_got32); 159 case CSKYMCExpr::VK_CSKY_GOTPC: 160 return MCFixupKind(CSKY::fixup_csky_gotpc); 161 case CSKYMCExpr::VK_CSKY_GOTOFF: 162 return MCFixupKind(CSKY::fixup_csky_gotoff); 163 case CSKYMCExpr::VK_CSKY_PLT: 164 return MCFixupKind(CSKY::fixup_csky_plt32); 165 case CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4: 166 return MCFixupKind(CSKY::fixup_csky_plt_imm18_scale4); 167 case CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4: 168 return MCFixupKind(CSKY::fixup_csky_got_imm18_scale4); 169 } 170 } 171 172 MCCodeEmitter *llvm::createCSKYMCCodeEmitter(const MCInstrInfo &MCII, 173 const MCRegisterInfo &MRI, 174 MCContext &Ctx) { 175 return new CSKYMCCodeEmitter(Ctx, MCII); 176 } 177 178 #include "CSKYGenMCCodeEmitter.inc" 179