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 "MCTargetDesc/CSKYFixupKinds.h"
17 #include "MCTargetDesc/CSKYMCExpr.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     if (MO.isImm())
53       return (MO.getImm() >> shift);
54 
55     assert(MO.isExpr() && "Unexpected MO type.");
56 
57     MCFixupKind Kind = getTargetFixup(MO.getExpr());
58     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
59     return 0;
60   }
61 
62   unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,
63                                SmallVectorImpl<MCFixup> &Fixups,
64                                const MCSubtargetInfo &STI) const;
65 
66   unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op,
67                                  SmallVectorImpl<MCFixup> &Fixups,
68                                  const MCSubtargetInfo &STI) const;
69 
70   unsigned getOImmOpValue(const MCInst &MI, unsigned Idx,
71                           SmallVectorImpl<MCFixup> &Fixups,
72                           const MCSubtargetInfo &STI) const;
73 
74   unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx,
75                              SmallVectorImpl<MCFixup> &Fixups,
76                              const MCSubtargetInfo &STI) const;
77 
78   unsigned getImmJMPIX(const MCInst &MI, unsigned Idx,
79                        SmallVectorImpl<MCFixup> &Fixups,
80                        const MCSubtargetInfo &STI) const;
81 
82   unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,
83                                 SmallVectorImpl<MCFixup> &Fixups,
84                                 const MCSubtargetInfo &STI) const;
85 
86   unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx,
87                               SmallVectorImpl<MCFixup> &Fixups,
88                               const MCSubtargetInfo &STI) const {
89     const MCOperand &MO = MI.getOperand(Idx);
90     assert(MO.isImm() && "Unexpected MO type.");
91     return 1 << MO.getImm();
92   }
93 
94   MCFixupKind getTargetFixup(const MCExpr *Expr) const;
95 
96   template <llvm::CSKY::Fixups FIXUP>
97   unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx,
98                                   SmallVectorImpl<MCFixup> &Fixups,
99                                   const MCSubtargetInfo &STI) const {
100     const MCOperand &MO = MI.getOperand(Idx);
101 
102     if (MO.isImm())
103       return MO.getImm() >> 1;
104 
105     assert(MO.isExpr() && "Unexpected MO type.");
106 
107     MCFixupKind Kind = MCFixupKind(FIXUP);
108     if (MO.getExpr()->getKind() == MCExpr::Target)
109       Kind = getTargetFixup(MO.getExpr());
110 
111     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
112     return 0;
113   }
114 
115   template <llvm::CSKY::Fixups FIXUP>
116   unsigned getConstpoolSymbolOpValue(const MCInst &MI, unsigned Idx,
117                                      SmallVectorImpl<MCFixup> &Fixups,
118                                      const MCSubtargetInfo &STI) const {
119     const MCOperand &MO = MI.getOperand(Idx);
120     assert(MO.isExpr() && "Unexpected MO type.");
121 
122     MCFixupKind Kind = MCFixupKind(FIXUP);
123     if (MO.getExpr()->getKind() == MCExpr::Target)
124       Kind = getTargetFixup(MO.getExpr());
125 
126     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
127     return 0;
128   }
129 
130   template <llvm::CSKY::Fixups FIXUP>
131   unsigned getDataSymbolOpValue(const MCInst &MI, unsigned Idx,
132                                 SmallVectorImpl<MCFixup> &Fixups,
133                                 const MCSubtargetInfo &STI) const {
134     const MCOperand &MO = MI.getOperand(Idx);
135     assert(MO.isExpr() && "Unexpected MO type.");
136 
137     MCFixupKind Kind = MCFixupKind(FIXUP);
138     if (MO.getExpr()->getKind() == MCExpr::Target)
139       Kind = getTargetFixup(MO.getExpr());
140 
141     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
142     return 0;
143   }
144 
145   unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx,
146                                 SmallVectorImpl<MCFixup> &Fixups,
147                                 const MCSubtargetInfo &STI) const {
148     const MCOperand &MO = MI.getOperand(Idx);
149     assert(MO.isExpr() && "Unexpected MO type.");
150 
151     MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm26_scale2);
152     if (MO.getExpr()->getKind() == MCExpr::Target)
153       Kind = getTargetFixup(MO.getExpr());
154 
155     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
156     return 0;
157   }
158 
159   unsigned getBareSymbolOpValue(const MCInst &MI, unsigned Idx,
160                                 SmallVectorImpl<MCFixup> &Fixups,
161                                 const MCSubtargetInfo &STI) const {
162     const MCOperand &MO = MI.getOperand(Idx);
163     assert(MO.isExpr() && "Unexpected MO type.");
164 
165     MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm18_scale2);
166     if (MO.getExpr()->getKind() == MCExpr::Target)
167       Kind = getTargetFixup(MO.getExpr());
168 
169     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
170     return 0;
171   }
172 };
173 
174 } // namespace llvm
175 
176 #endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H
177