Coverage Report

Created: 2025-07-01 07:03

/src/capstonev5/arch/PowerPC/PPCDisassembler.c
Line
Count
Source (jump to first uncovered line)
1
//===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
/* Capstone Disassembly Engine */
11
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
12
13
#ifdef CAPSTONE_HAS_POWERPC
14
15
#include <stdio.h>  // DEBUG
16
#include <stdlib.h>
17
#include <string.h>
18
19
#include "../../cs_priv.h"
20
#include "../../utils.h"
21
22
#include "PPCDisassembler.h"
23
24
#include "../../MCInst.h"
25
#include "../../MCInstrDesc.h"
26
#include "../../MCFixedLenDisassembler.h"
27
#include "../../MCRegisterInfo.h"
28
#include "../../MCDisassembler.h"
29
#include "../../MathExtras.h"
30
31
#define GET_REGINFO_ENUM
32
#include "PPCGenRegisterInfo.inc"
33
34
35
// FIXME: These can be generated by TableGen from the existing register
36
// encoding values!
37
38
static const unsigned CRRegs[] = {
39
  PPC_CR0, PPC_CR1, PPC_CR2, PPC_CR3,
40
  PPC_CR4, PPC_CR5, PPC_CR6, PPC_CR7
41
};
42
43
static const unsigned CRBITRegs[] = {
44
  PPC_CR0LT, PPC_CR0GT, PPC_CR0EQ, PPC_CR0UN,
45
  PPC_CR1LT, PPC_CR1GT, PPC_CR1EQ, PPC_CR1UN,
46
  PPC_CR2LT, PPC_CR2GT, PPC_CR2EQ, PPC_CR2UN,
47
  PPC_CR3LT, PPC_CR3GT, PPC_CR3EQ, PPC_CR3UN,
48
  PPC_CR4LT, PPC_CR4GT, PPC_CR4EQ, PPC_CR4UN,
49
  PPC_CR5LT, PPC_CR5GT, PPC_CR5EQ, PPC_CR5UN,
50
  PPC_CR6LT, PPC_CR6GT, PPC_CR6EQ, PPC_CR6UN,
51
  PPC_CR7LT, PPC_CR7GT, PPC_CR7EQ, PPC_CR7UN
52
};
53
54
static const unsigned FRegs[] = {
55
  PPC_F0, PPC_F1, PPC_F2, PPC_F3,
56
  PPC_F4, PPC_F5, PPC_F6, PPC_F7,
57
  PPC_F8, PPC_F9, PPC_F10, PPC_F11,
58
  PPC_F12, PPC_F13, PPC_F14, PPC_F15,
59
  PPC_F16, PPC_F17, PPC_F18, PPC_F19,
60
  PPC_F20, PPC_F21, PPC_F22, PPC_F23,
61
  PPC_F24, PPC_F25, PPC_F26, PPC_F27,
62
  PPC_F28, PPC_F29, PPC_F30, PPC_F31
63
};
64
65
static const unsigned VFRegs[] = {
66
  PPC_VF0, PPC_VF1, PPC_VF2, PPC_VF3,
67
  PPC_VF4, PPC_VF5, PPC_VF6, PPC_VF7,
68
  PPC_VF8, PPC_VF9, PPC_VF10, PPC_VF11,
69
  PPC_VF12, PPC_VF13, PPC_VF14, PPC_VF15,
70
  PPC_VF16, PPC_VF17, PPC_VF18, PPC_VF19,
71
  PPC_VF20, PPC_VF21, PPC_VF22, PPC_VF23,
72
  PPC_VF24, PPC_VF25, PPC_VF26, PPC_VF27,
73
  PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
74
};
75
76
static const unsigned VRegs[] = {
77
  PPC_V0, PPC_V1, PPC_V2, PPC_V3,
78
  PPC_V4, PPC_V5, PPC_V6, PPC_V7,
79
  PPC_V8, PPC_V9, PPC_V10, PPC_V11,
80
  PPC_V12, PPC_V13, PPC_V14, PPC_V15,
81
  PPC_V16, PPC_V17, PPC_V18, PPC_V19,
82
  PPC_V20, PPC_V21, PPC_V22, PPC_V23,
83
  PPC_V24, PPC_V25, PPC_V26, PPC_V27,
84
  PPC_V28, PPC_V29, PPC_V30, PPC_V31
85
};
86
87
static const unsigned VSRegs[] = {
88
  PPC_VSL0, PPC_VSL1, PPC_VSL2, PPC_VSL3,
89
  PPC_VSL4, PPC_VSL5, PPC_VSL6, PPC_VSL7,
90
  PPC_VSL8, PPC_VSL9, PPC_VSL10, PPC_VSL11,
91
  PPC_VSL12, PPC_VSL13, PPC_VSL14, PPC_VSL15,
92
  PPC_VSL16, PPC_VSL17, PPC_VSL18, PPC_VSL19,
93
  PPC_VSL20, PPC_VSL21, PPC_VSL22, PPC_VSL23,
94
  PPC_VSL24, PPC_VSL25, PPC_VSL26, PPC_VSL27,
95
  PPC_VSL28, PPC_VSL29, PPC_VSL30, PPC_VSL31,
96
97
  PPC_V0, PPC_V1, PPC_V2, PPC_V3,
98
  PPC_V4, PPC_V5, PPC_V6, PPC_V7,
99
  PPC_V8, PPC_V9, PPC_V10, PPC_V11,
100
  PPC_V12, PPC_V13, PPC_V14, PPC_V15,
101
  PPC_V16, PPC_V17, PPC_V18, PPC_V19,
102
  PPC_V20, PPC_V21, PPC_V22, PPC_V23,
103
  PPC_V24, PPC_V25, PPC_V26, PPC_V27,
104
  PPC_V28, PPC_V29, PPC_V30, PPC_V31
105
};
106
107
static const unsigned VSFRegs[] = {
108
  PPC_F0, PPC_F1, PPC_F2, PPC_F3,
109
  PPC_F4, PPC_F5, PPC_F6, PPC_F7,
110
  PPC_F8, PPC_F9, PPC_F10, PPC_F11,
111
  PPC_F12, PPC_F13, PPC_F14, PPC_F15,
112
  PPC_F16, PPC_F17, PPC_F18, PPC_F19,
113
  PPC_F20, PPC_F21, PPC_F22, PPC_F23,
114
  PPC_F24, PPC_F25, PPC_F26, PPC_F27,
115
  PPC_F28, PPC_F29, PPC_F30, PPC_F31,
116
117
  PPC_VF0, PPC_VF1, PPC_VF2, PPC_VF3,
118
  PPC_VF4, PPC_VF5, PPC_VF6, PPC_VF7,
119
  PPC_VF8, PPC_VF9, PPC_VF10, PPC_VF11,
120
  PPC_VF12, PPC_VF13, PPC_VF14, PPC_VF15,
121
  PPC_VF16, PPC_VF17, PPC_VF18, PPC_VF19,
122
  PPC_VF20, PPC_VF21, PPC_VF22, PPC_VF23,
123
  PPC_VF24, PPC_VF25, PPC_VF26, PPC_VF27,
124
  PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
125
};
126
127
static const unsigned VSSRegs[] = {
128
  PPC_F0, PPC_F1, PPC_F2, PPC_F3,
129
  PPC_F4, PPC_F5, PPC_F6, PPC_F7,
130
  PPC_F8, PPC_F9, PPC_F10, PPC_F11,
131
  PPC_F12, PPC_F13, PPC_F14, PPC_F15,
132
  PPC_F16, PPC_F17, PPC_F18, PPC_F19,
133
  PPC_F20, PPC_F21, PPC_F22, PPC_F23,
134
  PPC_F24, PPC_F25, PPC_F26, PPC_F27,
135
  PPC_F28, PPC_F29, PPC_F30, PPC_F31,
136
137
  PPC_VF0, PPC_VF1, PPC_VF2, PPC_VF3,
138
  PPC_VF4, PPC_VF5, PPC_VF6, PPC_VF7,
139
  PPC_VF8, PPC_VF9, PPC_VF10, PPC_VF11,
140
  PPC_VF12, PPC_VF13, PPC_VF14, PPC_VF15,
141
  PPC_VF16, PPC_VF17, PPC_VF18, PPC_VF19,
142
  PPC_VF20, PPC_VF21, PPC_VF22, PPC_VF23,
143
  PPC_VF24, PPC_VF25, PPC_VF26, PPC_VF27,
144
  PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
145
};
146
147
static const unsigned GPRegs[] = {
148
  PPC_R0, PPC_R1, PPC_R2, PPC_R3,
149
  PPC_R4, PPC_R5, PPC_R6, PPC_R7,
150
  PPC_R8, PPC_R9, PPC_R10, PPC_R11,
151
  PPC_R12, PPC_R13, PPC_R14, PPC_R15,
152
  PPC_R16, PPC_R17, PPC_R18, PPC_R19,
153
  PPC_R20, PPC_R21, PPC_R22, PPC_R23,
154
  PPC_R24, PPC_R25, PPC_R26, PPC_R27,
155
  PPC_R28, PPC_R29, PPC_R30, PPC_R31
156
};
157
158
static const unsigned GP0Regs[] = {
159
  PPC_ZERO, PPC_R1, PPC_R2, PPC_R3,
160
  PPC_R4, PPC_R5, PPC_R6, PPC_R7,
161
  PPC_R8, PPC_R9, PPC_R10, PPC_R11,
162
  PPC_R12, PPC_R13, PPC_R14, PPC_R15,
163
  PPC_R16, PPC_R17, PPC_R18, PPC_R19,
164
  PPC_R20, PPC_R21, PPC_R22, PPC_R23,
165
  PPC_R24, PPC_R25, PPC_R26, PPC_R27,
166
  PPC_R28, PPC_R29, PPC_R30, PPC_R31
167
};
168
169
static const unsigned G8Regs[] = {
170
  PPC_X0, PPC_X1, PPC_X2, PPC_X3,
171
  PPC_X4, PPC_X5, PPC_X6, PPC_X7,
172
  PPC_X8, PPC_X9, PPC_X10, PPC_X11,
173
  PPC_X12, PPC_X13, PPC_X14, PPC_X15,
174
  PPC_X16, PPC_X17, PPC_X18, PPC_X19,
175
  PPC_X20, PPC_X21, PPC_X22, PPC_X23,
176
  PPC_X24, PPC_X25, PPC_X26, PPC_X27,
177
  PPC_X28, PPC_X29, PPC_X30, PPC_X31
178
};
179
180
static const unsigned G80Regs[] = {
181
  PPC_ZERO8, PPC_X1, PPC_X2, PPC_X3,
182
  PPC_X4, PPC_X5, PPC_X6, PPC_X7,
183
  PPC_X8, PPC_X9, PPC_X10, PPC_X11,
184
  PPC_X12, PPC_X13, PPC_X14, PPC_X15,
185
  PPC_X16, PPC_X17, PPC_X18, PPC_X19,
186
  PPC_X20, PPC_X21, PPC_X22, PPC_X23,
187
  PPC_X24, PPC_X25, PPC_X26, PPC_X27,
188
  PPC_X28, PPC_X29, PPC_X30, PPC_X31
189
};
190
191
static const unsigned QFRegs[] = {
192
  PPC_QF0, PPC_QF1, PPC_QF2, PPC_QF3,
193
  PPC_QF4, PPC_QF5, PPC_QF6, PPC_QF7,
194
  PPC_QF8, PPC_QF9, PPC_QF10, PPC_QF11,
195
  PPC_QF12, PPC_QF13, PPC_QF14, PPC_QF15,
196
  PPC_QF16, PPC_QF17, PPC_QF18, PPC_QF19,
197
  PPC_QF20, PPC_QF21, PPC_QF22, PPC_QF23,
198
  PPC_QF24, PPC_QF25, PPC_QF26, PPC_QF27,
199
  PPC_QF28, PPC_QF29, PPC_QF30, PPC_QF31
200
};
201
202
static const unsigned SPERegs[] = {
203
  PPC_S0, PPC_S1, PPC_S2, PPC_S3,
204
  PPC_S4, PPC_S5, PPC_S6, PPC_S7,
205
  PPC_S8, PPC_S9, PPC_S10, PPC_S11,
206
  PPC_S12, PPC_S13, PPC_S14, PPC_S15,
207
  PPC_S16, PPC_S17, PPC_S18, PPC_S19,
208
  PPC_S20, PPC_S21, PPC_S22, PPC_S23,
209
  PPC_S24, PPC_S25, PPC_S26, PPC_S27,
210
  PPC_S28, PPC_S29, PPC_S30, PPC_S31
211
};
212
213
#if 0
214
static uint64_t getFeatureBits(int feature)
215
{
216
  // enable all features
217
  return (uint64_t)-1;
218
}
219
#endif
220
221
static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
222
    const unsigned *Regs, size_t RegsLen)
