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