Coverage Report

Created: 2025-07-11 06:32

/src/capstonenext/arch/PowerPC/PPCDisassembler.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
//===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- 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
#include <capstone/platform.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
28
#include "../../LEB128.h"
29
#include "../../MCDisassembler.h"
30
#include "../../MCFixedLenDisassembler.h"
31
#include "../../MCInst.h"
32
#include "../../MCInstPrinter.h"
33
#include "../../MCInstrDesc.h"
34
#include "../../MCRegisterInfo.h"
35
#include "../../SStream.h"
36
#include "../../utils.h"
37
#include "PPCLinkage.h"
38
#include "PPCMapping.h"
39
#include "PPCMCTargetDesc.h"
40
#include "PPCPredicates.h"
41
42
#define CONCAT(a, b) CONCAT_(a, b)
43
#define CONCAT_(a, b) a##_##b
44
45
DEFINE_PPC_REGCLASSES
46
47
#define DEBUG_TYPE "ppc-disassembler"
48
49
DecodeStatus getInstruction(csh ud, const uint8_t *Bytes, size_t BytesLen,
50
          MCInst *MI, uint16_t *Size, uint64_t Address,
51
          void *Info);
52
// end anonymous namespace
53
54
static DecodeStatus decodeCondBrTarget(MCInst *Inst, unsigned Imm,
55
               uint64_t Address, const void *Decoder)
56
7.02k
{
57
7.02k
  MCOperand_CreateImm0(Inst, (SignExtend32((Imm), 14)));
58
7.02k
  return MCDisassembler_Success;
59
7.02k
}
60
61
static DecodeStatus decodeDirectBrTarget(MCInst *Inst, unsigned Imm,
62
           uint64_t Address, const void *Decoder)
63
840
{
64
840
  int32_t Offset = SignExtend32((Imm), 24);
65
840
  MCOperand_CreateImm0(Inst, (Offset));
66
840
  return MCDisassembler_Success;
67
840
}
68
69
// FIXME: These can be generated by TableGen from the existing register
70
// encoding values!
71
72
static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
73
          const MCPhysReg *Regs)
74
113k
{
75
113k
  MCOperand_CreateReg0(Inst, (Regs[RegNo]));
76
113k
  return MCDisassembler_Success;
77
113k
}
78
79
static DecodeStatus DecodeCRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
80
              uint64_t Address,
81
              const void *Decoder)
82
2.24k
{
83
2.24k
  return decodeRegisterClass(Inst, RegNo, CRRegs);
84
2.24k
}
85
86
static DecodeStatus DecodeCRBITRCRegisterClass(MCInst *Inst, uint64_t RegNo,
87
                 uint64_t Address,
88
                 const void *Decoder)
89
8.20k
{
90
8.20k
  return decodeRegisterClass(Inst, RegNo, CRBITRegs);
91
8.20k
}
92
93
static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, uint64_t RegNo,
94
              uint64_t Address,
95
              const void *Decoder)
96
3.17k
{
97
3.17k
  return decodeRegisterClass(Inst, RegNo, FRegs);
98
3.17k
}
99
100
static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
101
              uint64_t Address,
102
              const void *Decoder)
103
6.13k
{
104
6.13k
  return decodeRegisterClass(Inst, RegNo, FRegs);
105
6.13k
}
106
107
static DecodeStatus DecodeFpRCRegisterClass(MCInst *Inst, uint64_t RegNo,
108
              uint64_t Address, const void *Decoder)
109
2.20k
{
110
2.20k
  if (RegNo > 30 || (RegNo & 1))
111
66
    return MCDisassembler_Fail;
112
2.13k
  return decodeRegisterClass(Inst, RegNo >> 1, FpRegs);
113
2.20k
}
114
115
static DecodeStatus DecodeVFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
116
              uint64_t Address,
117
              const void *Decoder)
118
387
{
119
387
  return decodeRegisterClass(Inst, RegNo, VFRegs);
120
387
}
121
122
static DecodeStatus DecodeVRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
123
              uint64_t Address,