223
136k
{
224
136k
  if (RegNo >= RegsLen / sizeof(unsigned)) {
225
0
    return MCDisassembler_Fail;
226
0
  }
227
136k
  MCOperand_CreateReg0(Inst, Regs[RegNo]);
228
136k
  return MCDisassembler_Success;
229
136k
}
230
231
static DecodeStatus DecodeCRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
232
    uint64_t Address, const void *Decoder)
233
6.20k
{
234
6.20k
  return decodeRegisterClass(Inst, RegNo, CRRegs, sizeof(CRRegs));
235
6.20k
}
236
237
#if 0
238
static DecodeStatus DecodeCRRC0RegisterClass(MCInst *Inst, uint64_t RegNo,
239
    uint64_t Address, const void *Decoder)
240
{
241
  return decodeRegisterClass(Inst, RegNo, CRRegs, sizeof(CRRegs));
242
}
243
#endif
244
245
static DecodeStatus DecodeCRBITRCRegisterClass(MCInst *Inst, uint64_t RegNo,
246
    uint64_t Address, const void *Decoder)
247
16.4k
{
248
16.4k
  return decodeRegisterClass(Inst, RegNo, CRBITRegs, sizeof(CRBITRegs));
249
16.4k
}
250
251
static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, uint64_t RegNo,
252
    uint64_t Address, const void *Decoder)
