Coverage Report

Created: 2025-08-28 06:43

/src/capstonenext/arch/Sparc/SparcDisassembler.c
Line
Count
Source (jump to first uncovered line)
1
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
2
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
3
/*    Rot127 <unisono@quyllur.org> 2022-2023 */
4
/* Automatically translated source file from LLVM. */
5
6
/* LLVM-commit: <commit> */
7
/* LLVM-tag: <tag> */
8
9
/* Only small edits allowed. */
10
/* For multiple similar edits, please create a Patch for the translator. */
11
12
/* Capstone's C++ file translator: */
13
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
14
15
//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
16
//
17
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
18
// See https://llvm.org/LICENSE.txt for license information.
19
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
20
//
21
//===----------------------------------------------------------------------===//
22
//
23
// This file is part of the Sparc Disassembler.
24
//
25
//===----------------------------------------------------------------------===//
26
27
#include <stdio.h>
28
#include <string.h>
29
#include <stdlib.h>
30
#include <capstone/platform.h>
31
32
#include "../../MCDisassembler.h"
33
#include "../../MCFixedLenDisassembler.h"
34
#include "SparcDisassemblerExtension.h"
35
#include "SparcLinkage.h"
36
#include "SparcMapping.h"
37
#include "SparcMCTargetDesc.h"
38
#define CONCAT(a, b) CONCAT_(a, b)
39
#define CONCAT_(a, b) a##_##b
40
41
#define DEBUG_TYPE "sparc-disassembler"
42
43
static const unsigned IntRegDecoderTable[] = {
44
  Sparc_G0, Sparc_G1, Sparc_G2, Sparc_G3, Sparc_G4, Sparc_G5, Sparc_G6,
45
  Sparc_G7, Sparc_O0, Sparc_O1, Sparc_O2, Sparc_O3, Sparc_O4, Sparc_O5,
46
  Sparc_O6, Sparc_O7, Sparc_L0, Sparc_L1, Sparc_L2, Sparc_L3, Sparc_L4,
47
  Sparc_L5, Sparc_L6, Sparc_L7, Sparc_I0, Sparc_I1, Sparc_I2, Sparc_I3,
48
  Sparc_I4, Sparc_I5, Sparc_I6, Sparc_I7
49
};
50
51
static const unsigned FPRegDecoderTable[] = {
52
  Sparc_F0,  Sparc_F1,  Sparc_F2,  Sparc_F3,  Sparc_F4,  Sparc_F5,
53
  Sparc_F6,  Sparc_F7,  Sparc_F8,  Sparc_F9,  Sparc_F10, Sparc_F11,
54
  Sparc_F12, Sparc_F13, Sparc_F14, Sparc_F15, Sparc_F16, Sparc_F17,
55
  Sparc_F18, Sparc_F19, Sparc_F20, Sparc_F21, Sparc_F22, Sparc_F23,
56
  Sparc_F24, Sparc_F25, Sparc_F26, Sparc_F27, Sparc_F28, Sparc_F29,
57
  Sparc_F30, Sparc_F31
58
};
59
60
static const unsigned DFPRegDecoderTable[] = {
61
  Sparc_D0,  Sparc_D16, Sparc_D1,  Sparc_D17, Sparc_D2,  Sparc_D18,
62
  Sparc_D3,  Sparc_D19, Sparc_D4,  Sparc_D20, Sparc_D5,  Sparc_D21,
63
  Sparc_D6,  Sparc_D22, Sparc_D7,  Sparc_D23, Sparc_D8,  Sparc_D24,
64
  Sparc_D9,  Sparc_D25, Sparc_D10, Sparc_D26, Sparc_D11, Sparc_D27,
65
  Sparc_D12, Sparc_D28, Sparc_D13, Sparc_D29, Sparc_D14, Sparc_D30,
66
  Sparc_D15, Sparc_D31
67
};
68
69
static const unsigned QFPRegDecoderTable[] = {
70
  Sparc_Q0, Sparc_Q8,  ~0U, ~0U, Sparc_Q1, Sparc_Q9,  ~0U, ~0U,
71
  Sparc_Q2, Sparc_Q10, ~0U, ~0U, Sparc_Q3, Sparc_Q11, ~0U, ~0U,
72
  Sparc_Q4, Sparc_Q12, ~0U, ~0U, Sparc_Q5, Sparc_Q13, ~0U, ~0U,
73
  Sparc_Q6, Sparc_Q14, ~0U, ~0U, Sparc_Q7, Sparc_Q15, ~0U, ~0U
74
};
75
76
static const unsigned FCCRegDecoderTable[] = { Sparc_FCC0, Sparc_FCC1,
77
                 Sparc_FCC2, Sparc_FCC3 };