124
              const void *Decoder)
125
7.09k
{
126
7.09k
  return decodeRegisterClass(Inst, RegNo, VRegs);
127
7.09k
}
128
129
static DecodeStatus DecodeVSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
130
              uint64_t Address,
131
              const void *Decoder)
132
7.16k
{
133
7.16k
  return decodeRegisterClass(Inst, RegNo, VSRegs);
134
7.16k
}
135
136
static DecodeStatus DecodeVSFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
137
               uint64_t Address,
138
               const void *Decoder)
139
3.51k
{
140
3.51k
  return decodeRegisterClass(Inst, RegNo, VSFRegs);
141
3.51k
}
142
143
static DecodeStatus DecodeVSSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
144
               uint64_t Address,
145
               const void *Decoder)
146
2.58k
{
147
2.58k
  return decodeRegisterClass(Inst, RegNo, VSSRegs);
148
2.58k
}
149
150
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo,
151
              uint64_t Address,
152
              const void *Decoder)
153
29.8k
{
154
29.8k
  return decodeRegisterClass(Inst, RegNo, RRegs);
155
29.8k
}
156
157
static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst *Inst, uint64_t RegNo,
158
             uint64_t Address,
159
             const void *Decoder)
160
20.6k
{
161
20.6k
  return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
162
20.6k
}
163
164
static DecodeStatus DecodeG8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
165
              uint64_t Address,
166
              const void *Decoder)
167
10.9k
{
168
10.9k
  return decodeRegisterClass(Inst, RegNo, XRegs);
169
10.9k
}
170
171
static DecodeStatus DecodeG8pRCRegisterClass(MCInst *Inst, uint64_t RegNo,
172
               uint64_t Address,
173
               const void *Decoder)
174
492
{
175
492
  return decodeRegisterClass(Inst, RegNo, XRegs);
176
492
}
177
178
static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst *Inst, uint64_t RegNo,
179
             uint64_t Address,
180
             const void *Decoder)
181
34
{
182
34
  return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
183
34
}
184
185
4.21k
#define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
186
20.1k
#define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
187
188
static DecodeStatus DecodeSPERCRegisterClass(MCInst *Inst, uint64_t RegNo,
189
               uint64_t Address,
190
               const void *Decoder)
191
0
{
192
0
  return decodeRegisterClass(Inst, RegNo, SPERegs);
193
0
}
194
195
static DecodeStatus DecodeACCRCRegisterClass(MCInst *Inst, uint64_t RegNo,
196
               uint64_t Address,
197
               const void *Decoder)
198
0
{
199
0
  return decodeRegisterClass(Inst, RegNo, ACCRegs);
200
0
}
201
202
static DecodeStatus DecodeWACCRCRegisterClass(MCInst *Inst, uint64_t RegNo,
203
                uint64_t Address,
204
                const void *Decoder)
205
359
{
206
359
  return decodeRegisterClass(Inst, RegNo, WACCRegs);
207
359
}
208
209
static DecodeStatus DecodeWACC_HIRCRegisterClass(MCInst *Inst, uint64_t RegNo,
210
             uint64_t Address,
211
             const void *Decoder)
212
40
{
213
40
  return decodeRegisterClass(Inst, RegNo, WACC_HIRegs);
214
40
}
215
216
// TODO: Make this function static when the register class is used by a new
217
//       instruction.
218
DecodeStatus DecodeDMRROWRCRegisterClass(MCInst *Inst, uint64_t RegNo,
219
           uint64_t Address, const void *Decoder)
220
0
{
221
0
  return decodeRegisterClass(Inst, RegNo, DMRROWRegs);
222
0
}
223
224
static DecodeStatus DecodeDMRROWpRCRegisterClass(MCInst *Inst, uint64_t RegNo,
225
             uint64_t Address,
226
             const void *Decoder)
