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 #ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H
14 #define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H
15 
16 #include "CSKYMCExpr.h"
17 #include "MCTargetDesc/CSKYFixupKinds.h"
18 #include "llvm/MC/MCCodeEmitter.h"
19 #include "llvm/MC/MCContext.h"
20 
21 namespace llvm {
22 
23 class CSKYMCCodeEmitter : public MCCodeEmitter {
24   MCContext &Ctx;
25   const MCInstrInfo &MII;
26 
27 public:
28   CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII)
29       : Ctx(Ctx), MII(MII) {}
30 
31   ~CSKYMCCodeEmitter() {}
32 
33   void encodeInstruction(const MCInst &Inst, raw_ostream &OS,
34                          SmallVectorImpl<MCFixup> &Fixups,
35                          const MCSubtargetInfo &STI) const override;
36 
37   // Generated by tablegen.
38   uint64_t getBinaryCodeForInstr(const MCInst &MI,
39                                  SmallVectorImpl<MCFixup> &Fixups,
40                                  const MCSubtargetInfo &STI) const;
41 
42   // Default encoding method used by tablegen.
43   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
44                              SmallVectorImpl<MCFixup> &Fixups,
45                              const MCSubtargetInfo &STI) const;
46 
47   template <int shift = 0>
48   unsigned getImmOpValue(const MCInst &MI, unsigned Idx,
49                          SmallVectorImpl<MCFixup> &Fixups,
50                          const MCSubtargetInfo &STI) const {
51     const MCOperand &MO = MI.getOperand(Idx);
52     assert(MO.isImm() && "Unexpected MO type.");
53     return (MO.getImm() >> shift);
54   }
55 
56   unsigned getOImmOpValue(const MCInst &MI, unsigned Idx,
57                           SmallVectorImpl<MCFixup> &Fixups,
58                           const MCSubtargetInfo &STI) const;
59 
60   unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx,
61                               SmallVectorImpl<MCFixup> &Fixups,
62                               const MCSubtargetInfo &STI) const {
63     const MCOperand &MO = MI.getOperand(Idx);
64     assert(MO.isImm() && "Unexpected MO type.");
65     return 1 << MO.getImm();
66   }
67 
68   MCFixupKind getTargetFixup(const MCExpr *Expr) const;
69 
70   template <llvm::CSKY::Fixups FIXUP>
71   unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx,
72                                   SmallVectorImpl<MCFixup> &Fixups,
73                                   const MCSubtargetInfo &STI) const {
74     const MCOperand &MO = MI.getOperand(Idx);
75 
76     if (MO.isImm())
77       return MO.getImm() >> 1;
78 
79     assert(MO.isExpr() && "Unexpected MO type.");
80 
81     MCFixupKind Kind = MCFixupKind(FIXUP);
82     if (MO.getExpr()->getKind() == MCExpr::Target)
83       Kind = getTargetFixup(MO.getExpr());
84 
85     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
86     return 0;
87   }
88 
89   template <llvm::CSKY::Fixups FIXUP>
90   unsigned getConstpoolSymbolOpValue(const MCInst &MI, unsigned Idx,
91                                      SmallVectorImpl<MCFixup> &Fixups,
92                                      const MCSubtargetInfo &STI) const {
93     const MCOperand &MO = MI.getOperand(Idx);
94     assert(MO.isExpr() && "Unexpected MO type.");
95 
96     MCFixupKind Kind = MCFixupKind(FIXUP);
97     if (MO.getExpr()->getKind() == MCExpr::Target)
98       Kind = getTargetFixup(MO.getExpr());
99 
100     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
101     return 0;
102   }
103 
104   unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx,
105                                 SmallVectorImpl<MCFixup> &Fixups,
106                                 const MCSubtargetInfo &STI) const {
107     const MCOperand &MO = MI.getOperand(Idx);
108     assert(MO.isExpr() && "Unexpected MO type.");
109 
110     MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm26_scale2);
111     if (MO.getExpr()->getKind() == MCExpr::Target)
112       Kind = getTargetFixup(MO.getExpr());
113 
114     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
115     return 0;
116   }
117 
118   unsigned getBareSymbolOpValue(const MCInst &MI, unsigned Idx,
119                                 SmallVectorImpl<MCFixup> &Fixups,
120                                 const MCSubtargetInfo &STI) const {
121     const MCOperand &MO = MI.getOperand(Idx);
122     assert(MO.isExpr() && "Unexpected MO type.");
123 
124     MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm18_scale2);
125     if (MO.getExpr()->getKind() == MCExpr::Target)
126       Kind = getTargetFixup(MO.getExpr());
127 
128     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
129     return 0;
130   }
131 };
132 
133 } // namespace llvm
134 
135 #endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H
136