78
79
static const unsigned ASRRegDecoderTable[] = {
80
  Sparc_Y,     Sparc_ASR1,  Sparc_ASR2,  Sparc_ASR3,  Sparc_ASR4,
81
  Sparc_ASR5,  Sparc_ASR6,  Sparc_ASR7,  Sparc_ASR8,  Sparc_ASR9,
82
  Sparc_ASR10, Sparc_ASR11, Sparc_ASR12, Sparc_ASR13, Sparc_ASR14,
83
  Sparc_ASR15, Sparc_ASR16, Sparc_ASR17, Sparc_ASR18, Sparc_ASR19,
84
  Sparc_ASR20, Sparc_ASR21, Sparc_ASR22, Sparc_ASR23, Sparc_ASR24,
85
  Sparc_ASR25, Sparc_ASR26, Sparc_ASR27, Sparc_ASR28, Sparc_ASR29,
86
  Sparc_ASR30, Sparc_ASR31
87
};
88
89
static const unsigned PRRegDecoderTable[] = {
90
  Sparc_TPC,  Sparc_TNPC, Sparc_TSTATE,  Sparc_TT,
91
  Sparc_TICK, Sparc_TBA,  Sparc_PSTATE,  Sparc_TL,
92
  Sparc_PIL,  Sparc_CWP,  Sparc_CANSAVE, Sparc_CANRESTORE,
93
  Sparc_CLEANWIN, Sparc_OTHERWIN, Sparc_WSTATE
94
};
95
96
static const uint16_t IntPairDecoderTable[] = {
97
  Sparc_G0_G1, Sparc_G2_G3, Sparc_G4_G5, Sparc_G6_G7,
98
  Sparc_O0_O1, Sparc_O2_O3, Sparc_O4_O5, Sparc_O6_O7,
99
  Sparc_L0_L1, Sparc_L2_L3, Sparc_L4_L5, Sparc_L6_L7,
100
  Sparc_I0_I1, Sparc_I2_I3, Sparc_I4_I5, Sparc_I6_I7,
101
};
102
103
static const unsigned CPRegDecoderTable[] = {
104
  Sparc_C0,  Sparc_C1,  Sparc_C2,  Sparc_C3,  Sparc_C4,  Sparc_C5,
105
  Sparc_C6,  Sparc_C7,  Sparc_C8,  Sparc_C9,  Sparc_C10, Sparc_C11,
106
  Sparc_C12, Sparc_C13, Sparc_C14, Sparc_C15, Sparc_C16, Sparc_C17,
107
  Sparc_C18, Sparc_C19, Sparc_C20, Sparc_C21, Sparc_C22, Sparc_C23,
108
  Sparc_C24, Sparc_C25, Sparc_C26, Sparc_C27, Sparc_C28, Sparc_C29,
109
  Sparc_C30, Sparc_C31
110
};
111
112
static const uint16_t CPPairDecoderTable[] = {
113
  Sparc_C0_C1,   Sparc_C2_C3,   Sparc_C4_C5,   Sparc_C6_C7,
114
  Sparc_C8_C9,   Sparc_C10_C11, Sparc_C12_C13, Sparc_C14_C15,
115
  Sparc_C16_C17, Sparc_C18_C19, Sparc_C20_C21, Sparc_C22_C23,
116
  Sparc_C24_C25, Sparc_C26_C27, Sparc_C28_C29, Sparc_C30_C31
117
};
118
119
static DecodeStatus DecodeDisp19(MCInst *Inst, uint32_t ImmVal,
120
         uint64_t Address, const void *Decoder)
121
7.04k
{
122
7.04k
  int64_t BranchTarget = Address + (SignExtend64(ImmVal, 19) * 4);
123
7.04k
  MCOperand_CreateImm0(Inst, BranchTarget);
124
7.04k
  return MCDisassembler_Success;
125
7.04k
}
126
127
static DecodeStatus DecodeDisp16(MCInst *Inst, uint32_t ImmVal,
128
         uint64_t Address, const void *Decoder)
129
1.68k
{
130
1.68k
  int64_t BranchTarget = Address + (SignExtend64(ImmVal, 16) * 4);
131
1.68k
  MCOperand_CreateImm0(Inst, BranchTarget);
132
1.68k
  return MCDisassembler_Success;
133
1.68k
}
134
135
static DecodeStatus DecodeDisp22(MCInst *Inst, uint32_t ImmVal,
136
         uint64_t Address, const void *Decoder)
137
6.03k
{
138
6.03k
  int64_t BranchTarget = Address + (SignExtend64(ImmVal, 22) * 4);
139
6.03k
  MCOperand_CreateImm0(Inst, BranchTarget);
140
6.03k
  return MCDisassembler_Success;
141
6.03k
}
142
143
static DecodeStatus DecodeIntRegsRegisterClass(MCInst *Inst, unsigned RegNo,
144
                 uint64_t Address,
145
                 const void *Decoder)