227
45
{
228
45
  return decodeRegisterClass(Inst, RegNo, DMRROWpRegs);
229
45
}
230
231
static DecodeStatus DecodeDMRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
232
               uint64_t Address,
233
               const void *Decoder)
234
129
{
235
129
  return decodeRegisterClass(Inst, RegNo, DMRRegs);
236
129
}
237
238
// TODO: Make this function static when the register class is used by a new
239
//       instruction.
240
DecodeStatus DecodeDMRpRCRegisterClass(MCInst *Inst, uint64_t RegNo,
241
               uint64_t Address, const void *Decoder)
242
0
{
243
0
  return decodeRegisterClass(Inst, RegNo, DMRpRegs);
244
0
}
245
246
static DecodeStatus DecodeVSRpRCRegisterClass(MCInst *Inst, uint64_t RegNo,
247
                uint64_t Address,
248
                const void *Decoder)
249
1.41k
{
250
1.41k
  return decodeRegisterClass(Inst, RegNo, VSRpRegs);
251
1.41k
}
252
253
827
#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
254
967
#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
255
256
static DecodeStatus DecodeQFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
257
              uint64_t Address,
258
              const void *Decoder)
259
6.81k
{
260
6.81k
  return decodeRegisterClass(Inst, RegNo, QFRegs);
261
6.81k
}
262
263
#define DEFINE_decodeUImmOperand(N) \
264
  static DecodeStatus CONCAT(decodeUImmOperand, \
265
           N)(MCInst * Inst, uint64_t Imm, \
266
              int64_t Address, const void *Decoder) \
267
30.3k
  { \
268
30.3k
    if (!isUIntN(N, Imm)) \
269
30.3k
      return MCDisassembler_Fail; \
270
30.3k
    MCOperand_CreateImm0(Inst, (Imm)); \
271
30.3k
    return MCDisassembler_Success; \
272
30.3k
  }
PPCDisassembler.c:decodeUImmOperand_5
Line
Count
Source
267
18.0k
  { \
268
18.0k
    if (!isUIntN(N, Imm)) \
269
18.0k
      return MCDisassembler_Fail; \
270
18.0k
    MCOperand_CreateImm0(Inst, (Imm)); \
271
18.0k
    return MCDisassembler_Success; \
272
18.0k
  }
PPCDisassembler.c:decodeUImmOperand_1
Line
Count
Source
267
2.45k
  { \
268
2.45k
    if (!isUIntN(N, Imm)) \
269
2.45k
      return MCDisassembler_Fail; \
270
2.45k
    MCOperand_CreateImm0(Inst, (Imm)); \
271
2.45k
    return MCDisassembler_Success; \
272
2.45k
  }
PPCDisassembler.c:decodeUImmOperand_4
Line
Count
Source
267
872
  { \
268
872
    if (!isUIntN(N, Imm)) \
269
872
      return MCDisassembler_Fail; \
270
872
    MCOperand_CreateImm0(Inst, (Imm)); \
271
866
    return MCDisassembler_Success; \
272
872
  }
PPCDisassembler.c:decodeUImmOperand_3
Line
Count
Source
267
2.00k
  { \
268
2.00k
    if (!isUIntN(N, Imm)) \
269
2.00k
      return MCDisassembler_Fail; \
270
2.00k
    MCOperand_CreateImm0(Inst, (Imm)); \
271
2.00k
    return MCDisassembler_Success; \
272
2.00k
  }
PPCDisassembler.c:decodeUImmOperand_16
Line
Count
Source
267
2.32k
  { \
268
2.32k
    if (!isUIntN(N, Imm)) \
269
2.32k
      return MCDisassembler_Fail; \
270
2.32k
    MCOperand_CreateImm0(Inst, (Imm)); \
271
2.32k
    return MCDisassembler_Success; \
272
2.32k
  }
PPCDisassembler.c:decodeUImmOperand_6
Line
Count
Source
267
2.52k
  { \
268
2.52k
    if (!isUIntN(N, Imm)) \
269
2.52k
      return MCDisassembler_Fail; \
270
2.52k
    MCOperand_CreateImm0(Inst, (Imm)); \
271
2.52k
    return MCDisassembler_Success; \
272
2.52k
  }
