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