146
83.7k
{
147
83.7k
  if (RegNo > 31)
148
0
    return MCDisassembler_Fail;
149
83.7k
  unsigned Reg = IntRegDecoderTable[RegNo];
150
83.7k
  MCOperand_CreateReg0(Inst, (Reg));
151
83.7k
  return MCDisassembler_Success;
152
83.7k
}
153
154
static DecodeStatus DecodeI64RegsRegisterClass(MCInst *Inst, unsigned RegNo,
155
                 uint64_t Address,
156
                 const void *Decoder)
157
6.09k
{
158
6.09k
  return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
159
6.09k
}
160
161
// This is used for the type "ptr_rc", which is either IntRegs or I64Regs
162
// depending on SparcRegisterInfo::getPointerRegClass.
163
static DecodeStatus DecodePointerLikeRegClass0(MCInst *Inst, unsigned RegNo,
164
                 uint64_t Address,
165
                 const void *Decoder)
166
18.1k
{
167
18.1k
  return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
168
18.1k
}
169
170
static DecodeStatus DecodeFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
171
                uint64_t Address,
172
                const void *Decoder)
173
10.2k
{
174
10.2k
  if (RegNo > 31)
175
0
    return MCDisassembler_Fail;
176
10.2k
  unsigned Reg = FPRegDecoderTable[RegNo];
177
10.2k
  MCOperand_CreateReg0(Inst, (Reg));
178
10.2k
  return MCDisassembler_Success;
179
10.2k
}
180
181
static DecodeStatus DecodeDFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
182
                 uint64_t Address,
183
                 const void *Decoder)
184
7.36k
{
185
7.36k
  if (RegNo > 31)
186
0
    return MCDisassembler_Fail;
187
7.36k
  unsigned Reg = DFPRegDecoderTable[RegNo];
188
7.36k
  MCOperand_CreateReg0(Inst, (Reg));
189
7.36k
  return MCDisassembler_Success;
190
7.36k
}
191
192
static DecodeStatus DecodeQFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
193
                 uint64_t Address,
194
                 const void *Decoder)
195
8.32k
{
196
8.32k
  if (RegNo > 31)
197
0
    return MCDisassembler_Fail;
198
199
8.32k
  unsigned Reg = QFPRegDecoderTable[RegNo];
200
8.32k
  if (Reg == ~0U)
201
47
    return MCDisassembler_Fail;
202
8.28k
  MCOperand_CreateReg0(Inst, (Reg));
203
8.28k
  return MCDisassembler_Success;
204
8.32k
}
205
206
static DecodeStatus DecodeCoprocRegsRegisterClass(MCInst *Inst, unsigned RegNo,
207
              uint64_t Address,
208
              const void *Decoder)
209
352
{
210
352
  if (RegNo > 31)
211
0
    return MCDisassembler_Fail;
212
352
  unsigned Reg = CPRegDecoderTable[RegNo];
213
352
  MCOperand_CreateReg0(Inst, (Reg));
214
352
  return MCDisassembler_Success;
215
352
}
216
217
static DecodeStatus DecodeFCCRegsRegisterClass(MCInst *Inst, unsigned RegNo,
218
                 uint64_t Address,
219
                 const void *Decoder)
220
15.5k
{
221
15.5k
  if (RegNo > 3)
222
7
    return MCDisassembler_Fail;
223
15.5k
  MCOperand_CreateReg0(Inst, (FCCRegDecoderTable[RegNo]));
224
15.5k
  return MCDisassembler_Success;
225
15.5k
}
226
227
static DecodeStatus DecodeASRRegsRegisterClass(MCInst *Inst, unsigned RegNo,
228
                 uint64_t Address,
229
                 const void *Decoder)
230
302
{
231
302
  if (RegNo > 31)
232
0
    return MCDisassembler_Fail;
233
302
  MCOperand_CreateReg0(Inst, (ASRRegDecoderTable[RegNo]));
234
302
  return MCDisassembler_Success;
235
302
}
236
237
static DecodeStatus DecodePRRegsRegisterClass(MCInst *Inst, unsigned RegNo,
238
                uint64_t Address,
239
                const void *Decoder)
240
126
{
241
126
  if (RegNo >= ARR_SIZE(PRRegDecoderTable))
242
4
    return MCDisassembler_Fail;
243
122
  MCOperand_CreateReg0(Inst, (PRRegDecoderTable[RegNo]));
244
122
  return MCDisassembler_Success;
245
126
}
246
247
static DecodeStatus DecodeIntPairRegisterClass(MCInst *Inst, unsigned RegNo,
248
                 uint64_t Address,
249
                 const void *Decoder)