253
5.24k
{
254
5.24k
  return decodeRegisterClass(Inst, RegNo, FRegs, sizeof(FRegs));
255
5.24k
}
256
257
static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
258
    uint64_t Address, const void *Decoder)
259
11.4k
{
260
11.4k
  return decodeRegisterClass(Inst, RegNo, FRegs, sizeof(FRegs));
261
11.4k
}
262
263
static DecodeStatus DecodeVFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
264
    uint64_t Address, const void *Decoder)
265
378
{
266
378
  return decodeRegisterClass(Inst, RegNo, VFRegs, sizeof(VFRegs));
267
378
}
268
269
static DecodeStatus DecodeVRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
270
    uint64_t Address, const void *Decoder)
271
10.3k
{
272
10.3k
  return decodeRegisterClass(Inst, RegNo, VRegs, sizeof(VRegs));
273
10.3k
}
274
275
static DecodeStatus DecodeVSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
276
    uint64_t Address, const void *Decoder)
277
16.3k
{
278
16.3k
  return decodeRegisterClass(Inst, RegNo, VSRegs, sizeof(VSRegs));
279
16.3k
}
280
281
static DecodeStatus DecodeVSFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
282
    uint64_t Address, const void *Decoder)
283
3.59k
{
284
3.59k
  return decodeRegisterClass(Inst, RegNo, VSFRegs, sizeof(VSFRegs));
285
3.59k
}
286
287
static DecodeStatus DecodeVSSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
288
    uint64_t Address, const void *Decoder)