PPCDisassembler.c:decodeUImmOperand_2
Line
Count
Source
267
1.31k
  { \
268
1.31k
    if (!isUIntN(N, Imm)) \
269
1.31k
      return MCDisassembler_Fail; \
270
1.31k
    MCOperand_CreateImm0(Inst, (Imm)); \
271
1.31k
    return MCDisassembler_Success; \
272
1.31k
  }
PPCDisassembler.c:decodeUImmOperand_10
Line
Count
Source
267
26
  { \
268
26
    if (!isUIntN(N, Imm)) \
269
26
      return MCDisassembler_Fail; \
270
26
    MCOperand_CreateImm0(Inst, (Imm)); \
271
26
    return MCDisassembler_Success; \
272
26
  }
PPCDisassembler.c:decodeUImmOperand_8
Line
Count
Source
267
91
  { \
268
91
    if (!isUIntN(N, Imm)) \
269
91
      return MCDisassembler_Fail; \
270
91
    MCOperand_CreateImm0(Inst, (Imm)); \
271
91
    return MCDisassembler_Success; \
272
91
  }
PPCDisassembler.c:decodeUImmOperand_7
Line
Count
Source
267
182
  { \
268
182
    if (!isUIntN(N, Imm)) \
269
182
      return MCDisassembler_Fail; \
270
182
    MCOperand_CreateImm0(Inst, (Imm)); \
271
182
    return MCDisassembler_Success; \
272
182
  }
PPCDisassembler.c:decodeUImmOperand_12
Line
Count
Source
267
472
  { \
268
472
    if (!isUIntN(N, Imm)) \
269
472
      return MCDisassembler_Fail; \
270
472
    MCOperand_CreateImm0(Inst, (Imm)); \
271
472
    return MCDisassembler_Success; \
272
472
  }
273
DEFINE_decodeUImmOperand(1);
274
DEFINE_decodeUImmOperand(2);
275
DEFINE_decodeUImmOperand(3);
276
DEFINE_decodeUImmOperand(4);
277
DEFINE_decodeUImmOperand(5);
278
DEFINE_decodeUImmOperand(6);
279
DEFINE_decodeUImmOperand(7);
280
DEFINE_decodeUImmOperand(8);
281
DEFINE_decodeUImmOperand(10);
282
DEFINE_decodeUImmOperand(12);
283
DEFINE_decodeUImmOperand(16);
284
285
#define DEFINE_decodeSImmOperand(N) \
286
  static DecodeStatus CONCAT(decodeSImmOperand, \
287
           N)(MCInst * Inst, uint64_t Imm, \
288
              int64_t Address, const void *Decoder) \
289
5.86k
  { \
290
5.86k
    if (!isUIntN(N, Imm)) \
291
5.86k
      return MCDisassembler_Fail; \
292
5.86k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
293
5.86k
    return MCDisassembler_Success; \
294
5.86k
  }
PPCDisassembler.c:decodeSImmOperand_16
Line
Count
Source
289
5.18k
  { \
290
5.18k
    if (!isUIntN(N, Imm)) \
291
5.18k
      return MCDisassembler_Fail; \
292
5.18k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
293
5.18k
    return MCDisassembler_Success; \
294
5.18k
  }
PPCDisassembler.c:decodeSImmOperand_5
Line
Count
Source
289
257
  { \
290
257
    if (!isUIntN(N, Imm)) \
291
257
      return MCDisassembler_Fail; \
292
257
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
293
257
    return MCDisassembler_Success; \
294
257
  }
PPCDisassembler.c:decodeSImmOperand_34
Line
Count
Source
289
425
  { \
290
425
    if (!isUIntN(N, Imm)) \
291
425
      return MCDisassembler_Fail; \
292
425
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
293
425
    return MCDisassembler_Success; \
294
425
  }
