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 MCInstrInfo;
24 
25 class CSKYMCCodeEmitter : public MCCodeEmitter {
26   MCContext &Ctx;
27   const MCInstrInfo &MII;
28 
29 public:
30   CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII)
31       : Ctx(Ctx), MII(MII) {}
32 
33   ~CSKYMCCodeEmitter() {}
34 
35   void encodeInstruction(const MCInst &Inst, raw_ostream &OS,
36                          SmallVectorImpl<MCFixup> &Fixups,
37                          const MCSubtargetInfo &STI) const override;
38 
39   // Generated by tablegen.
40   uint64_t getBinaryCodeForInstr(const MCInst &MI,
41                                  SmallVectorImpl<MCFixup> &Fixups,
42                                  const MCSubtargetInfo &STI) const;
43 
44   // Default encoding method used by tablegen.
45   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
46                              SmallVectorImpl<MCFixup> &Fixups,
47                              const MCSubtargetInfo &STI) const;
48 
49   template <int shift = 0>
50   unsigned getImmOpValue(const MCInst &MI, unsigned Idx,
51                          SmallVectorImpl<MCFixup> &Fixups,
52                          const MCSubtargetInfo &STI) const {
53     const MCOperand &MO = MI.getOperand(Idx);
54     if (MO.isImm())
55       return (MO.getImm() >> shift);
56 
57     assert(MO.isExpr() && "Unexpected MO type.");
58 
59     MCFixupKind Kind = getTargetFixup(MO.getExpr());
60     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
61     return 0;
62   }
63 
64   unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,
65                                SmallVectorImpl<MCFixup> &Fixups,
66                                const MCSubtargetInfo &STI) const;
67 
68   unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op,
69                                  SmallVectorImpl<MCFixup> &Fixups,
70                                  const MCSubtargetInfo &STI) const;
71 
72   unsigned getOImmOpValue(const MCInst &MI, unsigned Idx,
73                           SmallVectorImpl<MCFixup> &Fixups,
74                           const MCSubtargetInfo &STI) const;
75 
76   unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx,
77                              SmallVectorImpl<MCFixup> &Fixups,
78                              const MCSubtargetInfo &STI) const;
79 
80   unsigned getImmJMPIX(const MCInst &MI, unsigned Idx,
81                        SmallVectorImpl<MCFixup> &Fixups,
82                        const MCSubtargetInfo &STI) const;
83 
84   unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,
85                                 SmallVectorImpl<MCFixup> &Fixups,
86                                 const MCSubtargetInfo &STI) const;
87 
88   unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx,
89                               SmallVectorImpl<MCFixup> &Fixups,
90                               const MCSubtargetInfo &STI) const {
91     const MCOperand &MO = MI.getOperand(Idx);
92     assert(MO.isImm() && "Unexpected MO type.");
93     return 1 << MO.getImm();
94   }
95 
96   MCFixupKind getTargetFixup(const MCExpr *Expr) const;
97 
98   template <llvm::CSKY::Fixups FIXUP>
99   unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx,
100                                   SmallVectorImpl<MCFixup> &Fixups,
101                                   const MCSubtargetInfo &STI) const {
102     const MCOperand &MO = MI.getOperand(Idx);
103 
104     if (MO.isImm())
105       return MO.getImm() >> 1;
106 
107     assert(MO.isExpr() && "Unexpected MO type.");
108 
109     MCFixupKind Kind = MCFixupKind(FIXUP);
110     if (MO.getExpr()->getKind() == MCExpr::Target)
111       Kind = getTargetFixup(MO.getExpr());
112 
113     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
114     return 0;
115   }
116 
117   template <llvm::CSKY::Fixups FIXUP>
118   unsigned getConstpoolSymbolOpValue(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(FIXUP);
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   template <llvm::CSKY::Fixups FIXUP>
133   unsigned getDataSymbolOpValue(const MCInst &MI, unsigned Idx,
134                                 SmallVectorImpl<MCFixup> &Fixups,
135                                 const MCSubtargetInfo &STI) const {
136     const MCOperand &MO = MI.getOperand(Idx);
137     assert(MO.isExpr() && "Unexpected MO type.");
138 
139     MCFixupKind Kind = MCFixupKind(FIXUP);
140     if (MO.getExpr()->getKind() == MCExpr::Target)
141       Kind = getTargetFixup(MO.getExpr());
142 
143     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
144     return 0;
145   }
146 
147   unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx,
148                                 SmallVectorImpl<MCFixup> &Fixups,
149                                 const MCSubtargetInfo &STI) const {
150     const MCOperand &MO = MI.getOperand(Idx);
151     assert(MO.isExpr() && "Unexpected MO type.");
152 
153     MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm26_scale2);
154     if (MO.getExpr()->getKind() == MCExpr::Target)
155       Kind = getTargetFixup(MO.getExpr());
156 
157     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
158     return 0;
159   }
160 
161   unsigned getBareSymbolOpValue(const MCInst &MI, unsigned Idx,
162                                 SmallVectorImpl<MCFixup> &Fixups,
163                                 const MCSubtargetInfo &STI) const {
164     const MCOperand &MO = MI.getOperand(Idx);
165     assert(MO.isExpr() && "Unexpected MO type.");
166 
167     MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm18_scale2);
168     if (MO.getExpr()->getKind() == MCExpr::Target)
169       Kind = getTargetFixup(MO.getExpr());
170 
171     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
172     return 0;
173   }
174 
175   void expandJBTF(const MCInst &MI, raw_ostream &OS,
176                   SmallVectorImpl<MCFixup> &Fixups,
177                   const MCSubtargetInfo &STI) const;
178   void expandNEG(const MCInst &MI, raw_ostream &OS,
179                  SmallVectorImpl<MCFixup> &Fixups,
180                  const MCSubtargetInfo &STI) const;
181   void expandRSUBI(const MCInst &MI, raw_ostream &OS,
182                    SmallVectorImpl<MCFixup> &Fixups,
183                    const MCSubtargetInfo &STI) const;
184 };
185 
186 } // namespace llvm
187 
188 #endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H
189