289
2.02k
{
290
2.02k
  return decodeRegisterClass(Inst, RegNo, VSSRegs, sizeof(VSSRegs));
291
2.02k
}
292
293
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo,
294
    uint64_t Address, const void *Decoder)
295
82.8k
{
296
82.8k
  return decodeRegisterClass(Inst, RegNo, GPRegs, sizeof(GPRegs));
297
82.8k
}
298
299
static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst *Inst, uint64_t RegNo,
300
    uint64_t Address, const void *Decoder)
301
19.9k
{
302
19.9k
  return decodeRegisterClass(Inst, RegNo, GP0Regs, sizeof(GP0Regs));
303
19.9k
}
304
305
static DecodeStatus DecodeG8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
306
    uint64_t Address, const void *Decoder)
307
19.7k
{
308
19.7k
  return decodeRegisterClass(Inst, RegNo, G8Regs, sizeof(G8Regs));
309
19.7k
}
310
311
static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst *Inst, uint64_t RegNo,
312
    uint64_t Address, const void *Decoder)
313
76
{
314
76
  return decodeRegisterClass(Inst, RegNo, G80Regs, sizeof(G80Regs));
315
76
}
316
317
2.70k
#define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
318
3.10k
#define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
319
320
static DecodeStatus DecodeQFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
321
    uint64_t Address, const void *Decoder)