295
DEFINE_decodeSImmOperand(16);
296
DEFINE_decodeSImmOperand(5);
297
DEFINE_decodeSImmOperand(34);
298
299
static DecodeStatus decodeImmZeroOperand(MCInst *Inst, uint64_t Imm,
300
           int64_t Address, const void *Decoder)
301
109
{
302
109
  if (Imm != 0)
303
7
    return MCDisassembler_Fail;
304
102
  MCOperand_CreateImm0(Inst, (Imm));
305
102
  return MCDisassembler_Success;
306
109
}
307
308
static DecodeStatus decodeVSRpEvenOperands(MCInst *Inst, uint64_t RegNo,
309
             uint64_t Address,
310
             const void *Decoder)
311
0
{
312
0
  if (RegNo & 1)
313
0
    return MCDisassembler_Fail;
314
0
  MCOperand_CreateReg0(Inst, (VSRpRegs[RegNo >> 1]));
315
0
  return MCDisassembler_Success;
316
0
}
317
318
static DecodeStatus decodeDispSPE8Operand(MCInst *Inst, uint64_t Imm,
319
            int64_t Address, const void *Decoder)
320
0
{
321
  // Decode the dispSPE8 field, which has 5-bits, 8-byte aligned.
322
323
0
  uint64_t Disp = Imm & 0x1F;
324
325
0
  MCOperand_CreateImm0(Inst, (Disp << 3));
326
0
  return MCDisassembler_Success;
327
0
}
328
329
static DecodeStatus decodeDispSPE4Operand(MCInst *Inst, uint64_t Imm,
330
            int64_t Address, const void *Decoder)
331
0
{
332
  // Decode the dispSPE8 field, which has 5-bits, 4-byte aligned.
333
334
0
  uint64_t Disp = Imm & 0x1F;
335
336
0
  MCOperand_CreateImm0(Inst, (Disp << 2));
337
0
  return MCDisassembler_Success;
338
0
}
339
340
static DecodeStatus decodeDispSPE2Operand(MCInst *Inst, uint64_t Imm,
341
            int64_t Address, const void *Decoder)
342
0
{
343
  // Decode the dispSPE8 field, which has 5-bits, 2-byte aligned.
344
345
0
  uint64_t Disp = Imm & 0x1F;
346
0
  MCOperand_CreateImm0(Inst, (Disp << 1));
347
0
  return MCDisassembler_Success;
348
0
}
349
350
static DecodeStatus decodeDispRIXOperand(MCInst *Inst, uint64_t Imm,
351
           int64_t Address, const void *Decoder)
352
1.66k
{
353
  // The rix displacement is an immediate shifted by 2
354
1.66k
  MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 2), 16)));
355
1.66k
  return MCDisassembler_Success;
356
1.66k
}
357
358
static DecodeStatus decodeDispRIX16Operand(MCInst *Inst, uint64_t Imm,
359
             int64_t Address, const void *Decoder)
360
691
{
361
  // The rix16 displacement has 12-bits which are shifted by 4.
362
691
  MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 4), 16)));
363
691
  return MCDisassembler_Success;
364
691
}
365
366
static DecodeStatus decodeDispRIHashOperand(MCInst *Inst, uint64_t Imm,
367
              int64_t Address,
368
              const void *Decoder)
369
44
{
370
  // Decode the disp field for a hash store or hash check operation.
371
  // The field is composed of an immediate value that is 6 bits
372
  // and covers the range -8 to -512. The immediate is always negative and 2s
373
  // complement which is why we sign extend a 7 bit value.
374
44
  const int64_t Disp = SignExtend64(((Imm & 0x3F) + 64), 7) * 8;
375
376
44
  MCOperand_CreateImm0(Inst, (Disp));
377
44
  return MCDisassembler_Success;
378
44
}
379
380
static DecodeStatus decodeCRBitMOperand(MCInst *Inst, uint64_t Imm,
381
          int64_t Address, const void *Decoder)
