/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 | 143k | #define CONCAT(a, b) CONCAT_(a, b) |
40 | 143k | #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 | 4.15k | { |
72 | | // return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, |
73 | | // Offset, Width, /*InstSize=*/0); |
74 | 4.15k | return false; |
75 | 4.15k | } |
76 | | |
77 | | static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, |
78 | | const unsigned *Regs, unsigned Size, |
79 | | bool IsAddr) |
80 | 279k | { |
81 | 279k | CS_ASSERT((RegNo < Size && "Invalid register")); |
82 | 279k | if (IsAddr && RegNo == 0) { |
83 | 30.1k | RegNo = SystemZ_NoRegister; |
84 | 249k | } else { |
85 | 249k | RegNo = Regs[RegNo]; |
86 | 249k | if (RegNo == 0) |
87 | 171 | return MCDisassembler_Fail; |
88 | 249k | } |
89 | 279k | MCOperand_CreateReg0(Inst, (RegNo)); |
90 | 279k | return MCDisassembler_Success; |
91 | 279k | } |
92 | | |
93 | | static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
94 | | uint64_t Address, |
95 | | const void *Decoder) |
96 | 92.7k | { |
97 | 92.7k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, false); |
98 | 92.7k | } |
99 | | |
100 | | static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
101 | | uint64_t Address, |
102 | | const void *Decoder) |
103 | 11.0k | { |
104 | 11.0k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs, 16, false); |
105 | 11.0k | } |
106 | | |
107 | | static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
108 | | uint64_t Address, |
109 | | const void *Decoder) |
110 | 58.8k | { |
111 | 58.8k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, false); |
112 | 58.8k | } |
113 | | |
114 | | static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
115 | | uint64_t Address, |
116 | | const void *Decoder) |
117 | 23.3k | { |
118 | 23.3k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs, 16, false); |
119 | 23.3k | } |
120 | | |
121 | | static DecodeStatus DecodeADDR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
122 | | uint64_t Address, |
123 | | const void *Decoder) |
124 | 3.97k | { |
125 | 3.97k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, true); |
126 | 3.97k | } |
127 | | |
128 | | static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
129 | | uint64_t Address, |
130 | | const void *Decoder) |
131 | 97.2k | { |
132 | 97.2k | return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, true); |
133 | 97.2k | } |
134 | | |
135 | | static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
136 | | uint64_t Address, |
137 | | const void *Decoder) |
138 | 39.1k | { |
139 | 39.1k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs, 16, false); |
140 | 39.1k | } |
141 | | |
142 | | static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
143 | | uint64_t Address, |
144 | | const void *Decoder) |
145 | 49.6k | { |
146 | 49.6k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs, 16, false); |
147 | 49.6k | } |
148 | | |
149 | | static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
150 | | uint64_t Address, |
151 | | const void *Decoder) |
152 | 9.34k | { |
153 | 9.34k | return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs, 16, false); |
154 | 9.34k | } |
155 | | |
156 | | static DecodeStatus DecodeVR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
157 | | uint64_t Address, |
158 | | const void *Decoder) |
159 | 3.62k | { |
160 | 3.62k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR32Regs, 32, false); |
161 | 3.62k | } |
162 | | |
163 | | static DecodeStatus DecodeVR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
164 | | uint64_t Address, |
165 | | const void *Decoder) |
166 | 2.67k | { |
167 | 2.67k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR64Regs, 32, false); |
168 | 2.67k | } |
169 | | |
170 | | static DecodeStatus DecodeVR128BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
171 | | uint64_t Address, |
172 | | const void *Decoder) |
173 | 35.0k | { |
174 | 35.0k | return decodeRegisterClass(Inst, RegNo, SystemZMC_VR128Regs, 32, false); |
175 | 35.0k | } |
176 | | |
177 | | static DecodeStatus DecodeAR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
178 | | uint64_t Address, |
179 | | const void *Decoder) |
180 | 3.42k | { |
181 | 3.42k | return decodeRegisterClass(Inst, RegNo, SystemZMC_AR32Regs, 16, false); |
182 | 3.42k | } |
183 | | |
184 | | static DecodeStatus DecodeCR64BitRegisterClass(MCInst *Inst, uint64_t RegNo, |
185 | | uint64_t Address, |
186 | | const void *Decoder) |
187 | 1.26k | { |
188 | 1.26k | return decodeRegisterClass(Inst, RegNo, SystemZMC_CR64Regs, 16, false); |
189 | 1.26k | } |
190 | | |
191 | | #define DEFINE_decodeUImmOperand(N) \ |
192 | | static DecodeStatus CONCAT(decodeUImmOperand, N)(MCInst * Inst, \ |
193 | | uint64_t Imm) \ |
194 | 85.5k | { \ |
195 | 85.5k | if (!isUIntN(N, Imm)) \ |
196 | 85.5k | return MCDisassembler_Fail; \ |
197 | 85.5k | MCOperand_CreateImm0(Inst, (Imm)); \ |
198 | 85.5k | return MCDisassembler_Success; \ |
199 | 85.5k | } SystemZDisassembler.c:decodeUImmOperand_4 Line | Count | Source | 194 | 19.2k | { \ | 195 | 19.2k | if (!isUIntN(N, Imm)) \ | 196 | 19.2k | return MCDisassembler_Fail; \ | 197 | 19.2k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 19.2k | return MCDisassembler_Success; \ | 199 | 19.2k | } |
SystemZDisassembler.c:decodeUImmOperand_8 Line | Count | Source | 194 | 5.19k | { \ | 195 | 5.19k | if (!isUIntN(N, Imm)) \ | 196 | 5.19k | return MCDisassembler_Fail; \ | 197 | 5.19k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 5.19k | return MCDisassembler_Success; \ | 199 | 5.19k | } |
SystemZDisassembler.c:decodeUImmOperand_12 Line | Count | Source | 194 | 55.5k | { \ | 195 | 55.5k | if (!isUIntN(N, Imm)) \ | 196 | 55.5k | return MCDisassembler_Fail; \ | 197 | 55.5k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 55.5k | return MCDisassembler_Success; \ | 199 | 55.5k | } |
SystemZDisassembler.c:decodeUImmOperand_16 Line | Count | Source | 194 | 1.53k | { \ | 195 | 1.53k | if (!isUIntN(N, Imm)) \ | 196 | 1.53k | return MCDisassembler_Fail; \ | 197 | 1.53k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 1.53k | return MCDisassembler_Success; \ | 199 | 1.53k | } |
SystemZDisassembler.c:decodeUImmOperand_32 Line | Count | Source | 194 | 883 | { \ | 195 | 883 | if (!isUIntN(N, Imm)) \ | 196 | 883 | return MCDisassembler_Fail; \ | 197 | 883 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 883 | return MCDisassembler_Success; \ | 199 | 883 | } |
SystemZDisassembler.c:decodeUImmOperand_3 Line | Count | Source | 194 | 759 | { \ | 195 | 759 | if (!isUIntN(N, Imm)) \ | 196 | 759 | return MCDisassembler_Fail; \ | 197 | 759 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 755 | return MCDisassembler_Success; \ | 199 | 759 | } |
SystemZDisassembler.c:decodeUImmOperand_1 Line | Count | Source | 194 | 939 | { \ | 195 | 939 | if (!isUIntN(N, Imm)) \ | 196 | 939 | return MCDisassembler_Fail; \ | 197 | 939 | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 932 | return MCDisassembler_Success; \ | 199 | 939 | } |
SystemZDisassembler.c:decodeUImmOperand_2 Line | Count | Source | 194 | 1.41k | { \ | 195 | 1.41k | if (!isUIntN(N, Imm)) \ | 196 | 1.41k | return MCDisassembler_Fail; \ | 197 | 1.41k | MCOperand_CreateImm0(Inst, (Imm)); \ | 198 | 1.40k | return MCDisassembler_Success; \ | 199 | 1.41k | } |
|
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 | 12.8k | { \ |
213 | 12.8k | if (!isUIntN(N, Imm)) \ |
214 | 12.8k | return MCDisassembler_Fail; \ |
215 | 12.8k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ |
216 | 12.8k | return MCDisassembler_Success; \ |
217 | 12.8k | } SystemZDisassembler.c:decodeSImmOperand_16 Line | Count | Source | 212 | 2.25k | { \ | 213 | 2.25k | if (!isUIntN(N, Imm)) \ | 214 | 2.25k | return MCDisassembler_Fail; \ | 215 | 2.25k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 2.25k | return MCDisassembler_Success; \ | 217 | 2.25k | } |
SystemZDisassembler.c:decodeSImmOperand_32 Line | Count | Source | 212 | 619 | { \ | 213 | 619 | if (!isUIntN(N, Imm)) \ | 214 | 619 | return MCDisassembler_Fail; \ | 215 | 619 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 619 | return MCDisassembler_Success; \ | 217 | 619 | } |
SystemZDisassembler.c:decodeSImmOperand_20 Line | Count | Source | 212 | 9.01k | { \ | 213 | 9.01k | if (!isUIntN(N, Imm)) \ | 214 | 9.01k | return MCDisassembler_Fail; \ | 215 | 9.01k | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 9.01k | return MCDisassembler_Success; \ | 217 | 9.01k | } |
SystemZDisassembler.c:decodeSImmOperand_8 Line | Count | Source | 212 | 981 | { \ | 213 | 981 | if (!isUIntN(N, Imm)) \ | 214 | 981 | return MCDisassembler_Fail; \ | 215 | 981 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \ | 216 | 981 | return MCDisassembler_Success; \ | 217 | 981 | } |
|
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 | 1.34k | { |
226 | 1.34k | return CONCAT(decodeUImmOperand, 1)(Inst, Imm); |
227 | 1.34k | } |
228 | | |
229 | | static DecodeStatus decodeU2ImmOperand(MCInst *Inst, uint64_t Imm, |
230 | | uint64_t Address, const void *Decoder) |
231 | 2.06k | { |
232 | 2.06k | return CONCAT(decodeUImmOperand, 2)(Inst, Imm); |
233 | 2.06k | } |
234 | | |
235 | | static DecodeStatus decodeU3ImmOperand(MCInst *Inst, uint64_t Imm, |
236 | | uint64_t Address, const void *Decoder) |
237 | 861 | { |
238 | 861 | return CONCAT(decodeUImmOperand, 3)(Inst, Imm); |
239 | 861 | } |
240 | | |
241 | | static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm, |
242 | | uint64_t Address, const void *Decoder) |
243 | 38.4k | { |
244 | 38.4k | return CONCAT(decodeUImmOperand, 4)(Inst, Imm); |
245 | 38.4k | } |
246 | | |
247 | | static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm, |
248 | | uint64_t Address, const void *Decoder) |
249 | 11.3k | { |
250 | 11.3k | return CONCAT(decodeUImmOperand, 8)(Inst, Imm); |
251 | 11.3k | } |
252 | | |
253 | | static DecodeStatus decodeU12ImmOperand(MCInst *Inst, uint64_t Imm, |
254 | | uint64_t Address, const void *Decoder) |
255 | 55.7k | { |
256 | 55.7k | return CONCAT(decodeUImmOperand, 12)(Inst, Imm); |
257 | 55.7k | } |
258 | | |
259 | | static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm, |
260 | | uint64_t Address, const void *Decoder) |
261 | 3.83k | { |
262 | 3.83k | return CONCAT(decodeUImmOperand, 16)(Inst, Imm); |
263 | 3.83k | } |
264 | | |
265 | | static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm, |
266 | | uint64_t Address, const void *Decoder) |
267 | 1.89k | { |
268 | 1.89k | return CONCAT(decodeUImmOperand, 32)(Inst, Imm); |
269 | 1.89k | } |
270 | | |
271 | | static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm, |
272 | | uint64_t Address, const void *Decoder) |
273 | 2.74k | { |
274 | 2.74k | return CONCAT(decodeSImmOperand, 8)(Inst, Imm); |
275 | 2.74k | } |
276 | | |
277 | | static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm, |
278 | | uint64_t Address, const void *Decoder) |
279 | 5.69k | { |
280 | 5.69k | return CONCAT(decodeSImmOperand, 16)(Inst, Imm); |
281 | 5.69k | } |
282 | | |
283 | | static DecodeStatus decodeS20ImmOperand(MCInst *Inst, uint64_t Imm, |
284 | | uint64_t Address, const void *Decoder) |
285 | 9.01k | { |
286 | 9.01k | return CONCAT(decodeSImmOperand, 20)(Inst, Imm); |
287 | 9.01k | } |
288 | | |
289 | | static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm, |
290 | | uint64_t Address, const void *Decoder) |
291 | 1.82k | { |
292 | 1.82k | return CONCAT(decodeSImmOperand, 32)(Inst, Imm); |
293 | 1.82k | } |
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 | 8.19k | { \ |
300 | 8.19k | if (!isUIntN(N, Imm)) \ |
301 | 8.19k | return MCDisassembler_Fail; \ |
302 | 8.19k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ |
303 | 8.19k | return MCDisassembler_Success; \ |
304 | 8.19k | } SystemZDisassembler.c:decodeLenOperand_8 Line | Count | Source | 299 | 3.25k | { \ | 300 | 3.25k | if (!isUIntN(N, Imm)) \ | 301 | 3.25k | return MCDisassembler_Fail; \ | 302 | 3.25k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ | 303 | 3.25k | return MCDisassembler_Success; \ | 304 | 3.25k | } |
SystemZDisassembler.c:decodeLenOperand_4 Line | Count | Source | 299 | 4.94k | { \ | 300 | 4.94k | if (!isUIntN(N, Imm)) \ | 301 | 4.94k | return MCDisassembler_Fail; \ | 302 | 4.94k | MCOperand_CreateImm0(Inst, (Imm + 1)); \ | 303 | 4.94k | return MCDisassembler_Success; \ | 304 | 4.94k | } |
|
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 | 4.15k | { \ |
313 | 4.15k | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ |
314 | 4.15k | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ |
315 | 4.15k | \ |
316 | 4.15k | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ |
317 | 4.15k | N / 8, Inst, Decoder)) \ |
318 | 4.15k | MCOperand_CreateImm0(Inst, (Value)); \ |
319 | 4.15k | \ |
320 | 4.15k | return MCDisassembler_Success; \ |
321 | 4.15k | } SystemZDisassembler.c:decodePCDBLOperand_16 Line | Count | Source | 312 | 2.57k | { \ | 313 | 2.57k | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 2.57k | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 2.57k | \ | 316 | 2.57k | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 2.57k | N / 8, Inst, Decoder)) \ | 318 | 2.57k | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 2.57k | \ | 320 | 2.57k | return MCDisassembler_Success; \ | 321 | 2.57k | } |
SystemZDisassembler.c:decodePCDBLOperand_32 Line | Count | Source | 312 | 958 | { \ | 313 | 958 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 958 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 958 | \ | 316 | 958 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 958 | N / 8, Inst, Decoder)) \ | 318 | 958 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 958 | \ | 320 | 958 | return MCDisassembler_Success; \ | 321 | 958 | } |
SystemZDisassembler.c:decodePCDBLOperand_12 Line | Count | Source | 312 | 312 | { \ | 313 | 312 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 312 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 312 | \ | 316 | 312 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 312 | N / 8, Inst, Decoder)) \ | 318 | 312 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 312 | \ | 320 | 312 | return MCDisassembler_Success; \ | 321 | 312 | } |
SystemZDisassembler.c:decodePCDBLOperand_24 Line | Count | Source | 312 | 312 | { \ | 313 | 312 | CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \ | 314 | 312 | uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \ | 315 | 312 | \ | 316 | 312 | if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \ | 317 | 312 | N / 8, Inst, Decoder)) \ | 318 | 312 | MCOperand_CreateImm0(Inst, (Value)); \ | 319 | 312 | \ | 320 | 312 | return MCDisassembler_Success; \ | 321 | 312 | } |
|
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 | 602 | { |
331 | 602 | return CONCAT(decodePCDBLOperand, 12)(Inst, Imm, Address, true, |
332 | 602 | Decoder); |
333 | 602 | } |
334 | | |
335 | | static DecodeStatus decodePC16DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
336 | | uint64_t Address, |
337 | | const void *Decoder) |
338 | 6.49k | { |
339 | 6.49k | return CONCAT(decodePCDBLOperand, 16)(Inst, Imm, Address, true, |
340 | 6.49k | Decoder); |
341 | 6.49k | } |
342 | | |
343 | | static DecodeStatus decodePC24DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
344 | | uint64_t Address, |
345 | | const void *Decoder) |
346 | 602 | { |
347 | 602 | return CONCAT(decodePCDBLOperand, 24)(Inst, Imm, Address, true, |
348 | 602 | Decoder); |
349 | 602 | } |
350 | | |
351 | | static DecodeStatus decodePC32DBLBranchOperand(MCInst *Inst, uint64_t Imm, |
352 | | uint64_t Address, |
353 | | const void *Decoder) |
354 | 437 | { |
355 | 437 | return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, true, |
356 | 437 | Decoder); |
357 | 437 | } |
358 | | |
359 | | static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm, |
360 | | uint64_t Address, const void *Decoder) |
361 | 1.12k | { |
362 | 1.12k | return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, false, |
363 | 1.12k | Decoder); |
364 | 1.12k | } |
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 | 110k | { |
371 | | // Get the first two bytes of the instruction. |
372 | 110k | *Size = 0; |
373 | 110k | if (BytesLen < 2) |
374 | 608 | return MCDisassembler_Fail; |
375 | | |
376 | | // The top 2 bits of the first byte specify the size. |
377 | 109k | const uint8_t *Table; |
378 | 109k | uint64_t Inst = 0; |
379 | 109k | if (Bytes[0] < 0x40) { |
380 | 32.5k | *Size = 2; |
381 | 32.5k | Table = DecoderTable16; |
382 | 32.5k | Inst = readBytes16(MI, Bytes); |
383 | 77.0k | } else if (Bytes[0] < 0xc0) { |
384 | 36.5k | if (BytesLen < 4) { |
385 | 244 | return MCDisassembler_Fail; |
386 | 244 | } |
387 | 36.3k | *Size = 4; |
388 | 36.3k | Table = DecoderTable32; |
389 | 36.3k | Inst = readBytes32(MI, Bytes); |
390 | 40.4k | } else { |
391 | 40.4k | if (BytesLen < 6) { |
392 | 283 | return MCDisassembler_Fail; |
393 | 283 | } |
394 | 40.1k | *Size = 6; |
395 | 40.1k | Table = DecoderTable48; |
396 | 40.1k | Inst = readBytes48(MI, Bytes); |
397 | 40.1k | } |
398 | | |
399 | | // Read any remaining bytes. |
400 | 109k | if (BytesLen < *Size) { |
401 | 0 | *Size = BytesLen; |
402 | 0 | return MCDisassembler_Fail; |
403 | 0 | } |
404 | | |
405 | 109k | return decodeInstruction_8(Table, MI, Inst, Address, NULL); |
406 | 109k | } |
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 | 110k | { |
413 | 110k | return getInstruction(MI, Size, Bytes, BytesLen, MI->address, NULL); |
414 | 110k | } |