/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 | 182k | #define CONCAT(a, b) CONCAT_(a, b) |
40 | 182k | #define CONCAT_(a, b) a##_##b |
41 | | |
42 | | #define DEBUG_TYPE "systemz-disassembler" |
43 | | |
44 | | static DecodeStatus getInstruction(MCInst *Instr, uint16_t *Size, |
45 | | const uint8_t *Bytes, size_t BytesLen, |
46 | | uint64_t Address, 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 | 5.02k | { |
72 | | // return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, |
73 | | // Offset, Width, /*InstSize=*/0); |
74 | 5.02k | return false; |
75 | 5.02k | } |
76 | | |
77 | | static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, |
78 | | const unsigned *Regs, unsigned Size, |
79 | | bool IsAddr) |
80 | 340k | { |
81 | 340k | CS_ASSERT((RegNo < Size && "Invalid register")); |
82 | 340k | if (IsAddr && RegNo == 0) { |
83 | 43.5k | RegNo = SystemZ_NoRegister; |
84 | 297k | } else { |
85 | 297k | RegNo = Regs[RegNo]; |
86 | 297k | if (RegNo == 0) |
87 | 190 | return MCDisassembler_Fail; |
88 | 297k | } |
89 | 340k | MCOperand_CreateReg0(Inst, (RegNo)); |
90 | 340k | return MCDisassembler_Success; |
91 | 340k | } |
92 | | |
93 | | static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
94 | | uint64_t Address, |
95 | | const void *Decoder) |
96 | 98.8k | { |
97 | 98.8k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, false); |
98 | 98.8k | } |
99 | | |
100 | | static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
101 | | uint64_t Address, |
102 | | const void *Decoder) |
103 | 14.1k | { |
104 | 14.1k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs, 16, false); |
105 | 14.1k | } |
106 | | |
107 | | static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
108 | | uint64_t Address, |
109 | | const void *Decoder) |
110 | 61.8k | { |
111 | 61.8k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, false); |
112 | 61.8k | } |
113 | | |
114 | | static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
115 | | uint64_t Address, |
116 | | const void *Decoder) |
117 | 29.6k | { |
118 | 29.6k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs, 16, false); |
119 | 29.6k | } |
120 | | |
121 | | static DecodeStatus DecodeADDR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
122 | | uint64_t Address, |
123 | | const void *Decoder) |
124 | 6.12k | { |
125 | 6.12k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, true); |
126 | 6.12k | } |
127 | | |
128 | | static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
129 | | uint64_t Address, |
130 | | const void *Decoder) |
131 | 122k | { |
132 | 122k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, true); |
133 | 122k | } |
134 | | |
135 | | static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
136 | | uint64_t Address, |
137 | | const void *Decoder) |
138 | 44.1k | { |
139 | 44.1k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs, 16, false); |
140 | 44.1k | } |
141 | | |
142 | | static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
143 | | uint64_t Address, |
144 | | const void *Decoder) |
145 | 49.8k | { |
146 | 49.8k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs, 16, false); |
147 | 49.8k | } |
148 | | |
149 | | static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
150 | | uint64_t Address, |
151 | | const void *Decoder) |
152 | 11.5k | { |
153 | 11.5k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs, 16, false); |
154 | 11.5k | } |
155 | | |
156 | | static DecodeStatus DecodeVR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
157 | | uint64_t Address, |
158 | | const void *Decoder) |
159 | 5.68k | { |
160 | 5.68k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR32Regs, 32, false); |
161 | 5.68k | } |
162 | | |
163 | | static DecodeStatus DecodeVR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
164 | | uint64_t Address, |
165 | | const void *Decoder) |
166 | 3.05k | { |
167 | 3.05k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR64Regs, 32, false); |
168 | 3.05k | } |
169 | | |
170 | | static DecodeStatus DecodeVR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
171 | | uint64_t Address, |
172 | | const void *Decoder) |
173 | 38.9k | { |
174 | 38.9k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR128Regs, 32, false); |
175 | 38.9k | } |
176 | | |
177 | | static DecodeStatus DecodeAR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
178 | | uint64_t Address, |
179 | | const void *Decoder) |
180 | 3.09k | { |
181 | 3.09k | return decodeRegisterClass(Inst, RegNo, SystemZMC_AR32Regs, 16, false); |
182 | 3.09k | } |
183 | | |
184 | | static DecodeStatus DecodeCR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
185 | | uint64_t Address, |
186 | | const void *Decoder) |
187 | 3.54k | { |
188 | 3.54k | return decodeRegisterClass(Inst, RegNo, SystemZMC_CR64Regs, 16, false); |
189 | 3.54k | } |
190 | | |
191 | | #define DEFINE_decodeUImmOperand(N) \ |
192 | | static DecodeStatus CONCAT(decodeUImmOperand, N)(MCInst * Inst, \ |
193 | | uint64_t Imm) \ |
194 | 111k | { \ |
195 | 111k | if (!isUIntN(N, Imm)) \ |
196 | 111k | return MCDisassembler_Fail; \ |
197 | 111k | MCOperand_CreateImm0(Inst, (Imm)); \ |
198 | 111k | return MCDisassembler_Success; \ |
199 | 111k | } SystemZDisassembler.c:decodeUImmOperand_4 Line | Count | Source | 194 | 21.9k | { \ | 195 | 21.9k | if (!isUIntN(N, Imm)) \ | 196 | 21.9k | return MCDisassembler_Fail; \ | 197 | 21.9k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 21.9k | return MCDisassembler_Success; \ | 199 | 21.9k | } |
SystemZDisassembler.c:decodeUImmOperand_8 Line | Count | Source | 194 | 8.48k | { \ | 195 | 8.48k | if (!isUIntN(N, Imm)) \ | 196 | 8.48k | return MCDisassembler_Fail; \ | 197 | 8.48k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 8.48k | return MCDisassembler_Success; \ | 199 | 8.48k | } |
SystemZDisassembler.c:decodeUImmOperand_12 Line | Count | Source | 194 | 73.2k | { \ | 195 | 73.2k | if (!isUIntN(N, Imm)) \ | 196 | 73.2k | return MCDisassembler_Fail; \ | 197 | 73.2k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 73.2k | return MCDisassembler_Success; \ | 199 | 73.2k | } |
SystemZDisassembler.c:decodeUImmOperand_16 Line | Count | Source | 194 | 2.28k | { \ | 195 | 2.28k | if (!isUIntN(N, Imm)) \ | 196 | 2.28k | return MCDisassembler_Fail; \ | 197 | 2.28k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 2.28k | return MCDisassembler_Success; \ | 199 | 2.28k | } |
SystemZDisassembler.c:decodeUImmOperand_32 Line | Count | Source | 194 | 1.34k | { \ | 195 | 1.34k | if (!isUIntN(N, Imm)) \ | 196 | 1.34k | return MCDisassembler_Fail; \ | 197 | 1.34k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 1.34k | return MCDisassembler_Success; \ | 199 | 1.34k | } |
SystemZDisassembler.c:decodeUImmOperand_3 Line | Count | Source | 194 | 1.01k | { \ | 195 | 1.01k | if (!isUIntN(N, Imm)) \ | 196 | 1.01k | return MCDisassembler_Fail; \ | 197 | 1.01k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 1.01k | return MCDisassembler_Success; \ | 199 | 1.01k | } |
SystemZDisassembler.c:decodeUImmOperand_1 Line | Count | Source | 194 | 1.47k | { \ | 195 | 1.47k | if (!isUIntN(N, Imm)) \ | 196 | 1.47k | return MCDisassembler_Fail; \ | 197 | 1.47k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 1.46k | return MCDisassembler_Success; \ | 199 | 1.47k | } |
SystemZDisassembler.c:decodeUImmOperand_2 Line | Count | Source | 194 | 1.92k | { \ | 195 | 1.92k | if (!isUIntN(N, Imm)) \ | 196 | 1.92k | return MCDisassembler_Fail; \ | 197 | 1.92k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 1.92k | return MCDisassembler_Success; \ | 199 | 1.92k | } |
|
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 | 19.4k | { \ |
213 | 19.4k | if (!isUIntN(N, Imm)) \ |
214 | 19.4k | return MCDisassembler_Fail; \ |
215 | 19.4k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ |
216 | 19.4k | return MCDisassembler_Success; \ |
217 | 19.4k | } SystemZDisassembler.c:decodeSImmOperand_16 Line | Count | Source | 212 | 2.26k | { \ | 213 | 2.26k | if (!isUIntN(N, Imm)) \ | 214 | 2.26k | return MCDisassembler_Fail; \ | 215 | 2.26k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 2.26k | return MCDisassembler_Success; \ | 217 | 2.26k | } |
SystemZDisassembler.c:decodeSImmOperand_32 Line | Count | Source | 212 | 1.23k | { \ | 213 | 1.23k | if (!isUIntN(N, Imm)) \ | 214 | 1.23k | return MCDisassembler_Fail; \ | 215 | 1.23k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 1.23k | return MCDisassembler_Success; \ | 217 | 1.23k | } |
SystemZDisassembler.c:decodeSImmOperand_20 Line | Count | Source | 212 | 14.4k | { \ | 213 | 14.4k | if (!isUIntN(N, Imm)) \ | 214 | 14.4k | return MCDisassembler_Fail; \ | 215 | 14.4k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 14.4k | return MCDisassembler_Success; \ | 217 | 14.4k | } |
SystemZDisassembler.c:decodeSImmOperand_8 Line | Count | Source | 212 | 1.56k | { \ | 213 | 1.56k | if (!isUIntN(N, Imm)) \ | 214 | 1.56k | return MCDisassembler_Fail; \ | 215 | 1.56k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 1.56k | return MCDisassembler_Success; \ | 217 | 1.56k | } |
|
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 | 2.37k | { |
226 | 2.37k | return CONCAT(decodeUImmOperand, 1)(Inst, Imm); |
227 | 2.37k | } |
228 | | |
229 | | static DecodeStatus decodeU2ImmOperand(MCInst *Inst, uint64_t Imm, |
230 | | uint64_t Address, const void *Decoder) |
231 | 3.17k | { |
232 | 3.17k | return CONCAT(decodeUImmOperand, 2)(Inst, Imm); |
233 | 3.17k | } |
234 | | |
235 | | static DecodeStatus decodeU3ImmOperand(MCInst *Inst, uint64_t Imm, |
236 | | uint64_t Address, const void *Decoder) |
237 | 1.18k | { |
238 | 1.18k | return CONCAT(decodeUImmOperand, 3)(Inst, Imm); |
239 | 1.18k | } |
240 | | |
241 | | static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm, |
242 | | uint64_t Address, const void *Decoder) |
243 | 44.9k | { |
244 | 44.9k | return CONCAT(decodeUImmOperand, 4)(Inst, Imm); |
245 | 44.9k | } |
246 | | |
247 | | static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm, |
248 | | uint64_t Address, const void *Decoder) |
249 | 13.8k | { |
250 | 13.8k | return CONCAT(decodeUImmOperand, 8)(Inst, Imm); |
251 | 13.8k | } |
252 | | |
253 | | static DecodeStatus decodeU12ImmOperand(MCInst *Inst, uint64_t Imm, |
254 | | uint64_t Address, const void *Decoder) |
255 | 73.7k | { |
256 | 73.7k | return CONCAT(decodeUImmOperand, 12)(Inst, Imm); |
257 | 73.7k | } |
258 | | |
259 | | static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm, |
260 | | uint64_t Address, const void *Decoder) |
261 | 4.84k | { |
262 | 4.84k | return CONCAT(decodeUImmOperand, 16)(Inst, Imm); |
263 | 4.84k | } |
264 | | |
265 | | static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm, |
266 | | uint64_t Address, const void *Decoder) |
267 | 2.18k | { |
268 | 2.18k | return CONCAT(decodeUImmOperand, 32)(Inst, Imm); |
269 | 2.18k | } |
270 | | |
271 | | static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm, |
272 | | uint64_t Address, const void *Decoder) |
273 | 3.34k | { |
274 | 3.34k | return CONCAT(decodeSImmOperand, 8)(Inst, Imm); |
275 | 3.34k | } |
276 | | |
277 | | static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm, |
278 | | uint64_t Address, const void *Decoder) |
279 | 5.62k | { |
280 | 5.62k | return CONCAT(decodeSImmOperand, 16)(Inst, Imm); |
281 | 5.62k | } |
282 | | |
283 | | static DecodeStatus decodeS20ImmOperand(MCInst *Inst, uint64_t Imm, |
284 | | uint64_t Address, const void *Decoder) |
285 | 14.4k | { |
286 | 14.4k | return CONCAT(decodeSImmOperand, 20)(Inst, Imm); |
287 | 14.4k | } |
288 | | |
289 | | static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm, |
290 | | uint64_t Address, const void *Decoder) |
291 | 2.04k | { |
292 | 2.04k | return CONCAT(decodeSImmOperand, 32)(Inst, Imm); |
293 | 2.04k | } |
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 | 11.9k | { \ |
300 | 11.9k | if (!isUIntN(N, Imm)) \ |
301 | 11.9k | return MCDisassembler_Fail; \ |
302 | 11.9k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ |
303 | 11.9k | return MCDisassembler_Success; \ |
304 | 11.9k | } SystemZDisassembler.c:decodeLenOperand_8 Line | Count | Source | 299 | 4.75k | { \ | 300 | 4.75k | if (!isUIntN(N, Imm)) \ | 301 | 4.75k | return MCDisassembler_Fail; \ | 302 | 4.75k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ | 303 | 4.75k | return MCDisassembler_Success; \ | 304 | 4.75k | } |
SystemZDisassembler.c:decodeLenOperand_4 Line | Count | Source | 299 | 7.17k | { \ | 300 | 7.17k | if (!isUIntN(N, Imm)) \ | 301 | 7.17k | return MCDisassembler_Fail; \ | 302 | 7.17k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ | 303 | 7.17k | return MCDisassembler_Success; \ | 304 | 7.17k | } |
|
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 | 5.02k | { \ |
313 | 5.02k | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ |
314 | 5.02k | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ |
315 | 5.02k | \ |
316 | 5.02k | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ |
317 | 5.02k | N / 8, Inst, Decoder)) \ |
318 | 5.02k | MCOperand_CreateImm0(Inst, (Value)); \ |
319 | 5.02k | \ |
320 | 5.02k | return MCDisassembler_Success; \ |
321 | 5.02k | } SystemZDisassembler.c:decodePCDBLOperand_16 Line | Count | Source | 312 | 3.05k | { \ | 313 | 3.05k | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 3.05k | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 3.05k | \ | 316 | 3.05k | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 3.05k | N / 8, Inst, Decoder)) \ | 318 | 3.05k | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 3.05k | \ | 320 | 3.05k | return MCDisassembler_Success; \ | 321 | 3.05k | } |
SystemZDisassembler.c:decodePCDBLOperand_32 Line | Count | Source | 312 | 982 | { \ | 313 | 982 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 982 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 982 | \ | 316 | 982 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 982 | N / 8, Inst, Decoder)) \ | 318 | 982 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 982 | \ | 320 | 982 | return MCDisassembler_Success; \ | 321 | 982 | } |
SystemZDisassembler.c:decodePCDBLOperand_12 Line | Count | Source | 312 | 494 | { \ | 313 | 494 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 494 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 494 | \ | 316 | 494 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 494 | N / 8, Inst, Decoder)) \ | 318 | 494 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 494 | \ | 320 | 494 | return MCDisassembler_Success; \ | 321 | 494 | } |
SystemZDisassembler.c:decodePCDBLOperand_24 Line | Count | Source | 312 | 494 | { \ | 313 | 494 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 494 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 494 | \ | 316 | 494 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 494 | N / 8, Inst, Decoder)) \ | 318 | 494 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 494 | \ | 320 | 494 | return MCDisassembler_Success; \ | 321 | 494 | } |
|
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 | 783 | { |
331 | 783 | return CONCAT(decodePCDBLOperand, 12)(Inst, Imm, Address, true, |
332 | 783 | Decoder); |
333 | 783 | } |
334 | | |
335 | | static DecodeStatus decodePC16DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
336 | | uint64_t Address, |
337 | | const void *Decoder) |
338 | 6.74k | { |
339 | 6.74k | return CONCAT(decodePCDBLOperand, 16)(Inst, Imm, Address, true, |
340 | 6.74k | Decoder); |
341 | 6.74k | } |
342 | | |
343 | | static DecodeStatus decodePC24DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
344 | | uint64_t Address, |
345 | | const void *Decoder) |
346 | 783 | { |
347 | 783 | return CONCAT(decodePCDBLOperand, 24)(Inst, Imm, Address, true, |
348 | 783 | Decoder); |
349 | 783 | } |
350 | | |
351 | | static DecodeStatus decodePC32DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
352 | | uint64_t Address, |
353 | | const void *Decoder) |
354 | 480 | { |
355 | 480 | return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, true, |
356 | 480 | Decoder); |
357 | 480 | } |
358 | | |
359 | | static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm, |
360 | | uint64_t Address, const void *Decoder) |
361 | 1.84k | { |
362 | 1.84k | return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, false, |
363 | 1.84k | Decoder); |
364 | 1.84k | } |
365 | | |
366 | | #include "SystemZGenDisassemblerTables.inc" |
367 | | |
368 | | static DecodeStatus getInstruction(MCInst *MI, uint16_t *Size, |
369 | | const uint8_t *Bytes, size_t BytesLen, |
370 | | uint64_t Address, SStream *CS) |
371 | 133k | { |
372 | | // Get the first two bytes of the instruction. |
373 | 133k | *Size = 0; |
374 | 133k | if (BytesLen < 2) |
375 | 650 | return MCDisassembler_Fail; |
376 | | |
377 | | // The top 2 bits of the first byte specify the size. |
378 | 133k | const uint8_t *Table; |
379 | 133k | uint64_t Inst = 0; |
380 | 133k | if (Bytes[0] < 0x40) { |
381 | 33.2k | *Size = 2; |
382 | 33.2k | Table = DecoderTable16; |
383 | 33.2k | Inst = readBytes16(MI, Bytes); |
384 | 100k | } else if (Bytes[0] < 0xc0) { |
385 | 42.2k | if (BytesLen < 4) { |
386 | 280 | return MCDisassembler_Fail; |
387 | 280 | } |
388 | 41.9k | *Size = 4; |
389 | 41.9k | Table = DecoderTable32; |
390 | 41.9k | Inst = readBytes32(MI, Bytes); |
391 | 57.8k | } else { |
392 | 57.8k | if (BytesLen < 6) { |
393 | 354 | return MCDisassembler_Fail; |
394 | 354 | } |
395 | 57.5k | *Size = 6; |
396 | 57.5k | Table = DecoderTable48; |
397 | 57.5k | Inst = readBytes48(MI, Bytes); |
398 | 57.5k | } |
399 | | |
400 | | // Read any remaining bytes. |
401 | 132k | if (BytesLen < *Size) { |
402 | 0 | *Size = BytesLen; |
403 | 0 | return MCDisassembler_Fail; |
404 | 0 | } |
405 | | |
406 | 132k | return decodeInstruction_8(Table, MI, Inst, Address, NULL); |
407 | 132k | } |
408 | | |
409 | | DecodeStatus SystemZ_LLVM_getInstruction(csh handle, const uint8_t *Bytes, |
410 | | size_t BytesLen, MCInst *MI, |
411 | | uint16_t *Size, uint64_t Address, |
412 | | void *Info) |
413 | 133k | { |
414 | 133k | return getInstruction(MI, Size, Bytes, BytesLen, MI->address, NULL); |
415 | 133k | } |