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
21namespace llvm {
22
23class MCInstrInfo;
24
25class CSKYMCCodeEmitter : public MCCodeEmitter {
26  MCContext &Ctx;
27  const MCInstrInfo &MII;
28
29public:
30  CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII)
31      : Ctx(Ctx), MII(MII) {}
32
33  ~CSKYMCCodeEmitter() {}
34
35  void encodeInstruction(const MCInst &Inst, SmallVectorImpl<char> &CB,
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, SmallVectorImpl<char> &CB,
176                  SmallVectorImpl<MCFixup> &Fixups,
177                  const MCSubtargetInfo &STI) const;
178  void expandNEG(const MCInst &MI, SmallVectorImpl<char> &CB,
179                 SmallVectorImpl<MCFixup> &Fixups,
180                 const MCSubtargetInfo &STI) const;
181  void expandRSUBI(const MCInst &MI, SmallVectorImpl<char> &CB,
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