382
166
{
383
  // The cr bit encoding is 0x80 >> cr_reg_num.
384
385
166
  unsigned Zeros = CountTrailingZeros_32(Imm);
386
166
  if (Zeros >= 8)
387
2
    return MCDisassembler_Fail;
388
389
164
  MCOperand_CreateReg0(Inst, (CRRegs[7 - Zeros]));
390
164
  return MCDisassembler_Success;
391
166
}
392
393
#include "PPCGenDisassemblerTables.inc"
394
395
DecodeStatus getInstruction(csh ud, const uint8_t *Bytes, size_t BytesLen,
396
          MCInst *MI, uint16_t *Size, uint64_t Address,
397
          void *Info)
398
54.3k
{
399
  // If this is an 8-byte prefixed instruction, handle it here.
400
  // Note: prefixed instructions aren't technically 8-byte entities - the
401
  // prefix
402
  //       appears in memory at an address 4 bytes prior to that of the base
403
  //       instruction regardless of endianness. So we read the two pieces and
404
  //       rebuild the 8-byte instruction.
405
  // TODO: In this function we call decodeInstruction several times with
406
  //       different decoder tables. It may be possible to only call once by
407
  //       looking at the top 6 bits of the instruction.
408
54.3k
  if (PPC_getFeatureBits(MI->csh->mode, PPC_FeaturePrefixInstrs) &&
409
54.3k
      BytesLen >= 8) {
410
51.4k
    uint32_t Prefix = readBytes32(MI, Bytes);
411
51.4k
    uint32_t BaseInst = readBytes32(MI, Bytes + 4);
412
51.4k
    uint64_t Inst = BaseInst | (uint64_t)Prefix << 32;
413
51.4k
    DecodeStatus result =
414
51.4k
      decodeInstruction_4(DecoderTable64, MI, Inst, Address, NULL);
415
51.4k
    if (result != MCDisassembler_Fail) {
416
548
      *Size = 8;
417
548
      return result;
418
548
    }
419
51.4k
  }
420
421
  // Get the four bytes of the instruction.
422
53.8k
  *Size = 4;
423
53.8k
  if (BytesLen < 4) {
424
831
    *Size = 0;
425
831
    return MCDisassembler_Fail;
426
831
  }
427
428
  // Read the instruction in the proper endianness.
429
52.9k
  uint64_t Inst = readBytes32(MI, Bytes);
430
431
52.9k
  if (PPC_getFeatureBits(MI->csh->mode, PPC_FeatureQPX)) {
432
23.9k
    DecodeStatus result = decodeInstruction_4(DecoderTableQPX32, MI,
433
23.9k
                Inst, Address, NULL);
434
23.9k
    if (result != MCDisassembler_Fail)
435
2.28k
      return result;
436
29.0k
  } else if (PPC_getFeatureBits(MI->csh->mode, PPC_FeatureSPE)) {
437
0
    DecodeStatus result = decodeInstruction_4(DecoderTableSPE32, MI,
438
0
                Inst, Address, NULL);
439
0
    if (result != MCDisassembler_Fail)
440
0
      return result;
441
29.0k
  } else if (PPC_getFeatureBits(MI->csh->mode, PPC_FeaturePS)) {
442
10.1k
    DecodeStatus result = decodeInstruction_4(DecoderTablePS32, MI,
443
10.1k
                Inst, Address, NULL);
444
10.1k
    if (result != MCDisassembler_Fail)
445
908
      return result;
446
10.1k
  }
447
448
49.7k
  return decodeInstruction_4(DecoderTable32, MI, Inst, Address, NULL);
449
52.9k
}
450
451
DecodeStatus PPC_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
452
             size_t BytesLen, MCInst *MI,
453
             uint16_t *Size, uint64_t Address,
454
             void *Info)
455
54.3k
{
456
54.3k
  return getInstruction(handle, Bytes, BytesLen, MI, Size, Address, Info);
457
54.3k
}