1 //=- LoongArchMCCodeEmitter.cpp - Convert LoongArch code to machine code --===// 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 LoongArchMCCodeEmitter class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/LoongArchBaseInfo.h" 14 #include "MCTargetDesc/LoongArchMCTargetDesc.h" 15 #include "llvm/MC/MCCodeEmitter.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCInstBuilder.h" 18 #include "llvm/MC/MCInstrInfo.h" 19 #include "llvm/MC/MCRegisterInfo.h" 20 #include "llvm/Support/EndianStream.h" 21 22 using namespace llvm; 23 24 #define DEBUG_TYPE "mccodeemitter" 25 26 namespace { 27 class LoongArchMCCodeEmitter : public MCCodeEmitter { 28 LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete; 29 void operator=(const LoongArchMCCodeEmitter &) = delete; 30 MCContext &Ctx; 31 MCInstrInfo const &MCII; 32 33 public: 34 LoongArchMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII) 35 : Ctx(ctx), MCII(MCII) {} 36 37 ~LoongArchMCCodeEmitter() override {} 38 39 void encodeInstruction(const MCInst &MI, raw_ostream &OS, 40 SmallVectorImpl<MCFixup> &Fixups, 41 const MCSubtargetInfo &STI) const override; 42 43 /// TableGen'erated function for getting the binary encoding for an 44 /// instruction. 45 uint64_t getBinaryCodeForInstr(const MCInst &MI, 46 SmallVectorImpl<MCFixup> &Fixups, 47 const MCSubtargetInfo &STI) const; 48 49 /// Return binary encoding of operand. If the machine operand requires 50 /// relocation, record the relocation and return zero. 51 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 52 SmallVectorImpl<MCFixup> &Fixups, 53 const MCSubtargetInfo &STI) const; 54 }; 55 } // end anonymous namespace 56 57 unsigned 58 LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 59 SmallVectorImpl<MCFixup> &Fixups, 60 const MCSubtargetInfo &STI) const { 61 62 if (MO.isReg()) 63 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 64 65 if (MO.isImm()) 66 return static_cast<unsigned>(MO.getImm()); 67 68 llvm_unreachable("Unhandled expression!"); 69 return 0; 70 } 71 72 void LoongArchMCCodeEmitter::encodeInstruction( 73 const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, 74 const MCSubtargetInfo &STI) const { 75 const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 76 // Get byte count of instruction. 77 unsigned Size = Desc.getSize(); 78 79 switch (Size) { 80 default: 81 llvm_unreachable("Unhandled encodeInstruction length!"); 82 case 4: { 83 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 84 support::endian::write(OS, Bits, support::little); 85 break; 86 } 87 } 88 } 89 90 MCCodeEmitter *llvm::createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, 91 MCContext &Ctx) { 92 return new LoongArchMCCodeEmitter(Ctx, MCII); 93 } 94 95 #include "LoongArchGenMCCodeEmitter.inc" 96