322
19.6k
{
323
19.6k
  return decodeRegisterClass(Inst, RegNo, QFRegs, sizeof(QFRegs));
324
19.6k
}
325
326
static DecodeStatus DecodeSPE4RCRegisterClass(MCInst *Inst, uint64_t RegNo,
327
        uint64_t Address, const void *Decoder)
328
0
{
329
0
    return decodeRegisterClass(Inst, RegNo, GPRegs, sizeof(GPRegs));
330
0
}
331
332
static DecodeStatus DecodeSPERCRegisterClass(MCInst *Inst, uint64_t RegNo,
333
        uint64_t Address, const void *Decoder)
334
0
{
335
0
    return decodeRegisterClass(Inst, RegNo, SPERegs, sizeof(SPERegs));
336
0
}
337
338
1.16k
#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
339
7.98k
#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
340
341
static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm,
342
    int64_t Address, const void *Decoder, unsigned N)
343
37.5k
{
344
  //assert(isUInt<N>(Imm) && "Invalid immediate");
345
37.5k
  MCOperand_CreateImm0(Inst, Imm);
346
347
37.5k
  return MCDisassembler_Success;
348
37.5k
}
349
350
static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm,
351
    int64_t Address, const void *Decoder, unsigned N)
352
10.5k
{
353
  // assert(isUInt<N>(Imm) && "Invalid immediate");
354
10.5k
  MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
355
356
10.5k
  return MCDisassembler_Success;
357
10.5k
}
358
359
360
#define GET_INSTRINFO_ENUM
361
#include "PPCGenInstrInfo.inc"
362
363
static DecodeStatus decodeMemRIOperands(MCInst *Inst, uint64_t Imm,
364
    int64_t Address, const void *Decoder)
365
8.84k
{
366
  // Decode the memri field (imm, reg), which has the low 16-bits as the
367
  // displacement and the next 5 bits as the register #.
368
369
8.84k
  uint64_t Base = Imm >> 16;
370
8.84k
  uint64_t Disp = Imm & 0xFFFF;
371
372
  // assert(Base < 32 && "Invalid base register");
373
8.84k
  if (Base >= 32)
374
0
    return MCDisassembler_Fail;
375
376
8.84k
  switch (MCInst_getOpcode(Inst)) {
377
3.90k
    default: break;
378
3.90k
    case PPC_LBZU:
379
746
    case PPC_LHAU:
380
1.49k
    case PPC_LHZU:
381
2.54k
    case PPC_LWZU:
382
2.73k
    case PPC_LFSU:
383
3.03k
    case PPC_LFDU:
384
         // Add the tied output operand.
385
3.03k
         MCOperand_CreateReg0(Inst, GP0Regs[Base]);
386
3.03k
         break;
387
251
    case PPC_STBU:
388
747
    case PPC_STHU:
389
1.01k
    case PPC_STWU:
390
1.27k
    case PPC_STFSU:
391
1.90k
    case PPC_STFDU:
392
1.90k
         MCInst_insert0(Inst, 0, MCOperand_CreateReg1(Inst, GP0Regs[Base]));
393
1.90k
         break;
394
8.84k
  }
395
396
8.84k
  MCOperand_CreateImm0(Inst, SignExtend64(Disp, 16));
397
8.84k
  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
398
399
8.84k
  return MCDisassembler_Success;
400
8.84k
}
401
402
static DecodeStatus decodeMemRIXOperands(MCInst *Inst, uint64_t Imm,
403
    int64_t Address, const void *Decoder)
404
876
{
405
  // Decode the memrix field (imm, reg), which has the low 14-bits as the
406
  // displacement and the next 5 bits as the register #.
407
408
876
  uint64_t Base = Imm >> 14;
409
876
  uint64_t Disp = Imm & 0x3FFF;
410
411
  // assert(Base < 32 && "Invalid base register");
412
876
  if (Base >= 32)
413
0
    return MCDisassembler_Fail;
414
415
876
  if (MCInst_getOpcode(Inst) == PPC_LDU)
416
    // Add the tied output operand.
417
257
    MCOperand_CreateReg0(Inst, GP0Regs[Base]);
418
619
  else if (MCInst_getOpcode(Inst) == PPC_STDU)
419
89
    MCInst_insert0(Inst, 0, MCOperand_CreateReg1(Inst, GP0Regs[Base]));
420
421
876
  MCOperand_CreateImm0(Inst, SignExtend64(Disp << 2, 16));
422
876
  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
423
424
876
  return MCDisassembler_Success;
425
876
}
426
427
static DecodeStatus decodeMemRIX16Operands(MCInst *Inst, uint64_t Imm,
428
    int64_t Address, const void *Decoder)