250
1.38k
{
251
1.38k
  DecodeStatus S = MCDisassembler_Success;
252
253
1.38k
  if (RegNo > 31)
254
0
    return MCDisassembler_Fail;
255
256
1.38k
  if ((RegNo & 1))
257
566
    S = MCDisassembler_SoftFail;
258
259
1.38k
  unsigned RegisterPair = IntPairDecoderTable[RegNo / 2];
260
1.38k
  MCOperand_CreateReg0(Inst, (RegisterPair));
261
1.38k
  return S;
262
1.38k
}
263
264
static DecodeStatus DecodeCoprocPairRegisterClass(MCInst *Inst, unsigned RegNo,
265
              uint64_t Address,
266
              const void *Decoder)
267
164
{
268
164
  if (RegNo > 31)
269
0
    return MCDisassembler_Fail;
270
271
164
  unsigned RegisterPair = CPPairDecoderTable[RegNo / 2];
272
164
  MCOperand_CreateReg0(Inst, (RegisterPair));
273
164
  return MCDisassembler_Success;
274
164
}
275
276
static DecodeStatus DecodeCall(MCInst *Inst, unsigned insn, uint64_t Address,
277
             const void *Decoder);
278
static DecodeStatus DecodeSIMM13(MCInst *Inst, unsigned insn, uint64_t Address,
279
         const void *Decoder);
280
281
#include "SparcGenDisassemblerTables.inc"
282
283
static DecodeStatus getInstruction(MCInst *Instr, uint64_t *Size,
284
           const uint8_t *Bytes, size_t BytesLen,
285
           uint64_t Address, SStream *CStream)
286
48.2k
{
287
48.2k
  if (BytesLen < 4) {
288
646
    return MCDisassembler_Fail;
289
646
  }
290
47.5k
  uint32_t Insn = readBytes32(Instr, Bytes);
291
292
47.5k
  DecodeStatus Result = MCDisassembler_Fail;
293
  // Calling the auto-generated decoder function.
294
47.5k
  if (Sparc_getFeatureBits(Instr->csh->mode, Sparc_FeatureV9)) {
295
42.2k
    Result = decodeInstruction_4(DecoderTableSparcV932, Instr, Insn,
296
42.2k
               Address, NULL);
297
42.2k
  } else {
298
5.30k
    Result = decodeInstruction_4(DecoderTableSparcV832, Instr, Insn,
299
5.30k
               Address, NULL);
300
5.30k
  }
301
47.5k
  if (Result != MCDisassembler_Fail) {
302
2.44k
    *Size = 4;
303
2.44k
    return Result;
304
2.44k
  }
305
306
45.1k
  Result = decodeInstruction_4(DecoderTableSparc32, Instr, Insn, Address,
307
45.1k
             NULL);
308
309
45.1k
  if (Result != MCDisassembler_Fail) {
310
44.7k
    *Size = 4;
311
44.7k
    return Result;
312
44.7k
  }
313
314
349
  return MCDisassembler_Fail;
315
45.1k
}
316
317
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
318
             uint64_t Address, uint64_t Offset,
319
             uint64_t Width, MCInst *MI,
320
             const void *Decoder)
321
4.51k
{
322
  // Capstone doesn't support symbols.
323
4.51k
  return false;
324
4.51k
}
325
326
static DecodeStatus DecodeCall(MCInst *MI, unsigned insn, uint64_t Address,
327
             const void *Decoder)
328
4.51k
{
329
4.51k
  unsigned Offset = fieldFromInstruction_4(insn, 0, 30);
330
4.51k
  int64_t CallTarget = Address + (SignExtend64(Offset, 30) * 4);
331
4.51k
  if (!tryAddingSymbolicOperand(CallTarget, false, Address, 0, 30, MI,
332
4.51k
              Decoder))
333
4.51k
    MCOperand_CreateImm0(MI, CallTarget);
334
4.51k
  return MCDisassembler_Success;
335
4.51k
}
336
337
static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn, uint64_t Address,
338
         const void *Decoder)
339
4.04k
{
340
4.04k
  CS_ASSERT(isUIntN(13, insn));
341
4.04k
  MCOperand_CreateImm0(MI, (SignExtend64((insn), 13)));
342
4.04k
  return MCDisassembler_Success;
343
4.04k
}
344
345
DecodeStatus Sparc_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
346
               size_t ByteLen, MCInst *MI,
347
               uint16_t *Size, uint64_t Address,
348
               void *Info)
349
48.2k
{
350
48.2k
  uint64_t s = 0;
351
48.2k
  DecodeStatus status =
352
48.2k
    getInstruction(MI, &s, Bytes, ByteLen, Address, NULL);
353
48.2k
  *Size = (uint16_t)s;
354
48.2k
  return status;
355
48.2k
}