/src/capstonenext/arch/Xtensa/XtensaInstPrinter.c
Line | Count | Source |
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 | | //===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===// |
16 | | // |
17 | | // The LLVM Compiler Infrastructure |
18 | | // |
19 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
20 | | // See https://llvm.org/LICENSE.txt for license information. |
21 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
22 | | // |
23 | | //===----------------------------------------------------------------------===// |
24 | | // |
25 | | // This class prints an Xtensa MCInst to a .s file. |
26 | | // |
27 | | //===----------------------------------------------------------------------===// |
28 | | |
29 | | #include <stdio.h> |
30 | | #include <string.h> |
31 | | #include <stdlib.h> |
32 | | #include <capstone/platform.h> |
33 | | |
34 | | #include "../../MCInstPrinter.h" |
35 | | #include "../../SStream.h" |
36 | | #include "./priv.h" |
37 | | #include "../../Mapping.h" |
38 | | |
39 | | #include "XtensaMapping.h" |
40 | | #include "../../MathExtras.h" |
41 | | |
42 | | #define CONCAT(a, b) CONCAT_(a, b) |
43 | | #define CONCAT_(a, b) a##_##b |
44 | | |
45 | | #define DEBUG_TYPE "asm-printer" |
46 | | static MnemonicBitsInfo getMnemonic(MCInst *MI, SStream *O); |
47 | | static const char *getRegisterName(unsigned RegNo); |
48 | | |
49 | | typedef MCRegister Register; |
50 | | |
51 | | static void printRegName(SStream *O, MCRegister Reg) |
52 | 74 | { |
53 | 74 | SStream_concat0(O, getRegisterName(Reg)); |
54 | 74 | } |
55 | | |
56 | | static void printOp(MCInst *MI, MCOperand *MC, SStream *O) |
57 | 190k | { |
58 | 190k | if (MCOperand_isReg(MC)) |
59 | 180k | SStream_concat0(O, getRegisterName(MCOperand_getReg(MC))); |
60 | 9.74k | else if (MCOperand_isImm(MC)) |
61 | 9.74k | printInt64(O, MCOperand_getImm(MC)); |
62 | 0 | else if (MCOperand_isExpr(MC)) |
63 | 0 | printExpr(MCOperand_getExpr(MC), O); |
64 | 0 | else |
65 | 0 | CS_ASSERT(0 && "Invalid operand"); |
66 | 190k | } |
67 | | |
68 | | static void printOperand(MCInst *MI, const int op_num, SStream *O) |
69 | 180k | { |
70 | 180k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Operand, op_num); |
71 | 180k | printOp(MI, MCInst_getOperand(MI, op_num), O); |
72 | 180k | } |
73 | | |
74 | | static inline void printMemOperand(MCInst *MI, int OpNum, SStream *OS) |
75 | 9.74k | { |
76 | 9.74k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_MemOperand, OpNum); |
77 | 9.74k | SStream_concat0(OS, getRegisterName(MCOperand_getReg( |
78 | 9.74k | MCInst_getOperand(MI, (OpNum))))); |
79 | 9.74k | SStream_concat0(OS, ", "); |
80 | 9.74k | printOp(MI, MCInst_getOperand(MI, OpNum + 1), OS); |
81 | 9.74k | } |
82 | | |
83 | | static inline void printBranchTarget(MCInst *MI, int OpNum, SStream *OS) |
84 | 16.7k | { |
85 | 16.7k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_BranchTarget, OpNum); |
86 | 16.7k | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); |
87 | 16.7k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
88 | 16.7k | int64_t Val = MCOperand_getImm(MC) + 4; |
89 | 16.7k | SStream_concat0(OS, ". "); |
90 | 16.7k | if (Val > 0) |
91 | 8.38k | SStream_concat0(OS, "+"); |
92 | | |
93 | 16.7k | printInt64(OS, Val); |
94 | 16.7k | } else if (MCOperand_isExpr(MC)) |
95 | 0 | CS_ASSERT_RET(0 && "unimplemented expr printing"); |
96 | 0 | else |
97 | 0 | CS_ASSERT(0 && "Invalid operand"); |
98 | 16.7k | } |
99 | | |
100 | | static inline void printLoopTarget(MCInst *MI, int OpNum, SStream *OS) |
101 | 68 | { |
102 | 68 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_LoopTarget, OpNum); |
103 | 68 | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); |
104 | 68 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
105 | 68 | int64_t Val = MCOperand_getImm(MC) + 4; |
106 | 68 | SStream_concat0(OS, ". "); |
107 | 68 | if (Val > 0) |
108 | 68 | SStream_concat0(OS, "+"); |
109 | | |
110 | 68 | printInt64(OS, Val); |
111 | 68 | } else if (MCOperand_isExpr(MC)) |
112 | 0 | CS_ASSERT_RET(0 && "unimplemented expr printing"); |
113 | 0 | else |
114 | 0 | CS_ASSERT(0 && "Invalid operand"); |
115 | 68 | } |
116 | | |
117 | | static inline void printJumpTarget(MCInst *MI, int OpNum, SStream *OS) |
118 | 1.38k | { |
119 | 1.38k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_JumpTarget, OpNum); |
120 | 1.38k | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); |
121 | 1.38k | if (MCOperand_isImm(MC)) { |
122 | 1.38k | int64_t Val = MCOperand_getImm(MC) + 4; |
123 | 1.38k | SStream_concat0(OS, ". "); |
124 | 1.38k | if (Val > 0) |
125 | 821 | SStream_concat0(OS, "+"); |
126 | | |
127 | 1.38k | printInt64(OS, Val); |
128 | 1.38k | } else if (MCOperand_isExpr(MC)) |
129 | 0 | CS_ASSERT_RET(0 && "unimplemented expr printing"); |
130 | 0 | else |
131 | 0 | CS_ASSERT(0 && "Invalid operand"); |
132 | 1.38k | ; |
133 | 1.38k | } |
134 | | |
135 | | static inline void printCallOperand(MCInst *MI, int OpNum, SStream *OS) |
136 | 3.42k | { |
137 | 3.42k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_CallOperand, OpNum); |
138 | 3.42k | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); |
139 | 3.42k | if (MCOperand_isImm(MC)) { |
140 | 3.42k | int64_t Val = MCOperand_getImm(MC) + 4; |
141 | 3.42k | SStream_concat0(OS, ". "); |
142 | 3.42k | if (Val > 0) |
143 | 2.17k | SStream_concat0(OS, "+"); |
144 | | |
145 | 3.42k | printInt64(OS, Val); |
146 | 3.42k | } else if (MCOperand_isExpr(MC)) |
147 | 0 | CS_ASSERT_RET(0 && "unimplemented expr printing"); |
148 | 0 | else |
149 | 0 | CS_ASSERT(0 && "Invalid operand"); |
150 | 3.42k | } |
151 | | |
152 | | static inline void printL32RTarget(MCInst *MI, int OpNum, SStream *O) |
153 | 5.62k | { |
154 | 5.62k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_L32RTarget, OpNum); |
155 | 5.62k | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); |
156 | 5.62k | if (MCOperand_isImm(MC)) { |
157 | 5.62k | SStream_concat0(O, ". "); |
158 | 5.62k | printInt64(O, Xtensa_L32R_Value(MI, OpNum)); |
159 | 5.62k | } else if (MCOperand_isExpr(MC)) |
160 | 0 | CS_ASSERT_RET(0 && "unimplemented expr printing"); |
161 | 0 | else |
162 | 0 | CS_ASSERT(0 && "Invalid operand"); |
163 | 5.62k | } |
164 | | |
165 | | static inline void printImm8_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
166 | 425 | { |
167 | 425 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm8_AsmOperand, OpNum); |
168 | 425 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
169 | 425 | int64_t Value = |
170 | 425 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
171 | 425 | CS_ASSERT_RET( |
172 | 425 | isIntN(8, Value) && |
173 | 425 | "Invalid argument, value must be in ranges [-128,127]"); |
174 | 425 | printInt64(O, Value); |
175 | 425 | } else { |
176 | 0 | printOperand(MI, OpNum, O); |
177 | 0 | } |
178 | 425 | } |
179 | | |
180 | | static inline void printImm8_sh8_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
181 | 379 | { |
182 | 379 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm8_sh8_AsmOperand, OpNum); |
183 | 379 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
184 | 379 | int64_t Value = |
185 | 379 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
186 | 379 | CS_ASSERT_RET( |
187 | 379 | (isIntN(16, Value) && ((Value & 0xFF) == 0)) && |
188 | 379 | "Invalid argument, value must be multiples of 256 in range " |
189 | 379 | "[-32768,32512]"); |
190 | 379 | printInt64(O, Value); |
191 | 379 | } else |
192 | 0 | printOperand(MI, OpNum, O); |
193 | 379 | } |
194 | | |
195 | | static inline void printImm12_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
196 | 0 | { |
197 | 0 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm12_AsmOperand, OpNum); |
198 | 0 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
199 | 0 | int64_t Value = |
200 | 0 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
201 | 0 | CS_ASSERT_RET( |
202 | 0 | (Value >= -2048 && Value <= 2047) && |
203 | 0 | "Invalid argument, value must be in ranges [-2048,2047]"); |
204 | 0 | printInt64(O, Value); |
205 | 0 | } else |
206 | 0 | printOperand(MI, OpNum, O); |
207 | 0 | } |
208 | | |
209 | | static inline void printImm12m_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
210 | 344 | { |
211 | 344 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm12m_AsmOperand, OpNum); |
212 | 344 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
213 | 344 | int64_t Value = |
214 | 344 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
215 | 344 | CS_ASSERT_RET( |
216 | 344 | (Value >= -2048 && Value <= 2047) && |
217 | 344 | "Invalid argument, value must be in ranges [-2048,2047]"); |
218 | 344 | printInt64(O, Value); |
219 | 344 | } else |
220 | 0 | printOperand(MI, OpNum, O); |
221 | 344 | } |
222 | | |
223 | | static inline void printUimm4_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
224 | 2.65k | { |
225 | 2.65k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Uimm4_AsmOperand, OpNum); |
226 | 2.65k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
227 | 2.65k | int64_t Value = |
228 | 2.65k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
229 | 2.65k | CS_ASSERT_RET((Value >= 0 && Value <= 15) && |
230 | 2.65k | "Invalid argument"); |
231 | 2.65k | printInt64(O, Value); |
232 | 2.65k | } else |
233 | 0 | printOperand(MI, OpNum, O); |
234 | 2.65k | } |
235 | | |
236 | | static inline void printUimm5_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
237 | 3.40k | { |
238 | 3.40k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Uimm5_AsmOperand, OpNum); |
239 | 3.40k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
240 | 3.40k | int64_t Value = |
241 | 3.40k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
242 | 3.40k | CS_ASSERT_RET((Value >= 0 && Value <= 31) && |
243 | 3.40k | "Invalid argument"); |
244 | 3.40k | printInt64(O, Value); |
245 | 3.40k | } else |
246 | 0 | printOperand(MI, OpNum, O); |
247 | 3.40k | } |
248 | | |
249 | | static inline void printShimm1_31_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
250 | 0 | { |
251 | 0 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Shimm1_31_AsmOperand, OpNum); |
252 | 0 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
253 | 0 | int64_t Value = |
254 | 0 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
255 | 0 | CS_ASSERT_RET( |
256 | 0 | (Value >= 1 && Value <= 31) && |
257 | 0 | "Invalid argument, value must be in range [1,31]"); |
258 | 0 | printInt64(O, Value); |
259 | 0 | } else |
260 | 0 | printOperand(MI, OpNum, O); |
261 | 0 | } |
262 | | |
263 | | static inline void printShimm0_31_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
264 | 350 | { |
265 | 350 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Shimm0_31_AsmOperand, OpNum); |
266 | 350 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
267 | 350 | int64_t Value = |
268 | 350 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
269 | 350 | CS_ASSERT_RET( |
270 | 350 | (Value >= 0 && Value <= 31) && |
271 | 350 | "Invalid argument, value must be in range [0,31]"); |
272 | 223 | printInt64(O, Value); |
273 | 223 | } else |
274 | 0 | printOperand(MI, OpNum, O); |
275 | 350 | } |
276 | | |
277 | | static inline void printImm1_16_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
278 | 1.15k | { |
279 | 1.15k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm1_16_AsmOperand, OpNum); |
280 | 1.15k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
281 | 1.15k | int64_t Value = |
282 | 1.15k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
283 | 1.15k | CS_ASSERT_RET( |
284 | 1.15k | (Value >= 1 && Value <= 16) && |
285 | 1.15k | "Invalid argument, value must be in range [1,16]"); |
286 | 1.15k | printInt64(O, Value); |
287 | 1.15k | } else |
288 | 0 | printOperand(MI, OpNum, O); |
289 | 1.15k | } |
290 | | |
291 | | static inline void printImm1n_15_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
292 | 4.66k | { |
293 | 4.66k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm1n_15_AsmOperand, OpNum); |
294 | 4.66k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
295 | 4.66k | int64_t Value = |
296 | 4.66k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
297 | 4.66k | CS_ASSERT_RET( |
298 | 4.66k | (Value >= -1 && (Value != 0) && Value <= 15) && |
299 | 4.66k | "Invalid argument, value must be in ranges <-1,-1> or <1,15>"); |
300 | 4.66k | printInt64(O, Value); |
301 | 4.66k | } else |
302 | 0 | printOperand(MI, OpNum, O); |
303 | 4.66k | } |
304 | | |
305 | | static inline void printImm32n_95_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
306 | 1.68k | { |
307 | 1.68k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm32n_95_AsmOperand, OpNum); |
308 | 1.68k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
309 | 1.68k | int64_t Value = |
310 | 1.68k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
311 | 1.68k | CS_ASSERT_RET( |
312 | 1.68k | (Value >= -32 && Value <= 95) && |
313 | 1.68k | "Invalid argument, value must be in ranges <-32,95>"); |
314 | 1.68k | printInt64(O, Value); |
315 | 1.68k | } else |
316 | 0 | printOperand(MI, OpNum, O); |
317 | 1.68k | } |
318 | | |
319 | | static inline void printImm8n_7_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
320 | 235 | { |
321 | 235 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm8n_7_AsmOperand, OpNum); |
322 | 235 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
323 | 235 | int64_t Value = |
324 | 235 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
325 | 235 | CS_ASSERT_RET( |
326 | 235 | (Value >= -8 && Value <= 7) && |
327 | 235 | "Invalid argument, value must be in ranges <-8,7>"); |
328 | 235 | printInt64(O, Value); |
329 | 235 | } else |
330 | 0 | printOperand(MI, OpNum, O); |
331 | 235 | } |
332 | | |
333 | | static inline void printImm64n_4n_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
334 | 81 | { |
335 | 81 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm64n_4n_AsmOperand, OpNum); |
336 | 81 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
337 | 81 | int64_t Value = |
338 | 81 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
339 | 81 | CS_ASSERT_RET( |
340 | 81 | (Value >= -64 && Value <= -4) & ((Value & 0x3) == 0) && |
341 | 81 | "Invalid argument, value must be in ranges <-64,-4>"); |
342 | 81 | printInt64(O, Value); |
343 | 81 | } else |
344 | 0 | printOperand(MI, OpNum, O); |
345 | 81 | } |
346 | | |
347 | | static inline void printOffset8m32_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
348 | 1.06k | { |
349 | 1.06k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset8m32_AsmOperand, |
350 | 1.06k | OpNum); |
351 | 1.06k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
352 | 1.06k | int64_t Value = |
353 | 1.06k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
354 | 1.06k | CS_ASSERT_RET( |
355 | 1.06k | (Value >= 0 && Value <= 1020 && ((Value & 0x3) == 0)) && |
356 | 1.06k | "Invalid argument, value must be multiples of four in range [0,1020]"); |
357 | 1.06k | printInt64(O, Value); |
358 | 1.06k | } else |
359 | 0 | printOperand(MI, OpNum, O); |
360 | 1.06k | } |
361 | | |
362 | | static inline void printEntry_Imm12_AsmOperand(MCInst *MI, int OpNum, |
363 | | SStream *O) |
364 | 313 | { |
365 | 313 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Entry_Imm12_AsmOperand, |
366 | 313 | OpNum); |
367 | 313 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
368 | 313 | int64_t Value = |
369 | 313 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
370 | 313 | CS_ASSERT_RET( |
371 | 313 | (Value >= 0 && Value <= 32760) && |
372 | 313 | "Invalid argument, value must be multiples of eight in range " |
373 | 313 | "<0,32760>"); |
374 | 313 | printInt64(O, Value); |
375 | 313 | } else |
376 | 0 | printOperand(MI, OpNum, O); |
377 | 313 | } |
378 | | |
379 | | static inline void printB4const_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
380 | 4.85k | { |
381 | 4.85k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_B4const_AsmOperand, OpNum); |
382 | 4.85k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
383 | 4.85k | int64_t Value = |
384 | 4.85k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
385 | | |
386 | 4.85k | switch (Value) { |
387 | 278 | case -1: |
388 | 587 | case 1: |
389 | 871 | case 2: |
390 | 947 | case 3: |
391 | 1.23k | case 4: |
392 | 1.37k | case 5: |
393 | 1.74k | case 6: |
394 | 2.01k | case 7: |
395 | 2.29k | case 8: |
396 | 2.65k | case 10: |
397 | 3.40k | case 12: |
398 | 3.84k | case 16: |
399 | 4.05k | case 32: |
400 | 4.25k | case 64: |
401 | 4.51k | case 128: |
402 | 4.85k | case 256: |
403 | 4.85k | break; |
404 | 0 | default: |
405 | 0 | CS_ASSERT_RET((0) && "Invalid B4const argument"); |
406 | 4.85k | } |
407 | 4.85k | printInt64(O, Value); |
408 | 4.85k | } else |
409 | 0 | printOperand(MI, OpNum, O); |
410 | 4.85k | } |
411 | | |
412 | | static inline void printB4constu_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
413 | 4.15k | { |
414 | 4.15k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_B4constu_AsmOperand, OpNum); |
415 | 4.15k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
416 | 4.15k | int64_t Value = |
417 | 4.15k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
418 | | |
419 | 4.15k | switch (Value) { |
420 | 437 | case 32768: |
421 | 690 | case 65536: |
422 | 803 | case 2: |
423 | 893 | case 3: |
424 | 990 | case 4: |
425 | 1.54k | case 5: |
426 | 1.89k | case 6: |
427 | 1.99k | case 7: |
428 | 2.07k | case 8: |
429 | 2.18k | case 10: |
430 | 2.26k | case 12: |
431 | 2.89k | case 16: |
432 | 3.11k | case 32: |
433 | 3.31k | case 64: |
434 | 3.40k | case 128: |
435 | 4.15k | case 256: |
436 | 4.15k | break; |
437 | 0 | default: |
438 | 0 | CS_ASSERT_RET((0) && "Invalid B4constu argument"); |
439 | 4.15k | } |
440 | 4.15k | printInt64(O, Value); |
441 | 4.15k | } else |
442 | 0 | printOperand(MI, OpNum, O); |
443 | 4.15k | } |
444 | | |
445 | | static inline void printImm7_22_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
446 | 355 | { |
447 | 355 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Imm7_22_AsmOperand, OpNum); |
448 | 355 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
449 | 355 | int64_t Value = |
450 | 355 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
451 | 355 | CS_ASSERT_RET( |
452 | 355 | (Value >= 7 && Value <= 22) && |
453 | 355 | "Invalid argument, value must be in range <7,22>"); |
454 | 355 | printInt64(O, Value); |
455 | 355 | } else |
456 | 0 | printOperand(MI, OpNum, O); |
457 | 355 | } |
458 | | |
459 | | static inline void printSelect_2_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
460 | 1.17k | { |
461 | 1.17k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Select_2_AsmOperand, OpNum); |
462 | 1.17k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
463 | 1.17k | int64_t Value = |
464 | 1.17k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
465 | 1.17k | CS_ASSERT_RET((Value >= 0 && Value <= 1) && |
466 | 1.17k | "Invalid argument, value must be in range [0,1]"); |
467 | 1.17k | printInt64(O, Value); |
468 | 1.17k | } else |
469 | 0 | printOperand(MI, OpNum, O); |
470 | 1.17k | } |
471 | | |
472 | | static inline void printSelect_4_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
473 | 2.25k | { |
474 | 2.25k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Select_4_AsmOperand, OpNum); |
475 | 2.25k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
476 | 2.25k | int64_t Value = |
477 | 2.25k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
478 | 2.25k | CS_ASSERT_RET((Value >= 0 && Value <= 3) && |
479 | 2.25k | "Invalid argument, value must be in range [0,3]"); |
480 | 2.25k | printInt64(O, Value); |
481 | 2.25k | } else |
482 | 0 | printOperand(MI, OpNum, O); |
483 | 2.25k | } |
484 | | |
485 | | static inline void printSelect_8_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
486 | 1.11k | { |
487 | 1.11k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Select_8_AsmOperand, OpNum); |
488 | 1.11k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
489 | 1.11k | int64_t Value = |
490 | 1.11k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
491 | 1.11k | CS_ASSERT_RET((Value >= 0 && Value <= 7) && |
492 | 1.11k | "Invalid argument, value must be in range [0,7]"); |
493 | 1.11k | printInt64(O, Value); |
494 | 1.11k | } else |
495 | 0 | printOperand(MI, OpNum, O); |
496 | 1.11k | } |
497 | | |
498 | | static inline void printSelect_16_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
499 | 419 | { |
500 | 419 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Select_16_AsmOperand, OpNum); |
501 | 419 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
502 | 419 | int64_t Value = |
503 | 419 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
504 | 419 | CS_ASSERT_RET( |
505 | 419 | (Value >= 0 && Value <= 15) && |
506 | 419 | "Invalid argument, value must be in range [0,15]"); |
507 | 419 | printInt64(O, Value); |
508 | 419 | } else |
509 | 0 | printOperand(MI, OpNum, O); |
510 | 419 | } |
511 | | |
512 | | static inline void printSelect_256_AsmOperand(MCInst *MI, int OpNum, SStream *O) |
513 | 282 | { |
514 | 282 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Select_256_AsmOperand, |
515 | 282 | OpNum); |
516 | 282 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
517 | 282 | int64_t Value = |
518 | 282 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
519 | 282 | CS_ASSERT_RET( |
520 | 282 | (Value >= 0 && Value <= 255) && |
521 | 282 | "Invalid argument, value must be in range [0,255]"); |
522 | 282 | printInt64(O, Value); |
523 | 282 | } else |
524 | 0 | printOperand(MI, OpNum, O); |
525 | 282 | } |
526 | | |
527 | | static inline void printOffset_16_16_AsmOperand(MCInst *MI, int OpNum, |
528 | | SStream *O) |
529 | 710 | { |
530 | 710 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset_16_16_AsmOperand, |
531 | 710 | OpNum); |
532 | 710 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
533 | 710 | int64_t Value = |
534 | 710 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
535 | 710 | CS_ASSERT_RET( |
536 | 710 | (Value >= -128 && Value <= 112 && (Value & 0xf) == 0) && |
537 | 710 | "Invalid argument, value must be in range [-128,112], first 4 bits " |
538 | 710 | "should be zero"); |
539 | 270 | printInt64(O, Value); |
540 | 270 | } else { |
541 | 0 | printOperand(MI, OpNum, O); |
542 | 0 | } |
543 | 710 | } |
544 | | |
545 | | static inline void printOffset_256_8_AsmOperand(MCInst *MI, int OpNum, |
546 | | SStream *O) |
547 | 2.51k | { |
548 | 2.51k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset_256_8_AsmOperand, |
549 | 2.51k | OpNum); |
550 | 2.51k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
551 | 2.51k | int64_t Value = |
552 | 2.51k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
553 | 2.51k | CS_ASSERT_RET( |
554 | 2.51k | (Value >= -1024 && Value <= 1016 && |
555 | 2.51k | (Value & 0x7) == 0) && |
556 | 2.51k | "Invalid argument, value must be in range [-1024,1016], first 3 " |
557 | 2.51k | "bits should be zero"); |
558 | 1.05k | printInt64(O, Value); |
559 | 1.05k | } else |
560 | 0 | printOperand(MI, OpNum, O); |
561 | 2.51k | } |
562 | | |
563 | | static inline void printOffset_256_16_AsmOperand(MCInst *MI, int OpNum, |
564 | | SStream *O) |
565 | 1.48k | { |
566 | 1.48k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset_256_16_AsmOperand, |
567 | 1.48k | OpNum); |
568 | 1.48k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
569 | 1.48k | int64_t Value = |
570 | 1.48k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
571 | 1.48k | CS_ASSERT_RET( |
572 | 1.48k | (Value >= -2048 && Value <= 2032 && |
573 | 1.48k | (Value & 0xf) == 0) && |
574 | 1.48k | "Invalid argument, value must be in range [-2048,2032], first 4 " |
575 | 1.48k | "bits should be zero"); |
576 | 1.04k | printInt64(O, Value); |
577 | 1.04k | } else { |
578 | 0 | printOperand(MI, OpNum, O); |
579 | 0 | } |
580 | 1.48k | } |
581 | | |
582 | | static inline void printOffset_256_4_AsmOperand(MCInst *MI, int OpNum, |
583 | | SStream *O) |
584 | 701 | { |
585 | 701 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset_256_4_AsmOperand, |
586 | 701 | OpNum); |
587 | 701 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
588 | 701 | int64_t Value = |
589 | 701 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
590 | 701 | CS_ASSERT_RET( |
591 | 701 | (Value >= -512 && Value <= 508 && (Value & 0x3) == 0) && |
592 | 701 | "Invalid argument, value must be in range [-512,508], first 2 bits " |
593 | 701 | "should be zero"); |
594 | 382 | printInt64(O, Value); |
595 | 382 | } else |
596 | 0 | printOperand(MI, OpNum, O); |
597 | 701 | } |
598 | | |
599 | | static inline void printOffset_128_2_AsmOperand(MCInst *MI, int OpNum, |
600 | | SStream *O) |
601 | 750 | { |
602 | 750 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset_128_2_AsmOperand, |
603 | 750 | OpNum); |
604 | 750 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
605 | 750 | int64_t Value = |
606 | 750 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
607 | 750 | CS_ASSERT_RET( |
608 | 750 | (Value >= 0 && Value <= 254 && (Value & 0x1) == 0) && |
609 | 750 | "Invalid argument, value must be in range [0,254], first bit should " |
610 | 750 | "be zero"); |
611 | 750 | printInt64(O, Value); |
612 | 750 | } else |
613 | 0 | printOperand(MI, OpNum, O); |
614 | 750 | } |
615 | | |
616 | | static inline void printOffset_128_1_AsmOperand(MCInst *MI, int OpNum, |
617 | | SStream *O) |
618 | 208 | { |
619 | 208 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset_128_1_AsmOperand, |
620 | 208 | OpNum); |
621 | 208 | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
622 | 208 | int64_t Value = |
623 | 208 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
624 | 208 | CS_ASSERT_RET( |
625 | 208 | (Value >= 0 && Value <= 127) && |
626 | 208 | "Invalid argument, value must be in range [0,127]"); |
627 | 208 | printInt64(O, Value); |
628 | 208 | } else |
629 | 0 | printOperand(MI, OpNum, O); |
630 | 208 | } |
631 | | |
632 | | static inline void printOffset_64_16_AsmOperand(MCInst *MI, int OpNum, |
633 | | SStream *O) |
634 | 2.99k | { |
635 | 2.99k | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Offset_64_16_AsmOperand, |
636 | 2.99k | OpNum); |
637 | 2.99k | if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) { |
638 | 2.99k | int64_t Value = |
639 | 2.99k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
640 | 2.99k | CS_ASSERT_RET( |
641 | 2.99k | (Value >= -512 && Value <= 496 && (Value & 0xf) == 0) && |
642 | 2.99k | "Invalid argument, value must be in range [-512,496], first 4 bits " |
643 | 2.99k | "should be zero"); |
644 | 2.02k | printInt64(O, Value); |
645 | 2.02k | } else |
646 | 0 | printOperand(MI, OpNum, O); |
647 | 2.99k | } |
648 | | |
649 | | #define IMPL_printImmOperand(N, L, H, S) \ |
650 | | static void printImmOperand_##N(MCInst *MI, int OpNum, SStream *O) \ |
651 | 113 | { \ |
652 | 113 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_ImmOperand_##N, \ |
653 | 113 | OpNum); \ |
654 | 113 | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); \ |
655 | 113 | if (MCOperand_isImm(MC)) { \ |
656 | 113 | int64_t Value = MCOperand_getImm(MC); \ |
657 | 113 | CS_ASSERT_RET((Value >= L && Value <= H && \ |
658 | 113 | ((Value % S) == 0)) && \ |
659 | 113 | "Invalid argument"); \ |
660 | 113 | printInt64(O, Value); \ |
661 | 60 | } else { \ |
662 | 0 | printOperand(MI, OpNum, O); \ |
663 | 0 | } \ |
664 | 113 | } Unexecuted instantiation: XtensaInstPrinter.c:printImmOperand_minus16_47_1 Unexecuted instantiation: XtensaInstPrinter.c:printImmOperand_minus16_14_2 XtensaInstPrinter.c:printImmOperand_minus32_28_4 Line | Count | Source | 651 | 102 | { \ | 652 | 102 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_ImmOperand_##N, \ | 653 | 102 | OpNum); \ | 654 | 102 | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); \ | 655 | 102 | if (MCOperand_isImm(MC)) { \ | 656 | 102 | int64_t Value = MCOperand_getImm(MC); \ | 657 | 102 | CS_ASSERT_RET((Value >= L && Value <= H && \ | 658 | 102 | ((Value % S) == 0)) && \ | 659 | 102 | "Invalid argument"); \ | 660 | 102 | printInt64(O, Value); \ | 661 | 60 | } else { \ | 662 | 0 | printOperand(MI, OpNum, O); \ | 663 | 0 | } \ | 664 | 102 | } |
XtensaInstPrinter.c:printImmOperand_minus64_56_8 Line | Count | Source | 651 | 11 | { \ | 652 | 11 | Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_ImmOperand_##N, \ | 653 | 11 | OpNum); \ | 654 | 11 | MCOperand *MC = MCInst_getOperand(MI, (OpNum)); \ | 655 | 11 | if (MCOperand_isImm(MC)) { \ | 656 | 11 | int64_t Value = MCOperand_getImm(MC); \ | 657 | 11 | CS_ASSERT_RET((Value >= L && Value <= H && \ | 658 | 11 | ((Value % S) == 0)) && \ | 659 | 11 | "Invalid argument"); \ | 660 | 11 | printInt64(O, Value); \ | 661 | 0 | } else { \ | 662 | 0 | printOperand(MI, OpNum, O); \ | 663 | 0 | } \ | 664 | 11 | } |
Unexecuted instantiation: XtensaInstPrinter.c:printImmOperand_0_56_8 Unexecuted instantiation: XtensaInstPrinter.c:printImmOperand_0_3_1 Unexecuted instantiation: XtensaInstPrinter.c:printImmOperand_0_63_1 |
665 | | |
666 | | IMPL_printImmOperand(minus64_56_8, -64, 56, 8); |
667 | | IMPL_printImmOperand(minus32_28_4, -32, 28, 4); |
668 | | IMPL_printImmOperand(minus16_47_1, -16, 47, 1); |
669 | | IMPL_printImmOperand(minus16_14_2, -16, 14, 2); |
670 | | IMPL_printImmOperand(0_56_8, 0, 56, 8); |
671 | | IMPL_printImmOperand(0_3_1, 0, 3, 1); |
672 | | IMPL_printImmOperand(0_63_1, 0, 63, 1); |
673 | | |
674 | | #include "XtensaGenAsmWriter.inc" |
675 | | |
676 | | static void printInst(MCInst *MI, uint64_t Address, const char *Annot, |
677 | | SStream *O) |
678 | 94.4k | { |
679 | 94.4k | unsigned Opcode = MCInst_getOpcode(MI); |
680 | | |
681 | 94.4k | switch (Opcode) { |
682 | 333 | case Xtensa_WSR: { |
683 | | // INTERRUPT mnemonic is read-only, so use INTSET mnemonic instead |
684 | 333 | Register SR = MCOperand_getReg(MCInst_getOperand(MI, (0))); |
685 | 333 | if (SR == Xtensa_INTERRUPT) { |
686 | 74 | Register Reg = |
687 | 74 | MCOperand_getReg(MCInst_getOperand(MI, (1))); |
688 | 74 | SStream_concat1(O, '\t'); |
689 | 74 | SStream_concat(O, "%s", "wsr"); |
690 | 74 | SStream_concat0(O, "\t"); |
691 | | |
692 | 74 | printRegName(O, Reg); |
693 | 74 | SStream_concat(O, "%s", ", "); |
694 | 74 | SStream_concat0(O, "intset"); |
695 | 74 | ; |
696 | 74 | return; |
697 | 74 | } |
698 | 333 | } |
699 | 94.4k | } |
700 | 94.3k | printInstruction(MI, Address, O); |
701 | 94.3k | } |
702 | | |
703 | | void Xtensa_LLVM_printInstruction(MCInst *MI, uint64_t Address, SStream *O) |
704 | 94.4k | { |
705 | 94.4k | printInst(MI, Address, NULL, O); |
706 | 94.4k | } |
707 | | |
708 | | const char *Xtensa_LLVM_getRegisterName(unsigned RegNo) |
709 | 12.0k | { |
710 | 12.0k | return getRegisterName(RegNo); |
711 | 12.0k | } |