LLVM: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
31#include
32#include
33
34using namespace llvm;
35
36#define DEBUG_TYPE "mccodeemitter"
37
38STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
39
40namespace {
41
44
45public:
47 : Ctx(ctx) {}
48 SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete;
49 SparcMCCodeEmitter &operator=(const SparcMCCodeEmitter &) = delete;
50 ~SparcMCCodeEmitter() override = default;
51
52 void encodeInstruction(const MCInst &MI, SmallVectorImpl &CB,
53 SmallVectorImpl &Fixups,
54 const MCSubtargetInfo &STI) const override;
55
56
57
58 uint64_t getBinaryCodeForInstr(const MCInst &MI,
59 SmallVectorImpl &Fixups,
60 const MCSubtargetInfo &STI) const;
61
62
63
64 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
65 SmallVectorImpl &Fixups,
66 const MCSubtargetInfo &STI) const;
67 unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
68 SmallVectorImpl &Fixups,
69 const MCSubtargetInfo &STI) const;
71 SmallVectorImpl &Fixups,
72 const MCSubtargetInfo &STI) const;
73 unsigned getSImm5OpValue(const MCInst &MI, unsigned OpNo,
74 SmallVectorImpl &Fixups,
75 const MCSubtargetInfo &STI) const;
76 unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo,
77 SmallVectorImpl &Fixups,
78 const MCSubtargetInfo &STI) const;
79 unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
80 SmallVectorImpl &Fixups,
81 const MCSubtargetInfo &STI) const;
82 unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
83 SmallVectorImpl &Fixups,
84 const MCSubtargetInfo &STI) const;
85 unsigned getCompareAndBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
86 SmallVectorImpl &Fixups,
87 const MCSubtargetInfo &STI) const;
88};
89
90}
91
94 bool PCRel = false;
95 switch (Kind) {
96 case ELF::R_SPARC_PC10:
97 case ELF::R_SPARC_PC22:
98 case ELF::R_SPARC_WDISP10:
99 case ELF::R_SPARC_WDISP16:
100 case ELF::R_SPARC_WDISP19:
101 case ELF::R_SPARC_WDISP22:
103 PCRel = true;
104 }
106}
107
108void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI,
112 unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);
117
118
119 unsigned SymOpNo = 0;
120 switch (MI.getOpcode()) {
121 default: break;
122 case SP::TLS_CALL: SymOpNo = 1; break;
123 case SP::GDOP_LDrr:
124 case SP::GDOP_LDXrr:
125 case SP::TLS_ADDrr:
126 case SP::TLS_LDrr:
127 case SP::TLS_LDXrr: SymOpNo = 3; break;
128 }
129 if (SymOpNo != 0) {
130 const MCOperand &MO = MI.getOperand(SymOpNo);
131 uint64_t op = getMachineOpValue(MI, MO, Fixups, STI);
132 assert(op == 0 && "Unexpected operand value!");
133 (void)op;
134 }
135
136 ++MCNumEmitted;
137}
138
139unsigned SparcMCCodeEmitter::
140getMachineOpValue(const MCInst &MI, const MCOperand &MO,
141 SmallVectorImpl &Fixups,
142 const MCSubtargetInfo &STI) const {
145
148
150 const MCExpr *Expr = MO.getExpr();
152 addFixup(Fixups, 0, Expr, SExpr->getSpecifier());
153 return 0;
154 }
155
156 int64_t Res;
157 if (Expr->evaluateAsAbsolute(Res))
158 return Res;
159
161 return 0;
162}
163
164unsigned SparcMCCodeEmitter::getSImm5OpValue(const MCInst &MI, unsigned OpNo,
165 SmallVectorImpl &Fixups,
166 const MCSubtargetInfo &STI) const {
167 const MCOperand &MO = MI.getOperand(OpNo);
168
171
173 "getSImm5OpValue expects only expressions or an immediate");
174
175 const MCExpr *Expr = MO.getExpr();
176
177
179 return CE->getValue();
180
182 addFixup(Fixups, 0, Expr, SExpr->getSpecifier());
183 return 0;
184 }
185 addFixup(Fixups, 0, Expr, ELF::R_SPARC_5);
186 return 0;
187}
188
189unsigned
190SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
191 SmallVectorImpl &Fixups,
192 const MCSubtargetInfo &STI) const {
193 const MCOperand &MO = MI.getOperand(OpNo);
194
197
199 "getSImm13OpValue expects only expressions or an immediate");
200
201 const MCExpr *Expr = MO.getExpr();
202
203
205 return CE->getValue();
206
208 addFixup(Fixups, 0, Expr, SExpr->getSpecifier());
209 return 0;
210 }
212 return 0;
213}
214
215unsigned SparcMCCodeEmitter::
216getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
217 SmallVectorImpl &Fixups,
218 const MCSubtargetInfo &STI) const {
219 if (MI.getOpcode() == SP::TLS_CALL) {
220
221
222 return 0;
223 }
224
225 const MCOperand &MO = MI.getOperand(OpNo);
227 return 0;
228}
229
230unsigned SparcMCCodeEmitter::
231getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
232 SmallVectorImpl &Fixups,
233 const MCSubtargetInfo &STI) const {
234 const MCOperand &MO = MI.getOperand(OpNo);
236 return getMachineOpValue(MI, MO, Fixups, STI);
237
239 return 0;
240}
241
242unsigned SparcMCCodeEmitter::getBranchPredTargetOpValue(
243 const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups,
244 const MCSubtargetInfo &STI) const {
245 const MCOperand &MO = MI.getOperand(OpNo);
247 return getMachineOpValue(MI, MO, Fixups, STI);
248
250 return 0;
251}
252
253unsigned SparcMCCodeEmitter::getBranchOnRegTargetOpValue(
254 const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups,
255 const MCSubtargetInfo &STI) const {
256 const MCOperand &MO = MI.getOperand(OpNo);
258 return getMachineOpValue(MI, MO, Fixups, STI);
259
261 return 0;
262}
263
264unsigned SparcMCCodeEmitter::getCompareAndBranchTargetOpValue(
265 const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups,
266 const MCSubtargetInfo &STI) const {
267 const MCOperand &MO = MI.getOperand(OpNo);
269 return getMachineOpValue(MI, MO, Fixups, STI);
270
272 return 0;
273}
274
275#include "SparcGenMCCodeEmitter.inc"
276
279 return new SparcMCCodeEmitter(MCII, Ctx);
280}
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)
getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
bool isLittleEndian() const
True if the target is little endian.
MCCodeEmitter - Generic instruction encoding interface.
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
const MCAsmInfo * getAsmInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Instances of this class represent a single low-level machine instruction.
Interface to description of machine instruction set.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Generic base class for all target subtargets.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_sparc_13
fixup_sparc_13 - 13-bit fixup
@ CE
Windows NT (Windows on ARM)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)
MCCodeEmitter * createSparcMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
Definition SparcMCCodeEmitter.cpp:277