/src/capstonenext/arch/SystemZ/SystemZDisassembler.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 | | //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- 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 <stdio.h> |
24 | | #include <string.h> |
25 | | #include <stdlib.h> |
26 | | #include <capstone/platform.h> |
27 | | |
28 | | #include "../../MCInst.h" |
29 | | #include "../../MathExtras.h" |
30 | | #include "../../MCInstPrinter.h" |
31 | | #include "../../MCDisassembler.h" |
32 | | #include "../../MCFixedLenDisassembler.h" |
33 | | #include "../../cs_priv.h" |
34 | | #include "../../utils.h" |
35 | | |
36 | | #include "SystemZMCTargetDesc.h" |
37 | | #include "SystemZDisassemblerExtension.h" |
38 | | |
39 | 74.8k | #define CONCAT(a, b) CONCAT_(a, b) |
40 | 74.8k | #define CONCAT_(a, b) a##_##b |
41 | | |
42 | | #define DEBUG_TYPE "systemz-disassembler" |
43 | | |
44 | | static DecodeStatus getInstruction(MCInst *Instr, uint16_t *Size, const uint8_t *Bytes, |
45 | | size_t BytesLen, uint64_t Address, |
46 | | SStream *CStream); |
47 | | |
48 | | /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the |
49 | | /// immediate Value in the MCInst. |
50 | | /// |
51 | | /// @param Value - The immediate Value, has had any PC adjustment made by |
52 | | /// the caller. |
53 | | /// @param isBranch - If the instruction is a branch instruction |
54 | | /// @param Address - The starting address of the instruction |
55 | | /// @param Offset - The byte offset to this immediate in the instruction |
56 | | /// @param Width - The byte width of this immediate in the instruction |
57 | | /// |
58 | | /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was |
59 | | /// called then that function is called to get any symbolic information for the |
60 | | /// immediate in the instruction using the Address, Offset and Width. If that |
61 | | /// returns non-zero then the symbolic information it returns is used to create |
62 | | /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() |
63 | | /// returns zero and isBranch is true then a symbol look up for immediate Value |
64 | | /// is done and if a symbol is found an MCExpr is created with that, else |
65 | | /// an MCExpr with the immediate Value is created. This function returns true |
66 | | /// if it adds an operand to the MCInst and false otherwise. |
67 | | static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch, |
68 | | uint64_t Address, uint64_t Offset, |
69 | | uint64_t Width, MCInst *MI, |
70 | | const void *Decoder) |
71 | 3.72k | { |
72 | | // return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, |
73 | | // Offset, Width, /*InstSize=*/0); |
74 | 3.72k | return false; |
75 | 3.72k | } |
76 | | |
77 | | static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, |
78 | | const unsigned *Regs, unsigned Size, |
79 | | bool IsAddr) |
80 | 200k | { |
81 | 200k | CS_ASSERT((RegNo < Size && "Invalid register")); |
82 | 200k | if (IsAddr && RegNo == 0) { |
83 | 19.5k | RegNo = SystemZ_NoRegister; |
84 | 181k | } else { |
85 | 181k | RegNo = Regs[RegNo]; |
86 | 181k | if (RegNo == 0) |
87 | 139 | return MCDisassembler_Fail; |
88 | 181k | } |
89 | 200k | MCOperand_CreateReg0(Inst, (RegNo)); |
90 | 200k | return MCDisassembler_Success; |
91 | 200k | } |
92 | | |
93 | | static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
94 | | uint64_t Address, |
95 | | const void *Decoder) |
96 | 41.0k | { |
97 | 41.0k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, false); |
98 | 41.0k | } |
99 | | |
100 | | static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
101 | | uint64_t Address, |
102 | | const void *Decoder) |
103 | 3.37k | { |
104 | 3.37k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs, 16, false); |
105 | 3.37k | } |
106 | | |
107 | | static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
108 | | uint64_t Address, |
109 | | const void *Decoder) |
110 | 21.1k | { |
111 | 21.1k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, false); |
112 | 21.1k | } |
113 | | |
114 | | static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
115 | | uint64_t Address, |
116 | | const void *Decoder) |
117 | 10.4k | { |
118 | 10.4k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs, 16, false); |
119 | 10.4k | } |
120 | | |
121 | | static DecodeStatus DecodeADDR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
122 | | uint64_t Address, |
123 | | const void *Decoder) |
124 | 3.08k | { |
125 | 3.08k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, true); |
126 | 3.08k | } |
127 | | |
128 | | static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
129 | | uint64_t Address, |
130 | | const void *Decoder) |
131 | 66.3k | { |
132 | 66.3k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, true); |
133 | 66.3k | } |
134 | | |
135 | | static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
136 | | uint64_t Address, |
137 | | const void *Decoder) |
138 | 13.6k | { |
139 | 13.6k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs, 16, false); |
140 | 13.6k | } |
141 | | |
142 | | static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
143 | | uint64_t Address, |
144 | | const void *Decoder) |
145 | 19.0k | { |
146 | 19.0k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs, 16, false); |
147 | 19.0k | } |
148 | | |
149 | | static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
150 | | uint64_t Address, |
151 | | const void *Decoder) |
152 | 3.52k | { |
153 | 3.52k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs, 16, false); |
154 | 3.52k | } |
155 | | |
156 | | static DecodeStatus DecodeVR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
157 | | uint64_t Address, |
158 | | const void *Decoder) |
159 | 2.20k | { |
160 | 2.20k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR32Regs, 32, false); |
161 | 2.20k | } |
162 | | |
163 | | static DecodeStatus DecodeVR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
164 | | uint64_t Address, |
165 | | const void *Decoder) |
166 | 1.12k | { |
167 | 1.12k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR64Regs, 32, false); |
168 | 1.12k | } |
169 | | |
170 | | static DecodeStatus DecodeVR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
171 | | uint64_t Address, |
172 | | const void *Decoder) |
173 | 13.6k | { |
174 | 13.6k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR128Regs, 32, false); |
175 | 13.6k | } |
176 | | |
177 | | static DecodeStatus DecodeAR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
178 | | uint64_t Address, |
179 | | const void *Decoder) |
180 | 1.48k | { |
181 | 1.48k | return decodeRegisterClass(Inst, RegNo, SystemZMC_AR32Regs, 16, false); |
182 | 1.48k | } |
183 | | |
184 | | static DecodeStatus DecodeCR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
185 | | uint64_t Address, |
186 | | const void *Decoder) |
187 | 678 | { |
188 | 678 | return decodeRegisterClass(Inst, RegNo, SystemZMC_CR64Regs, 16, false); |
189 | 678 | } |
190 | | |
191 | | #define DEFINE_decodeUImmOperand(N) \ |
192 | | static DecodeStatus CONCAT(decodeUImmOperand, N)(MCInst * Inst, \ |
193 | | uint64_t Imm) \ |
194 | 62.4k | { \ |
195 | 62.4k | if (!isUIntN(N, Imm)) \ |
196 | 62.4k | return MCDisassembler_Fail; \ |
197 | 62.4k | MCOperand_CreateImm0(Inst, (Imm)); \ |
198 | 62.3k | return MCDisassembler_Success; \ |
199 | 62.4k | } SystemZDisassembler.c:decodeUImmOperand_4 Line | Count | Source | 194 | 14.6k | { \ | 195 | 14.6k | if (!isUIntN(N, Imm)) \ | 196 | 14.6k | return MCDisassembler_Fail; \ | 197 | 14.6k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 14.6k | return MCDisassembler_Success; \ | 199 | 14.6k | } |
SystemZDisassembler.c:decodeUImmOperand_8 Line | Count | Source | 194 | 4.34k | { \ | 195 | 4.34k | if (!isUIntN(N, Imm)) \ | 196 | 4.34k | return MCDisassembler_Fail; \ | 197 | 4.34k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 4.34k | return MCDisassembler_Success; \ | 199 | 4.34k | } |
SystemZDisassembler.c:decodeUImmOperand_12 Line | Count | Source | 194 | 40.1k | { \ | 195 | 40.1k | if (!isUIntN(N, Imm)) \ | 196 | 40.1k | return MCDisassembler_Fail; \ | 197 | 40.1k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 40.1k | return MCDisassembler_Success; \ | 199 | 40.1k | } |
SystemZDisassembler.c:decodeUImmOperand_16 Line | Count | Source | 194 | 823 | { \ | 195 | 823 | if (!isUIntN(N, Imm)) \ | 196 | 823 | return MCDisassembler_Fail; \ | 197 | 823 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 823 | return MCDisassembler_Success; \ | 199 | 823 | } |
SystemZDisassembler.c:decodeUImmOperand_32 Line | Count | Source | 194 | 631 | { \ | 195 | 631 | if (!isUIntN(N, Imm)) \ | 196 | 631 | return MCDisassembler_Fail; \ | 197 | 631 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 631 | return MCDisassembler_Success; \ | 199 | 631 | } |
SystemZDisassembler.c:decodeUImmOperand_3 Line | Count | Source | 194 | 491 | { \ | 195 | 491 | if (!isUIntN(N, Imm)) \ | 196 | 491 | return MCDisassembler_Fail; \ | 197 | 491 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 487 | return MCDisassembler_Success; \ | 199 | 491 | } |
SystemZDisassembler.c:decodeUImmOperand_1 Line | Count | Source | 194 | 756 | { \ | 195 | 756 | if (!isUIntN(N, Imm)) \ | 196 | 756 | return MCDisassembler_Fail; \ | 197 | 756 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 749 | return MCDisassembler_Success; \ | 199 | 756 | } |
SystemZDisassembler.c:decodeUImmOperand_2 Line | Count | Source | 194 | 507 | { \ | 195 | 507 | if (!isUIntN(N, Imm)) \ | 196 | 507 | return MCDisassembler_Fail; \ | 197 | 507 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 500 | return MCDisassembler_Success; \ | 199 | 507 | } |
|
200 | | DEFINE_decodeUImmOperand(1); |
201 | | DEFINE_decodeUImmOperand(2); |
202 | | DEFINE_decodeUImmOperand(3); |
203 | | DEFINE_decodeUImmOperand(4); |
204 | | DEFINE_decodeUImmOperand(8); |
205 | | DEFINE_decodeUImmOperand(12); |
206 | | DEFINE_decodeUImmOperand(16); |
207 | | DEFINE_decodeUImmOperand(32); |
208 | | |
209 | | #define DEFINE_decodeSImmOperand(N) \ |
210 | | static DecodeStatus CONCAT(decodeSImmOperand, N)(MCInst * Inst, \ |
211 | | uint64_t Imm) \ |
212 | 8.75k | { \ |
213 | 8.75k | if (!isUIntN(N, Imm)) \ |
214 | 8.75k | return MCDisassembler_Fail; \ |
215 | 8.75k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ |
216 | 8.75k | return MCDisassembler_Success; \ |
217 | 8.75k | } SystemZDisassembler.c:decodeSImmOperand_16 Line | Count | Source | 212 | 1.54k | { \ | 213 | 1.54k | if (!isUIntN(N, Imm)) \ | 214 | 1.54k | return MCDisassembler_Fail; \ | 215 | 1.54k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 1.54k | return MCDisassembler_Success; \ | 217 | 1.54k | } |
SystemZDisassembler.c:decodeSImmOperand_32 Line | Count | Source | 212 | 348 | { \ | 213 | 348 | if (!isUIntN(N, Imm)) \ | 214 | 348 | return MCDisassembler_Fail; \ | 215 | 348 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 348 | return MCDisassembler_Success; \ | 217 | 348 | } |
SystemZDisassembler.c:decodeSImmOperand_20 Line | Count | Source | 212 | 6.14k | { \ | 213 | 6.14k | if (!isUIntN(N, Imm)) \ | 214 | 6.14k | return MCDisassembler_Fail; \ | 215 | 6.14k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 6.14k | return MCDisassembler_Success; \ | 217 | 6.14k | } |
SystemZDisassembler.c:decodeSImmOperand_8 Line | Count | Source | 212 | 718 | { \ | 213 | 718 | if (!isUIntN(N, Imm)) \ | 214 | 718 | return MCDisassembler_Fail; \ | 215 | 718 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 718 | return MCDisassembler_Success; \ | 217 | 718 | } |
|
218 | | DEFINE_decodeSImmOperand(8); |
219 | | DEFINE_decodeSImmOperand(16); |
220 | | DEFINE_decodeSImmOperand(20); |
221 | | DEFINE_decodeSImmOperand(32); |
222 | | |
223 | | static DecodeStatus decodeU1ImmOperand(MCInst *Inst, uint64_t Imm, |
224 | | uint64_t Address, const void *Decoder) |
225 | 756 | { |
226 | 756 | return CONCAT(decodeUImmOperand, 1)(Inst, Imm); |
227 | 756 | } |
228 | | |
229 | | static DecodeStatus decodeU2ImmOperand(MCInst *Inst, uint64_t Imm, |
230 | | uint64_t Address, const void *Decoder) |
231 | 507 | { |
232 | 507 | return CONCAT(decodeUImmOperand, 2)(Inst, Imm); |
233 | 507 | } |
234 | | |
235 | | static DecodeStatus decodeU3ImmOperand(MCInst *Inst, uint64_t Imm, |
236 | | uint64_t Address, const void *Decoder) |
237 | 491 | { |
238 | 491 | return CONCAT(decodeUImmOperand, 3)(Inst, Imm); |
239 | 491 | } |
240 | | |
241 | | static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm, |
242 | | uint64_t Address, const void *Decoder) |
243 | 14.6k | { |
244 | 14.6k | return CONCAT(decodeUImmOperand, 4)(Inst, Imm); |
245 | 14.6k | } |
246 | | |
247 | | static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm, |
248 | | uint64_t Address, const void *Decoder) |
249 | 4.34k | { |
250 | 4.34k | return CONCAT(decodeUImmOperand, 8)(Inst, Imm); |
251 | 4.34k | } |
252 | | |
253 | | static DecodeStatus decodeU12ImmOperand(MCInst *Inst, uint64_t Imm, |
254 | | uint64_t Address, const void *Decoder) |
255 | 40.1k | { |
256 | 40.1k | return CONCAT(decodeUImmOperand, 12)(Inst, Imm); |
257 | 40.1k | } |
258 | | |
259 | | static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm, |
260 | | uint64_t Address, const void *Decoder) |
261 | 823 | { |
262 | 823 | return CONCAT(decodeUImmOperand, 16)(Inst, Imm); |
263 | 823 | } |
264 | | |
265 | | static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm, |
266 | | uint64_t Address, const void *Decoder) |
267 | 631 | { |
268 | 631 | return CONCAT(decodeUImmOperand, 32)(Inst, Imm); |
269 | 631 | } |
270 | | |
271 | | static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm, |
272 | | uint64_t Address, const void *Decoder) |
273 | 718 | { |
274 | 718 | return CONCAT(decodeSImmOperand, 8)(Inst, Imm); |
275 | 718 | } |
276 | | |
277 | | static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm, |
278 | | uint64_t Address, const void *Decoder) |
279 | 1.54k | { |
280 | 1.54k | return CONCAT(decodeSImmOperand, 16)(Inst, Imm); |
281 | 1.54k | } |
282 | | |
283 | | static DecodeStatus decodeS20ImmOperand(MCInst *Inst, uint64_t Imm, |
284 | | uint64_t Address, const void *Decoder) |
285 | 6.14k | { |
286 | 6.14k | return CONCAT(decodeSImmOperand, 20)(Inst, Imm); |
287 | 6.14k | } |
288 | | |
289 | | static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm, |
290 | | uint64_t Address, const void *Decoder) |
291 | 348 | { |
292 | 348 | return CONCAT(decodeSImmOperand, 32)(Inst, Imm); |
293 | 348 | } |
294 | | |
295 | | #define DEFINE_decodeLenOperand(N) \ |
296 | | static DecodeStatus CONCAT(decodeLenOperand, \ |
297 | | N)(MCInst * Inst, uint64_t Imm, \ |
298 | | uint64_t Address, const void *Decoder) \ |
299 | 6.49k | { \ |
300 | 6.49k | if (!isUIntN(N, Imm)) \ |
301 | 6.49k | return MCDisassembler_Fail; \ |
302 | 6.49k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ |
303 | 6.49k | return MCDisassembler_Success; \ |
304 | 6.49k | } SystemZDisassembler.c:decodeLenOperand_8 Line | Count | Source | 299 | 2.96k | { \ | 300 | 2.96k | if (!isUIntN(N, Imm)) \ | 301 | 2.96k | return MCDisassembler_Fail; \ | 302 | 2.96k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ | 303 | 2.96k | return MCDisassembler_Success; \ | 304 | 2.96k | } |
SystemZDisassembler.c:decodeLenOperand_4 Line | Count | Source | 299 | 3.52k | { \ | 300 | 3.52k | if (!isUIntN(N, Imm)) \ | 301 | 3.52k | return MCDisassembler_Fail; \ | 302 | 3.52k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ | 303 | 3.52k | return MCDisassembler_Success; \ | 304 | 3.52k | } |
|
305 | | DEFINE_decodeLenOperand(8); |
306 | | DEFINE_decodeLenOperand(4); |
307 | | |
308 | | #define DEFINE_decodePCDBLOperand(N) \ |
309 | | static DecodeStatus CONCAT(decodePCDBLOperand, N)( \ |
310 | | MCInst * Inst, uint64_t Imm, uint64_t Address, bool isBranch, \ |
311 | | const void *Decoder) \ |
312 | 3.72k | { \ |
313 | 3.72k | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ |
314 | 3.72k | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ |
315 | 3.72k | \ |
316 | 3.72k | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ |
317 | 3.72k | N / 8, Inst, Decoder)) \ |
318 | 3.72k | MCOperand_CreateImm0(Inst, (Value)); \ |
319 | 3.72k | \ |
320 | 3.72k | return MCDisassembler_Success; \ |
321 | 3.72k | } SystemZDisassembler.c:decodePCDBLOperand_16 Line | Count | Source | 312 | 1.89k | { \ | 313 | 1.89k | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 1.89k | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 1.89k | \ | 316 | 1.89k | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 1.89k | N / 8, Inst, Decoder)) \ | 318 | 1.89k | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 1.89k | \ | 320 | 1.89k | return MCDisassembler_Success; \ | 321 | 1.89k | } |
SystemZDisassembler.c:decodePCDBLOperand_32 Line | Count | Source | 312 | 956 | { \ | 313 | 956 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 956 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 956 | \ | 316 | 956 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 956 | N / 8, Inst, Decoder)) \ | 318 | 956 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 956 | \ | 320 | 956 | return MCDisassembler_Success; \ | 321 | 956 | } |
SystemZDisassembler.c:decodePCDBLOperand_12 Line | Count | Source | 312 | 434 | { \ | 313 | 434 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 434 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 434 | \ | 316 | 434 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 434 | N / 8, Inst, Decoder)) \ | 318 | 434 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 434 | \ | 320 | 434 | return MCDisassembler_Success; \ | 321 | 434 | } |
SystemZDisassembler.c:decodePCDBLOperand_24 Line | Count | Source | 312 | 434 | { \ | 313 | 434 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 434 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 434 | \ | 316 | 434 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 434 | N / 8, Inst, Decoder)) \ | 318 | 434 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 434 | \ | 320 | 434 | return MCDisassembler_Success; \ | 321 | 434 | } |
|
322 | | DEFINE_decodePCDBLOperand(12); |
323 | | DEFINE_decodePCDBLOperand(16); |
324 | | DEFINE_decodePCDBLOperand(24); |
325 | | DEFINE_decodePCDBLOperand(32); |
326 | | |
327 | | static DecodeStatus decodePC12DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
328 | | uint64_t Address, |
329 | | const void *Decoder) |
330 | 434 | { |
331 | 434 | return CONCAT(decodePCDBLOperand, 12)(Inst, Imm, Address, true, |
332 | 434 | Decoder); |
333 | 434 | } |
334 | | |
335 | | static DecodeStatus decodePC16DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
336 | | uint64_t Address, |
337 | | const void *Decoder) |
338 | 1.89k | { |
339 | 1.89k | return CONCAT(decodePCDBLOperand, 16)(Inst, Imm, Address, true, |
340 | 1.89k | Decoder); |
341 | 1.89k | } |
342 | | |
343 | | static DecodeStatus decodePC24DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
344 | | uint64_t Address, |
345 | | const void *Decoder) |
346 | 434 | { |
347 | 434 | return CONCAT(decodePCDBLOperand, 24)(Inst, Imm, Address, true, |
348 | 434 | Decoder); |
349 | 434 | } |
350 | | |
351 | | static DecodeStatus decodePC32DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
352 | | uint64_t Address, |
353 | | const void *Decoder) |
354 | 236 | { |
355 | 236 | return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, true, |
356 | 236 | Decoder); |
357 | 236 | } |
358 | | |
359 | | static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm, |
360 | | uint64_t Address, const void *Decoder) |
361 | 720 | { |
362 | 720 | return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, false, |
363 | 720 | Decoder); |
364 | 720 | } |
365 | | |
366 | | #include "SystemZGenDisassemblerTables.inc" |
367 | | |
368 | | static DecodeStatus getInstruction(MCInst *MI, uint16_t *Size, const uint8_t *Bytes, |
369 | | size_t BytesLen, uint64_t Address, SStream *CS) |
370 | 79.7k | { |
371 | | // Get the first two bytes of the instruction. |
372 | 79.7k | *Size = 0; |
373 | 79.7k | if (BytesLen < 2) |
374 | 510 | return MCDisassembler_Fail; |
375 | | |
376 | | // The top 2 bits of the first byte specify the size. |
377 | 79.2k | const uint8_t *Table; |
378 | 79.2k | uint64_t Inst = 0; |
379 | 79.2k | if (Bytes[0] < 0x40) { |
380 | 23.7k | *Size = 2; |
381 | 23.7k | Table = DecoderTable16; |
382 | 23.7k | Inst = readBytes16(MI, Bytes); |
383 | 55.5k | } else if (Bytes[0] < 0xc0) { |
384 | 26.5k | if (BytesLen < 4) { |
385 | 205 | return MCDisassembler_Fail; |
386 | 205 | } |
387 | 26.3k | *Size = 4; |
388 | 26.3k | Table = DecoderTable32; |
389 | 26.3k | Inst = readBytes32(MI, Bytes); |
390 | 28.9k | } else { |
391 | 28.9k | if (BytesLen < 6) { |
392 | 210 | return MCDisassembler_Fail; |
393 | 210 | } |
394 | 28.7k | *Size = 6; |
395 | 28.7k | Table = DecoderTable48; |
396 | 28.7k | Inst = readBytes48(MI, Bytes); |
397 | 28.7k | } |
398 | | |
399 | | // Read any remaining bytes. |
400 | 78.8k | if (BytesLen < *Size) { |
401 | 0 | *Size = BytesLen; |
402 | 0 | return MCDisassembler_Fail; |
403 | 0 | } |
404 | | |
405 | 78.8k | return decodeInstruction_8(Table, MI, Inst, Address, NULL); |
406 | 78.8k | } |
407 | | |
408 | | DecodeStatus SystemZ_LLVM_getInstruction(csh handle, const uint8_t *Bytes, |
409 | | size_t BytesLen, MCInst *MI, |
410 | | uint16_t *Size, uint64_t Address, |
411 | | void *Info) |
412 | 79.7k | { |
413 | 79.7k | return getInstruction(MI, Size, Bytes, BytesLen, MI->address, NULL); |
414 | 79.7k | } |