Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
35293 views
1
//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
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 is part of the Sparc Disassembler.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "MCTargetDesc/SparcMCTargetDesc.h"
14
#include "TargetInfo/SparcTargetInfo.h"
15
#include "llvm/MC/MCAsmInfo.h"
16
#include "llvm/MC/MCContext.h"
17
#include "llvm/MC/MCDecoderOps.h"
18
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
19
#include "llvm/MC/MCInst.h"
20
#include "llvm/MC/TargetRegistry.h"
21
22
using namespace llvm;
23
24
#define DEBUG_TYPE "sparc-disassembler"
25
26
typedef MCDisassembler::DecodeStatus DecodeStatus;
27
28
namespace {
29
30
/// A disassembler class for Sparc.
31
class SparcDisassembler : public MCDisassembler {
32
public:
33
SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
34
: MCDisassembler(STI, Ctx) {}
35
virtual ~SparcDisassembler() = default;
36
37
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
38
ArrayRef<uint8_t> Bytes, uint64_t Address,
39
raw_ostream &CStream) const override;
40
};
41
}
42
43
static MCDisassembler *createSparcDisassembler(const Target &T,
44
const MCSubtargetInfo &STI,
45
MCContext &Ctx) {
46
return new SparcDisassembler(STI, Ctx);
47
}
48
49
50
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcDisassembler() {
51
// Register the disassembler.
52
TargetRegistry::RegisterMCDisassembler(getTheSparcTarget(),
53
createSparcDisassembler);
54
TargetRegistry::RegisterMCDisassembler(getTheSparcV9Target(),
55
createSparcDisassembler);
56
TargetRegistry::RegisterMCDisassembler(getTheSparcelTarget(),
57
createSparcDisassembler);
58
}
59
60
static const unsigned IntRegDecoderTable[] = {
61
SP::G0, SP::G1, SP::G2, SP::G3,
62
SP::G4, SP::G5, SP::G6, SP::G7,
63
SP::O0, SP::O1, SP::O2, SP::O3,
64
SP::O4, SP::O5, SP::O6, SP::O7,
65
SP::L0, SP::L1, SP::L2, SP::L3,
66
SP::L4, SP::L5, SP::L6, SP::L7,
67
SP::I0, SP::I1, SP::I2, SP::I3,
68
SP::I4, SP::I5, SP::I6, SP::I7 };
69
70
static const unsigned FPRegDecoderTable[] = {
71
SP::F0, SP::F1, SP::F2, SP::F3,
72
SP::F4, SP::F5, SP::F6, SP::F7,
73
SP::F8, SP::F9, SP::F10, SP::F11,
74
SP::F12, SP::F13, SP::F14, SP::F15,
75
SP::F16, SP::F17, SP::F18, SP::F19,
76
SP::F20, SP::F21, SP::F22, SP::F23,
77
SP::F24, SP::F25, SP::F26, SP::F27,
78
SP::F28, SP::F29, SP::F30, SP::F31 };
79
80
static const unsigned DFPRegDecoderTable[] = {
81
SP::D0, SP::D16, SP::D1, SP::D17,
82
SP::D2, SP::D18, SP::D3, SP::D19,
83
SP::D4, SP::D20, SP::D5, SP::D21,
84
SP::D6, SP::D22, SP::D7, SP::D23,
85
SP::D8, SP::D24, SP::D9, SP::D25,
86
SP::D10, SP::D26, SP::D11, SP::D27,
87
SP::D12, SP::D28, SP::D13, SP::D29,
88
SP::D14, SP::D30, SP::D15, SP::D31 };
89
90
static const unsigned QFPRegDecoderTable[] = {
91
SP::Q0, SP::Q8, ~0U, ~0U,
92
SP::Q1, SP::Q9, ~0U, ~0U,
93
SP::Q2, SP::Q10, ~0U, ~0U,
94
SP::Q3, SP::Q11, ~0U, ~0U,
95
SP::Q4, SP::Q12, ~0U, ~0U,
96
SP::Q5, SP::Q13, ~0U, ~0U,
97
SP::Q6, SP::Q14, ~0U, ~0U,
98
SP::Q7, SP::Q15, ~0U, ~0U } ;
99
100
static const unsigned FCCRegDecoderTable[] = {
101
SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
102
103
static const unsigned ASRRegDecoderTable[] = {
104
SP::Y, SP::ASR1, SP::ASR2, SP::ASR3, SP::ASR4, SP::ASR5, SP::ASR6,
105
SP::ASR7, SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11, SP::ASR12, SP::ASR13,
106
SP::ASR14, SP::ASR15, SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, SP::ASR20,
107
SP::ASR21, SP::ASR22, SP::ASR23, SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
108
SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
109
110
static const unsigned PRRegDecoderTable[] = {
111
SP::TPC, SP::TNPC, SP::TSTATE, SP::TT, SP::TICK,
112
SP::TBA, SP::PSTATE, SP::TL, SP::PIL, SP::CWP,
113
SP::CANSAVE, SP::CANRESTORE, SP::CLEANWIN, SP::OTHERWIN, SP::WSTATE};
114
115
static const uint16_t IntPairDecoderTable[] = {
116
SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7,
117
SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7,
118
SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7,
119
SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7,
120
};
121
122
static const unsigned CPRegDecoderTable[] = {
123
SP::C0, SP::C1, SP::C2, SP::C3,
124
SP::C4, SP::C5, SP::C6, SP::C7,
125
SP::C8, SP::C9, SP::C10, SP::C11,
126
SP::C12, SP::C13, SP::C14, SP::C15,
127
SP::C16, SP::C17, SP::C18, SP::C19,
128
SP::C20, SP::C21, SP::C22, SP::C23,
129
SP::C24, SP::C25, SP::C26, SP::C27,
130
SP::C28, SP::C29, SP::C30, SP::C31
131
};
132
133
134
static const uint16_t CPPairDecoderTable[] = {
135
SP::C0_C1, SP::C2_C3, SP::C4_C5, SP::C6_C7,
136
SP::C8_C9, SP::C10_C11, SP::C12_C13, SP::C14_C15,
137
SP::C16_C17, SP::C18_C19, SP::C20_C21, SP::C22_C23,
138
SP::C24_C25, SP::C26_C27, SP::C28_C29, SP::C30_C31
139
};
140
141
static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
142
uint64_t Address,
143
const MCDisassembler *Decoder) {
144
if (RegNo > 31)
145
return MCDisassembler::Fail;
146
unsigned Reg = IntRegDecoderTable[RegNo];
147
Inst.addOperand(MCOperand::createReg(Reg));
148
return MCDisassembler::Success;
149
}
150
151
static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, unsigned RegNo,
152
uint64_t Address,
153
const MCDisassembler *Decoder) {
154
return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
155
}
156
157
// This is used for the type "ptr_rc", which is either IntRegs or I64Regs
158
// depending on SparcRegisterInfo::getPointerRegClass.
159
static DecodeStatus DecodePointerLikeRegClass0(MCInst &Inst, unsigned RegNo,
160
uint64_t Address,
161
const MCDisassembler *Decoder) {
162
return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
163
}
164
165
static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,
166
uint64_t Address,
167
const MCDisassembler *Decoder) {
168
if (RegNo > 31)
169
return MCDisassembler::Fail;
170
unsigned Reg = FPRegDecoderTable[RegNo];
171
Inst.addOperand(MCOperand::createReg(Reg));
172
return MCDisassembler::Success;
173
}
174
175
static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,
176
uint64_t Address,
177
const MCDisassembler *Decoder) {
178
if (RegNo > 31)
179
return MCDisassembler::Fail;
180
unsigned Reg = DFPRegDecoderTable[RegNo];
181
Inst.addOperand(MCOperand::createReg(Reg));
182
return MCDisassembler::Success;
183
}
184
185
static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,
186
uint64_t Address,
187
const MCDisassembler *Decoder) {
188
if (RegNo > 31)
189
return MCDisassembler::Fail;
190
191
unsigned Reg = QFPRegDecoderTable[RegNo];
192
if (Reg == ~0U)
193
return MCDisassembler::Fail;
194
Inst.addOperand(MCOperand::createReg(Reg));
195
return MCDisassembler::Success;
196
}
197
198
static DecodeStatus
199
DecodeCoprocRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
200
const MCDisassembler *Decoder) {
201
if (RegNo > 31)
202
return MCDisassembler::Fail;
203
unsigned Reg = CPRegDecoderTable[RegNo];
204
Inst.addOperand(MCOperand::createReg(Reg));
205
return MCDisassembler::Success;
206
}
207
208
static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
209
uint64_t Address,
210
const MCDisassembler *Decoder) {
211
if (RegNo > 3)
212
return MCDisassembler::Fail;
213
Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));
214
return MCDisassembler::Success;
215
}
216
217
static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
218
uint64_t Address,
219
const MCDisassembler *Decoder) {
220
if (RegNo > 31)
221
return MCDisassembler::Fail;
222
Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));
223
return MCDisassembler::Success;
224
}
225
226
static DecodeStatus DecodePRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
227
uint64_t Address,
228
const MCDisassembler *Decoder) {
229
if (RegNo >= std::size(PRRegDecoderTable))
230
return MCDisassembler::Fail;
231
Inst.addOperand(MCOperand::createReg(PRRegDecoderTable[RegNo]));
232
return MCDisassembler::Success;
233
}
234
235
static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo,
236
uint64_t Address,
237
const MCDisassembler *Decoder) {
238
DecodeStatus S = MCDisassembler::Success;
239
240
if (RegNo > 31)
241
return MCDisassembler::Fail;
242
243
if ((RegNo & 1))
244
S = MCDisassembler::SoftFail;
245
246
unsigned RegisterPair = IntPairDecoderTable[RegNo/2];
247
Inst.addOperand(MCOperand::createReg(RegisterPair));
248
return S;
249
}
250
251
static DecodeStatus
252
DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
253
const MCDisassembler *Decoder) {
254
if (RegNo > 31)
255
return MCDisassembler::Fail;
256
257
unsigned RegisterPair = CPPairDecoderTable[RegNo/2];
258
Inst.addOperand(MCOperand::createReg(RegisterPair));
259
return MCDisassembler::Success;
260
}
261
262
static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address,
263
const MCDisassembler *Decoder);
264
static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address,
265
const MCDisassembler *Decoder);
266
267
#include "SparcGenDisassemblerTables.inc"
268
269
/// Read four bytes from the ArrayRef and return 32 bit word.
270
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
271
uint64_t &Size, uint32_t &Insn,
272
bool IsLittleEndian) {
273
// We want to read exactly 4 Bytes of data.
274
if (Bytes.size() < 4) {
275
Size = 0;
276
return MCDisassembler::Fail;
277
}
278
279
Insn = IsLittleEndian
280
? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
281
(Bytes[3] << 24)
282
: (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
283
(Bytes[0] << 24);
284
285
return MCDisassembler::Success;
286
}
287
288
DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
289
ArrayRef<uint8_t> Bytes,
290
uint64_t Address,
291
raw_ostream &CStream) const {
292
uint32_t Insn;
293
bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
294
DecodeStatus Result =
295
readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
296
if (Result == MCDisassembler::Fail)
297
return MCDisassembler::Fail;
298
299
// Calling the auto-generated decoder function.
300
301
if (STI.hasFeature(Sparc::FeatureV9))
302
{
303
Result = decodeInstruction(DecoderTableSparcV932, Instr, Insn, Address, this, STI);
304
}
305
else
306
{
307
Result = decodeInstruction(DecoderTableSparcV832, Instr, Insn, Address, this, STI);
308
}
309
if (Result != MCDisassembler::Fail) {
310
Size = 4;
311
return Result;
312
}
313
314
Result =
315
decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
316
317
if (Result != MCDisassembler::Fail) {
318
Size = 4;
319
return Result;
320
}
321
322
return MCDisassembler::Fail;
323
}
324
325
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
326
uint64_t Address, uint64_t Offset,
327
uint64_t Width, MCInst &MI,
328
const MCDisassembler *Decoder) {
329
return Decoder->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset,
330
Width, /*InstSize=*/4);
331
}
332
333
static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,
334
const MCDisassembler *Decoder) {
335
unsigned tgt = fieldFromInstruction(insn, 0, 30);
336
tgt <<= 2;
337
if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
338
0, 30, MI, Decoder))
339
MI.addOperand(MCOperand::createImm(tgt));
340
return MCDisassembler::Success;
341
}
342
343
static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,
344
const MCDisassembler *Decoder) {
345
assert(isUInt<13>(insn));
346
MI.addOperand(MCOperand::createImm(SignExtend64<13>(insn)));
347
return MCDisassembler::Success;
348
}
349
350