429
101
{
430
  // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
431
  // displacement with 16-byte aligned, and the next 5 bits as the register #.
432
433
101
  uint64_t Base = Imm >> 12;
434
101
  uint64_t Disp = Imm & 0xFFF;
435
436
  // assert(Base < 32 && "Invalid base register");
437
101
  if (Base >= 32)
438
0
    return MCDisassembler_Fail;
439
440
101
  MCOperand_CreateImm0(Inst, SignExtend64(Disp << 4, 16));
441
101
  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
442
443
101
  return MCDisassembler_Success;
444
101
}
445
446
static DecodeStatus decodeSPE8Operands(MCInst *Inst, uint64_t Imm,
447
    int64_t Address, const void *Decoder)
448
0
{
449
  // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
450
  // displacement with 8-byte aligned, and the next 5 bits as the register #.
451
452
0
  uint64_t Base = Imm >> 5;
453
0
  uint64_t Disp = Imm & 0x1F;
454
455
  // assert(Base < 32 && "Invalid base register");
456
0
  if (Base >= 32)
457
0
    return MCDisassembler_Fail;
458
459
0
  MCOperand_CreateImm0(Inst, Disp << 3);
460
0
  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
461
462
0
  return MCDisassembler_Success;
463
0
}
464
465
static DecodeStatus decodeSPE4Operands(MCInst *Inst, uint64_t Imm,
466
    int64_t Address, const void *Decoder)
467
0
{
468
  // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
469
  // displacement with 4-byte aligned, and the next 5 bits as the register #.
470
471
0
  uint64_t Base = Imm >> 5;
472
0
  uint64_t Disp = Imm & 0x1F;
473
474
  // assert(Base < 32 && "Invalid base register");
475
0
  if (Base >= 32)
476
0
    return MCDisassembler_Fail;
477
478
0
  MCOperand_CreateImm0(Inst, Disp << 2);
479
0
  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
480
481
0
  return MCDisassembler_Success;
482
0
}
483
484
static DecodeStatus decodeSPE2Operands(MCInst *Inst, uint64_t Imm,
485
    int64_t Address, const void *Decoder)
486
0
{
487
  // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
488
  // displacement with 2-byte aligned, and the next 5 bits as the register #.
489
490
0
  uint64_t Base = Imm >> 5;
491
0
  uint64_t Disp = Imm & 0x1F;
492
493
  // assert(Base < 32 && "Invalid base register");
494
0
  if (Base >= 32)
495
0
    return MCDisassembler_Fail;
496
497
0
  MCOperand_CreateImm0(Inst, Disp << 1);
498
0
  MCOperand_CreateReg0(Inst, GP0Regs[Base]);
499
500
0
  return MCDisassembler_Success;
501
0
}
502
503
static DecodeStatus decodeCRBitMOperand(MCInst *Inst, uint64_t Imm,
504
    int64_t Address, const void *Decoder)
505
622
{
506
  // The cr bit encoding is 0x80 >> cr_reg_num.
507
508
622
  unsigned Zeros = CountTrailingZeros_64(Imm);
509
  // assert(Zeros < 8 && "Invalid CR bit value");
510
622
  if (Zeros >= 8)
511
4
    return MCDisassembler_Fail;
512
513
618
  MCOperand_CreateReg0(Inst, CRRegs[7 - Zeros]);
514
515
618
  return MCDisassembler_Success;
516
622
}
517
518
#include "PPCGenDisassemblerTables.inc"
519
520
static DecodeStatus getInstruction(MCInst *MI,
521
    const uint8_t *code, size_t code_len,
522
    uint16_t *Size,
523
    uint64_t Address, MCRegisterInfo *MRI)
