/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 | 9.32k | { |
57 | 9.32k | MCOperand_CreateImm0(Inst, (SignExtend32((Imm), 14))); |
58 | 9.32k | return MCDisassembler_Success; |
59 | 9.32k | } |
60 | | |
61 | | static DecodeStatus decodeDirectBrTarget(MCInst *Inst, unsigned Imm, |
62 | | uint64_t Address, const void *Decoder) |
63 | 684 | { |
64 | 684 | int32_t Offset = SignExtend32((Imm), 24); |
65 | 684 | MCOperand_CreateImm0(Inst, (Offset)); |
66 | 684 | return MCDisassembler_Success; |
67 | 684 | } |
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 | 131k | { |
75 | 131k | MCOperand_CreateReg0(Inst, (Regs[RegNo])); |
76 | 131k | return MCDisassembler_Success; |
77 | 131k | } |
78 | | |
79 | | static DecodeStatus DecodeCRRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
80 | | uint64_t Address, |
81 | | const void *Decoder) |
82 | 8.93k | { |
83 | 8.93k | return decodeRegisterClass(Inst, RegNo, CRRegs); |
84 | 8.93k | } |
85 | | |
86 | | static DecodeStatus DecodeCRBITRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
87 | | uint64_t Address, |
88 | | const void *Decoder) |
89 | 21.3k | { |
90 | 21.3k | return decodeRegisterClass(Inst, RegNo, CRBITRegs); |
91 | 21.3k | } |
92 | | |
93 | | static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, uint64_t RegNo, |
94 | | uint64_t Address, |
95 | | const void *Decoder) |
96 | 8.55k | { |
97 | 8.55k | return decodeRegisterClass(Inst, RegNo, FRegs); |
98 | 8.55k | } |
99 | | |
100 | | static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, uint64_t RegNo, |
101 | | uint64_t Address, |
102 | | const void *Decoder) |
103 | 16.3k | { |
104 | 16.3k | return decodeRegisterClass(Inst, RegNo, FRegs); |
105 | 16.3k | } |
106 | | |
107 | | static DecodeStatus DecodeFpRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
108 | | uint64_t Address, |
109 | | const void *Decoder) |
110 | 1.68k | { |
111 | 1.68k | if (RegNo > 30 || (RegNo & 1)) |
112 | 67 | return MCDisassembler_Fail; |
113 | 1.62k | return decodeRegisterClass(Inst, RegNo >> 1, FpRegs); |
114 | 1.68k | } |
115 | | |
116 | | static DecodeStatus DecodeVFRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
117 | | uint64_t Address, |
118 | | const void *Decoder) |
119 | 937 | { |
120 | 937 | return decodeRegisterClass(Inst, RegNo, VFRegs); |
121 | 937 | } |
122 | | |
123 | | static DecodeStatus DecodeVRRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
124 | | uint64_t Address, |
125 | | const void *Decoder) |
126 | 19.9k | { |
127 | 19.9k | return decodeRegisterClass(Inst, RegNo, VRegs); |
128 | 19.9k | } |
129 | | |
130 | | static DecodeStatus DecodeVSRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
131 | | uint64_t Address, |
132 | | const void *Decoder) |
133 | 32.0k | { |
134 | 32.0k | return decodeRegisterClass(Inst, RegNo, VSRegs); |
135 | 32.0k | } |
136 | | |
137 | | static DecodeStatus DecodeVSFRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
138 | | uint64_t Address, |
139 | | const void *Decoder) |
140 | 8.25k | { |
141 | 8.25k | return decodeRegisterClass(Inst, RegNo, VSFRegs); |
142 | 8.25k | } |
143 | | |
144 | | static DecodeStatus DecodeVSSRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
145 | | uint64_t Address, |
146 | | const void *Decoder) |
147 | 8.17k | { |
148 | 8.17k | return decodeRegisterClass(Inst, RegNo, VSSRegs); |
149 | 8.17k | } |
150 | | |
151 | | static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
152 | | uint64_t Address, |
153 | | const void *Decoder) |
154 | 122k | { |
155 | 122k | return decodeRegisterClass(Inst, RegNo, RRegs); |
156 | 122k | } |
157 | | |
158 | | static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst *Inst, uint64_t RegNo, |
159 | | uint64_t Address, |
160 | | const void *Decoder) |
161 | 30.6k | { |
162 | 30.6k | return decodeRegisterClass(Inst, RegNo, RRegsNoR0); |
163 | 30.6k | } |
164 | | |
165 | | static DecodeStatus DecodeG8RCRegisterClass(MCInst *Inst, uint64_t RegNo, |
166 | | uint64_t Address, |
167 | | const void *Decoder) |
168 | 30.2k | { |
169 | 30.2k | return decodeRegisterClass(Inst, RegNo, XRegs); |
170 | 30.2k | } |
171 | | |
172 | | static DecodeStatus DecodeG8pRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
173 | | uint64_t Address, |
174 | | const void *Decoder) |
175 | 539 | { |
176 | 539 | return decodeRegisterClass(Inst, RegNo, XRegs); |
177 | 539 | } |
178 | | |
179 | | static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst *Inst, uint64_t RegNo, |
180 | | uint64_t Address, |
181 | | const void *Decoder) |
182 | 199 | { |
183 | 199 | return decodeRegisterClass(Inst, RegNo, XRegsNoX0); |
184 | 199 | } |
185 | | |
186 | 6.20k | #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass |
187 | 21.4k | #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass |
188 | | |
189 | | static DecodeStatus DecodeSPERCRegisterClass(MCInst *Inst, uint64_t RegNo, |
190 | | uint64_t Address, |
191 | | const void *Decoder) |
192 | 0 | { |
193 | 0 | return decodeRegisterClass(Inst, RegNo, SPERegs); |
194 | 0 | } |
195 | | |
196 | | static DecodeStatus DecodeACCRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
197 | | uint64_t Address, |
198 | | const void *Decoder) |
199 | 0 | { |
200 | 0 | return decodeRegisterClass(Inst, RegNo, ACCRegs); |
201 | 0 | } |
202 | | |
203 | | static DecodeStatus DecodeWACCRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
204 | | uint64_t Address, |
205 | | const void *Decoder) |
206 | 398 | { |
207 | 398 | return decodeRegisterClass(Inst, RegNo, WACCRegs); |
208 | 398 | } |
209 | | |
210 | | static DecodeStatus DecodeWACC_HIRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
211 | | uint64_t Address, |
212 | | const void *Decoder) |
213 | 114 | { |
214 | 114 | return decodeRegisterClass(Inst, RegNo, WACC_HIRegs); |
215 | 114 | } |
216 | | |
217 | | // TODO: Make this function static when the register class is used by a new |
218 | | // instruction. |
219 | | DecodeStatus DecodeDMRROWRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
220 | | uint64_t Address, const void *Decoder) |
221 | 0 | { |
222 | 0 | return decodeRegisterClass(Inst, RegNo, DMRROWRegs); |
223 | 0 | } |
224 | | |
225 | | static DecodeStatus DecodeDMRROWpRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
226 | | uint64_t Address, |
227 | | const void *Decoder) |
228 | 102 | { |
229 | 102 | return decodeRegisterClass(Inst, RegNo, DMRROWpRegs); |
230 | 102 | } |
231 | | |
232 | | static DecodeStatus DecodeDMRRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
233 | | uint64_t Address, |
234 | | const void *Decoder) |
235 | 135 | { |
236 | 135 | return decodeRegisterClass(Inst, RegNo, DMRRegs); |
237 | 135 | } |
238 | | |
239 | | // TODO: Make this function static when the register class is used by a new |
240 | | // instruction. |
241 | | DecodeStatus DecodeDMRpRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
242 | | uint64_t Address, const void *Decoder) |
243 | 0 | { |
244 | 0 | return decodeRegisterClass(Inst, RegNo, DMRpRegs); |
245 | 0 | } |
246 | | |
247 | | static DecodeStatus DecodeVSRpRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
248 | | uint64_t Address, |
249 | | const void *Decoder) |
250 | 1.93k | { |
251 | 1.93k | return decodeRegisterClass(Inst, RegNo, VSRpRegs); |
252 | 1.93k | } |
253 | | |
254 | 1.59k | #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass |
255 | 949 | #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass |
256 | | |
257 | | static DecodeStatus DecodeQFRCRegisterClass(MCInst *Inst, uint64_t RegNo, |
258 | | uint64_t Address, |
259 | | const void *Decoder) |
260 | 28.0k | { |
261 | 28.0k | return decodeRegisterClass(Inst, RegNo, QFRegs); |
262 | 28.0k | } |
263 | | |
264 | | #define DEFINE_decodeUImmOperand(N) \ |
265 | | static DecodeStatus CONCAT(decodeUImmOperand, \ |
266 | | N)(MCInst * Inst, uint64_t Imm, \ |
267 | | int64_t Address, const void *Decoder) \ |
268 | 35.7k | { \ |
269 | 35.7k | if (!isUIntN(N, Imm)) \ |
270 | 35.7k | return MCDisassembler_Fail; \ |
271 | 35.7k | MCOperand_CreateImm0(Inst, (Imm)); \ |
272 | 35.7k | return MCDisassembler_Success; \ |
273 | 35.7k | } PPCDisassembler.c:decodeUImmOperand_5 Line | Count | Source | 268 | 20.5k | { \ | 269 | 20.5k | if (!isUIntN(N, Imm)) \ | 270 | 20.5k | return MCDisassembler_Fail; \ | 271 | 20.5k | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 20.5k | return MCDisassembler_Success; \ | 273 | 20.5k | } |
PPCDisassembler.c:decodeUImmOperand_1 Line | Count | Source | 268 | 2.36k | { \ | 269 | 2.36k | if (!isUIntN(N, Imm)) \ | 270 | 2.36k | return MCDisassembler_Fail; \ | 271 | 2.36k | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 2.36k | return MCDisassembler_Success; \ | 273 | 2.36k | } |
PPCDisassembler.c:decodeUImmOperand_4 Line | Count | Source | 268 | 963 | { \ | 269 | 963 | if (!isUIntN(N, Imm)) \ | 270 | 963 | return MCDisassembler_Fail; \ | 271 | 963 | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 957 | return MCDisassembler_Success; \ | 273 | 963 | } |
PPCDisassembler.c:decodeUImmOperand_3 Line | Count | Source | 268 | 2.98k | { \ | 269 | 2.98k | if (!isUIntN(N, Imm)) \ | 270 | 2.98k | return MCDisassembler_Fail; \ | 271 | 2.98k | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 2.98k | return MCDisassembler_Success; \ | 273 | 2.98k | } |
PPCDisassembler.c:decodeUImmOperand_16 Line | Count | Source | 268 | 4.22k | { \ | 269 | 4.22k | if (!isUIntN(N, Imm)) \ | 270 | 4.22k | return MCDisassembler_Fail; \ | 271 | 4.22k | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 4.22k | return MCDisassembler_Success; \ | 273 | 4.22k | } |
PPCDisassembler.c:decodeUImmOperand_6 Line | Count | Source | 268 | 2.18k | { \ | 269 | 2.18k | if (!isUIntN(N, Imm)) \ | 270 | 2.18k | return MCDisassembler_Fail; \ | 271 | 2.18k | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 2.18k | return MCDisassembler_Success; \ | 273 | 2.18k | } |
PPCDisassembler.c:decodeUImmOperand_2 Line | Count | Source | 268 | 1.58k | { \ | 269 | 1.58k | if (!isUIntN(N, Imm)) \ | 270 | 1.58k | return MCDisassembler_Fail; \ | 271 | 1.58k | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 1.58k | return MCDisassembler_Success; \ | 273 | 1.58k | } |
PPCDisassembler.c:decodeUImmOperand_10 Line | Count | Source | 268 | 489 | { \ | 269 | 489 | if (!isUIntN(N, Imm)) \ | 270 | 489 | return MCDisassembler_Fail; \ | 271 | 489 | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 489 | return MCDisassembler_Success; \ | 273 | 489 | } |
PPCDisassembler.c:decodeUImmOperand_8 Line | Count | Source | 268 | 79 | { \ | 269 | 79 | if (!isUIntN(N, Imm)) \ | 270 | 79 | return MCDisassembler_Fail; \ | 271 | 79 | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 79 | return MCDisassembler_Success; \ | 273 | 79 | } |
PPCDisassembler.c:decodeUImmOperand_7 Line | Count | Source | 268 | 108 | { \ | 269 | 108 | if (!isUIntN(N, Imm)) \ | 270 | 108 | return MCDisassembler_Fail; \ | 271 | 108 | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 108 | return MCDisassembler_Success; \ | 273 | 108 | } |
PPCDisassembler.c:decodeUImmOperand_12 Line | Count | Source | 268 | 196 | { \ | 269 | 196 | if (!isUIntN(N, Imm)) \ | 270 | 196 | return MCDisassembler_Fail; \ | 271 | 196 | MCOperand_CreateImm0(Inst, (Imm)); \ | 272 | 196 | return MCDisassembler_Success; \ | 273 | 196 | } |
|
274 | | DEFINE_decodeUImmOperand(1); |
275 | | DEFINE_decodeUImmOperand(2); |
276 | | DEFINE_decodeUImmOperand(3); |
277 | | DEFINE_decodeUImmOperand(4); |
278 | | DEFINE_decodeUImmOperand(5); |
279 | | DEFINE_decodeUImmOperand(6); |
280 | | DEFINE_decodeUImmOperand(7); |
281 | | DEFINE_decodeUImmOperand(8); |
282 | | DEFINE_decodeUImmOperand(10); |
283 | | DEFINE_decodeUImmOperand(12); |
284 | | DEFINE_decodeUImmOperand(16); |
285 | | |
286 | | #define DEFINE_decodeSImmOperand(N) \ |
287 | | static DecodeStatus CONCAT(decodeSImmOperand, \ |
288 | | N)(MCInst * Inst, uint64_t Imm, \ |
289 | | int64_t Address, const void *Decoder) \ |
290 | 6.95k | { \ |
291 | 6.95k | if (!isUIntN(N, Imm)) \ |
292 | 6.95k | return MCDisassembler_Fail; \ |
293 | 6.95k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ |
294 | 6.95k | return MCDisassembler_Success; \ |
295 | 6.95k | } PPCDisassembler.c:decodeSImmOperand_16 Line | Count | Source | 290 | 6.22k | { \ | 291 | 6.22k | if (!isUIntN(N, Imm)) \ | 292 | 6.22k | return MCDisassembler_Fail; \ | 293 | 6.22k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 294 | 6.22k | return MCDisassembler_Success; \ | 295 | 6.22k | } |
PPCDisassembler.c:decodeSImmOperand_5 Line | Count | Source | 290 | 170 | { \ | 291 | 170 | if (!isUIntN(N, Imm)) \ | 292 | 170 | return MCDisassembler_Fail; \ | 293 | 170 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 294 | 170 | return MCDisassembler_Success; \ | 295 | 170 | } |
PPCDisassembler.c:decodeSImmOperand_34 Line | Count | Source | 290 | 561 | { \ | 291 | 561 | if (!isUIntN(N, Imm)) \ | 292 | 561 | return MCDisassembler_Fail; \ | 293 | 561 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 294 | 561 | return MCDisassembler_Success; \ | 295 | 561 | } |
|
296 | | DEFINE_decodeSImmOperand(16); |
297 | | DEFINE_decodeSImmOperand(5); |
298 | | DEFINE_decodeSImmOperand(34); |
299 | | |
300 | | static DecodeStatus decodeImmZeroOperand(MCInst *Inst, uint64_t Imm, |
301 | | int64_t Address, const void *Decoder) |
302 | 329 | { |
303 | 329 | if (Imm != 0) |
304 | 8 | return MCDisassembler_Fail; |
305 | 321 | MCOperand_CreateImm0(Inst, (Imm)); |
306 | 321 | return MCDisassembler_Success; |
307 | 329 | } |
308 | | |
309 | | static DecodeStatus decodeVSRpEvenOperands(MCInst *Inst, uint64_t RegNo, |
310 | | uint64_t Address, |
311 | | const void *Decoder) |
312 | 0 | { |
313 | 0 | if (RegNo & 1) |
314 | 0 | return MCDisassembler_Fail; |
315 | 0 | MCOperand_CreateReg0(Inst, (VSRpRegs[RegNo >> 1])); |
316 | 0 | return MCDisassembler_Success; |
317 | 0 | } |
318 | | |
319 | | static DecodeStatus decodeDispSPE8Operand(MCInst *Inst, uint64_t Imm, |
320 | | int64_t Address, const void *Decoder) |
321 | 0 | { |
322 | | // Decode the dispSPE8 field, which has 5-bits, 8-byte aligned. |
323 | |
|
324 | 0 | uint64_t Disp = Imm & 0x1F; |
325 | |
|
326 | 0 | MCOperand_CreateImm0(Inst, (Disp << 3)); |
327 | 0 | return MCDisassembler_Success; |
328 | 0 | } |
329 | | |
330 | | static DecodeStatus decodeDispSPE4Operand(MCInst *Inst, uint64_t Imm, |
331 | | int64_t Address, const void *Decoder) |
332 | 0 | { |
333 | | // Decode the dispSPE8 field, which has 5-bits, 4-byte aligned. |
334 | |
|
335 | 0 | uint64_t Disp = Imm & 0x1F; |
336 | |
|
337 | 0 | MCOperand_CreateImm0(Inst, (Disp << 2)); |
338 | 0 | return MCDisassembler_Success; |
339 | 0 | } |
340 | | |
341 | | static DecodeStatus decodeDispSPE2Operand(MCInst *Inst, uint64_t Imm, |
342 | | int64_t Address, const void *Decoder) |
343 | 0 | { |
344 | | // Decode the dispSPE8 field, which has 5-bits, 2-byte aligned. |
345 | |
|
346 | 0 | uint64_t Disp = Imm & 0x1F; |
347 | 0 | MCOperand_CreateImm0(Inst, (Disp << 1)); |
348 | 0 | return MCDisassembler_Success; |
349 | 0 | } |
350 | | |
351 | | static DecodeStatus decodeDispRIXOperand(MCInst *Inst, uint64_t Imm, |
352 | | int64_t Address, const void *Decoder) |
353 | 1.38k | { |
354 | | // The rix displacement is an immediate shifted by 2 |
355 | 1.38k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 2), 16))); |
356 | 1.38k | return MCDisassembler_Success; |
357 | 1.38k | } |
358 | | |
359 | | static DecodeStatus decodeDispRIX16Operand(MCInst *Inst, uint64_t Imm, |
360 | | int64_t Address, const void *Decoder) |
361 | 638 | { |
362 | | // The rix16 displacement has 12-bits which are shifted by 4. |
363 | 638 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 4), 16))); |
364 | 638 | return MCDisassembler_Success; |
365 | 638 | } |
366 | | |
367 | | static DecodeStatus decodeDispRIHashOperand(MCInst *Inst, uint64_t Imm, |
368 | | int64_t Address, |
369 | | const void *Decoder) |
370 | 102 | { |
371 | | // Decode the disp field for a hash store or hash check operation. |
372 | | // The field is composed of an immediate value that is 6 bits |
373 | | // and covers the range -8 to -512. The immediate is always negative and 2s |
374 | | // complement which is why we sign extend a 7 bit value. |
375 | 102 | const int64_t Disp = SignExtend64(((Imm & 0x3F) + 64), 7) * 8; |
376 | | |
377 | 102 | MCOperand_CreateImm0(Inst, (Disp)); |
378 | 102 | return MCDisassembler_Success; |
379 | 102 | } |
380 | | |
381 | | static DecodeStatus decodeCRBitMOperand(MCInst *Inst, uint64_t Imm, |
382 | | int64_t Address, const void *Decoder) |
383 | 1.02k | { |
384 | | // The cr bit encoding is 0x80 >> cr_reg_num. |
385 | | |
386 | 1.02k | unsigned Zeros = CountTrailingZeros_32(Imm); |
387 | 1.02k | if (Zeros >= 8) |
388 | 4 | return MCDisassembler_Fail; |
389 | | |
390 | 1.02k | MCOperand_CreateReg0(Inst, (CRRegs[7 - Zeros])); |
391 | 1.02k | return MCDisassembler_Success; |
392 | 1.02k | } |
393 | | |
394 | | #include "PPCGenDisassemblerTables.inc" |
395 | | |
396 | | DecodeStatus getInstruction(csh ud, const uint8_t *Bytes, size_t BytesLen, |
397 | | MCInst *MI, uint16_t *Size, uint64_t Address, |
398 | | void *Info) |
399 | 63.4k | { |
400 | | // If this is an 8-byte prefixed instruction, handle it here. |
401 | | // Note: prefixed instructions aren't technically 8-byte entities - the |
402 | | // prefix |
403 | | // appears in memory at an address 4 bytes prior to that of the base |
404 | | // instruction regardless of endianness. So we read the two pieces and |
405 | | // rebuild the 8-byte instruction. |
406 | | // TODO: In this function we call decodeInstruction several times with |
407 | | // different decoder tables. It may be possible to only call once by |
408 | | // looking at the top 6 bits of the instruction. |
409 | 63.4k | if (PPC_getFeatureBits(MI->csh->mode, PPC_FeaturePrefixInstrs) && |
410 | 63.4k | BytesLen >= 8) { |
411 | 60.5k | uint32_t Prefix = readBytes32(MI, Bytes); |
412 | 60.5k | uint32_t BaseInst = readBytes32(MI, Bytes + 4); |
413 | 60.5k | uint64_t Inst = BaseInst | (uint64_t)Prefix << 32; |
414 | 60.5k | DecodeStatus result = decodeInstruction_4(DecoderTable64, MI, |
415 | 60.5k | Inst, Address, NULL); |
416 | 60.5k | if (result != MCDisassembler_Fail) { |
417 | 672 | *Size = 8; |
418 | 672 | return result; |
419 | 672 | } |
420 | 60.5k | } |
421 | | |
422 | | // Get the four bytes of the instruction. |
423 | 62.8k | *Size = 4; |
424 | 62.8k | if (BytesLen < 4) { |
425 | 917 | *Size = 0; |
426 | 917 | return MCDisassembler_Fail; |
427 | 917 | } |
428 | | |
429 | | // Read the instruction in the proper endianness. |
430 | 61.8k | uint64_t Inst = readBytes32(MI, Bytes); |
431 | | |
432 | 61.8k | if (PPC_getFeatureBits(MI->csh->mode, PPC_FeatureQPX)) { |
433 | 28.5k | DecodeStatus result = decodeInstruction_4(DecoderTableQPX32, MI, |
434 | 28.5k | Inst, Address, NULL); |
435 | 28.5k | if (result != MCDisassembler_Fail) |
436 | 2.56k | return result; |
437 | 33.3k | } else if (PPC_getFeatureBits(MI->csh->mode, PPC_FeatureSPE)) { |
438 | 0 | DecodeStatus result = decodeInstruction_4(DecoderTableSPE32, MI, |
439 | 0 | Inst, Address, NULL); |
440 | 0 | if (result != MCDisassembler_Fail) |
441 | 0 | return result; |
442 | 33.3k | } else if (PPC_getFeatureBits(MI->csh->mode, PPC_FeaturePS)) { |
443 | 9.99k | DecodeStatus result = decodeInstruction_4(DecoderTablePS32, MI, |
444 | 9.99k | Inst, Address, NULL); |
445 | 9.99k | if (result != MCDisassembler_Fail) |
446 | 812 | return result; |
447 | 9.99k | } |
448 | | |
449 | 58.5k | return decodeInstruction_4(DecoderTable32, MI, Inst, Address, NULL); |
450 | 61.8k | } |
451 | | |
452 | | DecodeStatus PPC_LLVM_getInstruction(csh handle, const uint8_t *Bytes, |
453 | | size_t BytesLen, MCInst *MI, |
454 | | uint16_t *Size, uint64_t Address, |
455 | | void *Info) |
456 | 63.4k | { |
457 | 63.4k | return getInstruction(handle, Bytes, BytesLen, MI, Size, Address, Info); |
458 | 63.4k | } |