524
80.8k
{
525
80.8k
  uint32_t insn;
526
80.8k
  DecodeStatus result;
527
528
  // Get the four bytes of the instruction.
529
80.8k
  if (code_len < 4) {
530
    // not enough data
531
804
    *Size = 0;
532
804
    return MCDisassembler_Fail;
533
804
  }
534
535
  // The instruction is big-endian encoded.
536
80.0k
  if (MODE_IS_BIG_ENDIAN(MI->csh->mode))
537
80.0k
    insn = ((uint32_t) code[0] << 24) | (code[1] << 16) |
538
80.0k
      (code[2] <<  8) | (code[3] <<  0);
539
0
  else  // little endian
540
0
    insn = ((uint32_t) code[3] << 24) | (code[2] << 16) |
541
0
      (code[1] <<  8) | (code[0] <<  0);
542
543
80.0k
  if (MI->flat_insn->detail) {
544
80.0k
    memset(MI->flat_insn->detail, 0, offsetof(cs_detail, ppc) + sizeof(cs_ppc));
545
80.0k
  }
546
547
80.0k
  if (MI->csh->mode & CS_MODE_QPX) {
548
41.5k
    result = decodeInstruction_4(DecoderTableQPX32, MI, insn, Address);
549
41.5k
    if (result != MCDisassembler_Fail) {
550
4.71k
      *Size = 4;
551
552
4.71k
      return result;
553
4.71k
    }
554
555
    // failed to decode
556
36.8k
    MCInst_clear(MI);
557
38.4k
  } else if (MI->csh->mode & CS_MODE_SPE) {
558
0
    result = decodeInstruction_4(DecoderTableSPE32, MI, insn, Address);
559
0
    if (result != MCDisassembler_Fail) {
560
0
      *Size = 4;
561
562
0
      return result;
563
0
    }
564
565
    // failed to decode
566
0
    MCInst_clear(MI);
567
38.4k
  } else if (MI->csh->mode & CS_MODE_PS) {
568
0
    result = decodeInstruction_4(DecoderTablePS32, MI, insn, Address);
569
0
    if (result != MCDisassembler_Fail) {
570
0
      *Size = 4;
571
572
0
      return result;
573
0
    }
574
575
    // failed to decode
576
0
    MCInst_clear(MI);
577
0
  }
578
579
75.3k
  result = decodeInstruction_4(DecoderTable32, MI, insn, Address);
580
75.3k
  if (result != MCDisassembler_Fail) {
581
74.9k
    *Size = 4;
582
583
74.9k
    return result;
584
74.9k
  }
585
586
  // cannot decode, report error
587
351
  MCInst_clear(MI);
588
351
  *Size = 0;
589
590
351
  return MCDisassembler_Fail;
591
75.3k
}
592
593
bool PPC_getInstruction(csh ud, const uint8_t *code, size_t code_len,
594
    MCInst *instr, uint16_t *size, uint64_t address, void *info)
595
80.8k
{
596
80.8k
  DecodeStatus status = getInstruction(instr,
597
80.8k
      code, code_len,
598
80.8k
      size,
599
80.8k
      address, (MCRegisterInfo *)info);
600
601
80.8k
  return status == MCDisassembler_Success;
602
80.8k
}
603
604
#define GET_REGINFO_MC_DESC
605
#include "PPCGenRegisterInfo.inc"
606
void PPC_init(MCRegisterInfo *MRI)
607
2.59k
{
608
  /*
609
     InitMCRegisterInfo(PPCRegDesc, 344,
610
     RA, PC,
611
     PPCMCRegisterClasses, 36,
612
     PPCRegUnitRoots, 171, PPCRegDiffLists, PPCLaneMaskLists, PPCRegStrings, PPCRegClassStrings,
613
     PPCSubRegIdxLists, 7,
614
     PPCSubRegIdxRanges, PPCRegEncodingTable);
615
   */
616
617
2.59k
  MCRegisterInfo_InitMCRegisterInfo(MRI, PPCRegDesc, 344,
618
2.59k
      0, 0,
619
2.59k
      PPCMCRegisterClasses, 36,
620
2.59k
      0, 0,
621
2.59k
      PPCRegDiffLists,
622
2.59k
      0,
623
2.59k
      PPCSubRegIdxLists, 7,
624
2.59k
      0);
625
2.59k
}
626
627
#endif