kvx-dis.c revision 1.1.1.3 1 1.1 christos /* kvx-dis.c -- Kalray MPPA generic disassembler.
2 1.1.1.3 christos Copyright (C) 2009-2026 Free Software Foundation, Inc.
3 1.1 christos Contributed by Kalray SA.
4 1.1 christos
5 1.1 christos This file is part of the GNU opcodes library.
6 1.1 christos
7 1.1 christos This library is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3, or (at your option)
10 1.1 christos any later version.
11 1.1 christos
12 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
13 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 1.1 christos License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; see the file COPYING3. If not,
19 1.1 christos see <http://www.gnu.org/licenses/>. */
20 1.1 christos
21 1.1 christos #define STATIC_TABLE
22 1.1 christos #define DEFINE_TABLE
23 1.1 christos
24 1.1 christos #include "sysdep.h"
25 1.1 christos #include "disassemble.h"
26 1.1 christos #include "libiberty.h"
27 1.1 christos #include "opintl.h"
28 1.1 christos #include <assert.h>
29 1.1 christos #include "elf-bfd.h"
30 1.1 christos #include "kvx-dis.h"
31 1.1 christos
32 1.1 christos #include "elf/kvx.h"
33 1.1 christos #include "opcode/kvx.h"
34 1.1 christos
35 1.1 christos /* Steering values for the kvx VLIW architecture. */
36 1.1 christos
37 1.1 christos typedef enum
38 1.1 christos {
39 1.1 christos Steering_BCU,
40 1.1 christos Steering_LSU,
41 1.1 christos Steering_MAU,
42 1.1 christos Steering_ALU,
43 1.1 christos Steering__
44 1.1 christos } enum_Steering;
45 1.1 christos typedef uint8_t Steering;
46 1.1 christos
47 1.1 christos /* BundleIssue enumeration. */
48 1.1 christos
49 1.1 christos typedef enum
50 1.1 christos {
51 1.1 christos BundleIssue_BCU,
52 1.1 christos BundleIssue_TCA,
53 1.1 christos BundleIssue_ALU0,
54 1.1 christos BundleIssue_ALU1,
55 1.1 christos BundleIssue_MAU,
56 1.1 christos BundleIssue_LSU,
57 1.1 christos BundleIssue__,
58 1.1 christos } enum_BundleIssue;
59 1.1 christos typedef uint8_t BundleIssue;
60 1.1 christos
61 1.1 christos /* An IMMX syllable is associated with the BundleIssue Extension_BundleIssue[extension]. */
62 1.1 christos static const BundleIssue Extension_BundleIssue[] = {
63 1.1 christos BundleIssue_ALU0,
64 1.1 christos BundleIssue_ALU1,
65 1.1 christos BundleIssue_MAU,
66 1.1 christos BundleIssue_LSU
67 1.1 christos };
68 1.1 christos
69 1.1 christos static inline int
70 1.1 christos kvx_steering (uint32_t x)
71 1.1 christos {
72 1.1 christos return (((x) & 0x60000000) >> 29);
73 1.1 christos }
74 1.1 christos
75 1.1 christos static inline int
76 1.1 christos kvx_extension (uint32_t x)
77 1.1 christos {
78 1.1 christos return (((x) & 0x18000000) >> 27);
79 1.1 christos }
80 1.1 christos
81 1.1 christos static inline int
82 1.1 christos kvx_has_parallel_bit (uint32_t x)
83 1.1 christos {
84 1.1 christos return (((x) & 0x80000000) == 0x80000000);
85 1.1 christos }
86 1.1 christos
87 1.1 christos static inline int
88 1.1 christos kvx_is_tca_opcode (uint32_t x)
89 1.1 christos {
90 1.1 christos unsigned major = ((x) >> 24) & 0x1F;
91 1.1 christos return (major > 1) && (major < 8);
92 1.1 christos }
93 1.1 christos
94 1.1 christos static inline int
95 1.1 christos kvx_is_nop_opcode (uint32_t x)
96 1.1 christos {
97 1.1 christos return ((x) << 1) == 0xFFFFFFFE;
98 1.1 christos }
99 1.1 christos
100 1.1 christos /* A raw instruction. */
101 1.1 christos
102 1.1 christos struct insn_s
103 1.1 christos {
104 1.1 christos uint32_t syllables[KVXMAXSYLLABLES];
105 1.1 christos int len;
106 1.1 christos };
107 1.1 christos typedef struct insn_s insn_t;
108 1.1 christos
109 1.1 christos
110 1.1 christos static uint32_t bundle_words[KVXMAXBUNDLEWORDS];
111 1.1 christos
112 1.1 christos static insn_t bundle_insn[KVXMAXBUNDLEISSUE];
113 1.1 christos
114 1.1 christos /* A re-interpreted instruction. */
115 1.1 christos
116 1.1 christos struct instr_s
117 1.1 christos {
118 1.1 christos int valid;
119 1.1 christos int opcode;
120 1.1 christos int immx[2];
121 1.1 christos int immx_valid[2];
122 1.1 christos int immx_count;
123 1.1 christos int nb_syllables;
124 1.1 christos };
125 1.1 christos
126 1.1 christos /* Option for "pretty printing", ie, not the usual little endian objdump output. */
127 1.1 christos static int opt_pretty = 0;
128 1.1 christos /* Option for not emiting a new line between all bundles. */
129 1.1 christos static int opt_compact_assembly = 0;
130 1.1 christos
131 1.1 christos void
132 1.1 christos parse_kvx_dis_option (const char *option)
133 1.1 christos {
134 1.1 christos /* Try to match options that are simple flags. */
135 1.1 christos if (startswith (option, "pretty"))
136 1.1 christos {
137 1.1 christos opt_pretty = 1;
138 1.1 christos return;
139 1.1 christos }
140 1.1 christos
141 1.1 christos if (startswith (option, "compact-assembly"))
142 1.1 christos {
143 1.1 christos opt_compact_assembly = 1;
144 1.1 christos return;
145 1.1 christos }
146 1.1 christos
147 1.1 christos if (startswith (option, "no-compact-assembly"))
148 1.1 christos {
149 1.1 christos opt_compact_assembly = 0;
150 1.1 christos return;
151 1.1 christos }
152 1.1 christos
153 1.1 christos /* Invalid option. */
154 1.1 christos opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
155 1.1 christos }
156 1.1 christos
157 1.1 christos static void
158 1.1 christos parse_kvx_dis_options (const char *options)
159 1.1 christos {
160 1.1 christos const char *option_end;
161 1.1 christos
162 1.1 christos if (options == NULL)
163 1.1 christos return;
164 1.1 christos
165 1.1 christos while (*options != '\0')
166 1.1 christos {
167 1.1 christos /* Skip empty options. */
168 1.1 christos if (*options == ',')
169 1.1 christos {
170 1.1 christos options++;
171 1.1 christos continue;
172 1.1 christos }
173 1.1 christos
174 1.1 christos /* We know that *options is neither NUL or a comma. */
175 1.1 christos option_end = options + 1;
176 1.1 christos while (*option_end != ',' && *option_end != '\0')
177 1.1 christos option_end++;
178 1.1 christos
179 1.1 christos parse_kvx_dis_option (options);
180 1.1 christos
181 1.1 christos /* Go on to the next one. If option_end points to a comma, it
182 1.1 christos will be skipped above. */
183 1.1 christos options = option_end;
184 1.1 christos }
185 1.1 christos }
186 1.1 christos
187 1.1 christos struct kvx_dis_env
188 1.1 christos {
189 1.1 christos int kvx_arch_size;
190 1.1 christos struct kvxopc *opc_table;
191 1.1 christos struct kvx_Register *kvx_registers;
192 1.1 christos const char ***kvx_modifiers;
193 1.1 christos int *kvx_dec_registers;
194 1.1 christos int *kvx_regfiles;
195 1.1 christos unsigned int kvx_max_dec_registers;
196 1.1 christos int initialized_p;
197 1.1 christos };
198 1.1 christos
199 1.1 christos static struct kvx_dis_env env = {
200 1.1 christos .kvx_arch_size = 0,
201 1.1 christos .opc_table = NULL,
202 1.1 christos .kvx_registers = NULL,
203 1.1 christos .kvx_modifiers = NULL,
204 1.1 christos .kvx_dec_registers = NULL,
205 1.1 christos .kvx_regfiles = NULL,
206 1.1 christos .initialized_p = 0,
207 1.1 christos .kvx_max_dec_registers = 0
208 1.1 christos };
209 1.1 christos
210 1.1 christos static void
211 1.1 christos kvx_dis_init (struct disassemble_info *info)
212 1.1 christos {
213 1.1 christos env.kvx_arch_size = 32;
214 1.1 christos switch (info->mach)
215 1.1 christos {
216 1.1 christos case bfd_mach_kv3_1_64:
217 1.1 christos env.kvx_arch_size = 64;
218 1.1 christos /* fallthrough */
219 1.1 christos case bfd_mach_kv3_1_usr:
220 1.1 christos case bfd_mach_kv3_1:
221 1.1 christos default:
222 1.1 christos env.opc_table = kvx_kv3_v1_optab;
223 1.1 christos env.kvx_regfiles = kvx_kv3_v1_regfiles;
224 1.1 christos env.kvx_registers = kvx_kv3_v1_registers;
225 1.1 christos env.kvx_modifiers = kvx_kv3_v1_modifiers;
226 1.1 christos env.kvx_dec_registers = kvx_kv3_v1_dec_registers;
227 1.1 christos break;
228 1.1 christos case bfd_mach_kv3_2_64:
229 1.1 christos env.kvx_arch_size = 64;
230 1.1 christos /* fallthrough */
231 1.1 christos case bfd_mach_kv3_2_usr:
232 1.1 christos case bfd_mach_kv3_2:
233 1.1 christos env.opc_table = kvx_kv3_v2_optab;
234 1.1 christos env.kvx_regfiles = kvx_kv3_v2_regfiles;
235 1.1 christos env.kvx_registers = kvx_kv3_v2_registers;
236 1.1 christos env.kvx_modifiers = kvx_kv3_v2_modifiers;
237 1.1 christos env.kvx_dec_registers = kvx_kv3_v2_dec_registers;
238 1.1 christos break;
239 1.1 christos case bfd_mach_kv4_1_64:
240 1.1 christos env.kvx_arch_size = 64;
241 1.1 christos /* fallthrough */
242 1.1 christos case bfd_mach_kv4_1_usr:
243 1.1 christos case bfd_mach_kv4_1:
244 1.1 christos env.opc_table = kvx_kv4_v1_optab;
245 1.1 christos env.kvx_regfiles = kvx_kv4_v1_regfiles;
246 1.1 christos env.kvx_registers = kvx_kv4_v1_registers;
247 1.1 christos env.kvx_modifiers = kvx_kv4_v1_modifiers;
248 1.1 christos env.kvx_dec_registers = kvx_kv4_v1_dec_registers;
249 1.1 christos break;
250 1.1 christos }
251 1.1 christos
252 1.1 christos env.kvx_max_dec_registers = env.kvx_regfiles[KVX_REGFILE_DEC_REGISTERS];
253 1.1 christos
254 1.1 christos if (info->disassembler_options)
255 1.1 christos parse_kvx_dis_options (info->disassembler_options);
256 1.1 christos
257 1.1 christos env.initialized_p = 1;
258 1.1 christos }
259 1.1 christos
260 1.1 christos static bool
261 1.1 christos kvx_reassemble_bundle (int wordcount, int *_insncount)
262 1.1 christos {
263 1.1 christos
264 1.1 christos /* Debugging flag. */
265 1.1 christos int debug = 0;
266 1.1 christos
267 1.1 christos /* Available resources. */
268 1.1 christos int bcu_taken = 0;
269 1.1 christos int tca_taken = 0;
270 1.1 christos int alu0_taken = 0;
271 1.1 christos int alu1_taken = 0;
272 1.1 christos int mau_taken = 0;
273 1.1 christos int lsu_taken = 0;
274 1.1 christos
275 1.1 christos if (debug)
276 1.1 christos fprintf (stderr, "kvx_reassemble_bundle: wordcount = %d\n", wordcount);
277 1.1 christos
278 1.1 christos if (wordcount > KVXMAXBUNDLEWORDS)
279 1.1 christos {
280 1.1 christos if (debug)
281 1.1 christos fprintf (stderr, "bundle exceeds maximum size\n");
282 1.1 christos return false;
283 1.1 christos }
284 1.1 christos
285 1.1 christos struct instr_s instr[KVXMAXBUNDLEISSUE];
286 1.1 christos memset (instr, 0, sizeof (instr));
287 1.1 christos assert (KVXMAXBUNDLEISSUE >= BundleIssue__);
288 1.1 christos
289 1.1 christos int i;
290 1.1 christos unsigned int j;
291 1.1 christos
292 1.1 christos for (i = 0; i < wordcount; i++)
293 1.1 christos {
294 1.1 christos uint32_t syllable = bundle_words[i];
295 1.1 christos switch (kvx_steering (syllable))
296 1.1 christos {
297 1.1 christos case Steering_BCU:
298 1.1 christos /* BCU or TCA instruction. */
299 1.1 christos if (i == 0)
300 1.1 christos {
301 1.1 christos if (kvx_is_tca_opcode (syllable))
302 1.1 christos {
303 1.1 christos if (tca_taken)
304 1.1 christos {
305 1.1 christos if (debug)
306 1.1 christos fprintf (stderr, "Too many TCA instructions");
307 1.1 christos return false;
308 1.1 christos }
309 1.1 christos if (debug)
310 1.1 christos fprintf (stderr,
311 1.1 christos "Syllable 0: Set valid on TCA for instr %d with 0x%x\n",
312 1.1 christos BundleIssue_TCA, syllable);
313 1.1 christos instr[BundleIssue_TCA].valid = 1;
314 1.1 christos instr[BundleIssue_TCA].opcode = syllable;
315 1.1 christos instr[BundleIssue_TCA].nb_syllables = 1;
316 1.1 christos tca_taken = 1;
317 1.1 christos }
318 1.1 christos else
319 1.1 christos {
320 1.1 christos if (debug)
321 1.1 christos fprintf (stderr,
322 1.1 christos "Syllable 0: Set valid on BCU for instr %d with 0x%x\n",
323 1.1 christos BundleIssue_BCU, syllable);
324 1.1 christos
325 1.1 christos instr[BundleIssue_BCU].valid = 1;
326 1.1 christos instr[BundleIssue_BCU].opcode = syllable;
327 1.1 christos instr[BundleIssue_BCU].nb_syllables = 1;
328 1.1 christos bcu_taken = 1;
329 1.1 christos }
330 1.1 christos }
331 1.1 christos else
332 1.1 christos {
333 1.1 christos if (i == 1 && bcu_taken && kvx_is_tca_opcode (syllable))
334 1.1 christos {
335 1.1 christos if (tca_taken)
336 1.1 christos {
337 1.1 christos if (debug)
338 1.1 christos fprintf (stderr, "Too many TCA instructions");
339 1.1 christos return false;
340 1.1 christos }
341 1.1 christos if (debug)
342 1.1 christos fprintf (stderr,
343 1.1 christos "Syllable 0: Set valid on TCA for instr %d with 0x%x\n",
344 1.1 christos BundleIssue_TCA, syllable);
345 1.1 christos instr[BundleIssue_TCA].valid = 1;
346 1.1 christos instr[BundleIssue_TCA].opcode = syllable;
347 1.1 christos instr[BundleIssue_TCA].nb_syllables = 1;
348 1.1 christos tca_taken = 1;
349 1.1 christos }
350 1.1 christos else
351 1.1 christos {
352 1.1 christos /* Not first syllable in bundle, IMMX. */
353 1.1 christos struct instr_s *instr_p =
354 1.1 christos &(instr[Extension_BundleIssue[kvx_extension (syllable)]]);
355 1.1 christos int immx_count = instr_p->immx_count;
356 1.1 christos if (immx_count > 1)
357 1.1 christos {
358 1.1 christos if (debug)
359 1.1 christos fprintf (stderr, "Too many IMMX syllables");
360 1.1 christos return false;
361 1.1 christos }
362 1.1 christos instr_p->immx[immx_count] = syllable;
363 1.1 christos instr_p->immx_valid[immx_count] = 1;
364 1.1 christos instr_p->nb_syllables++;
365 1.1 christos if (debug)
366 1.1 christos fprintf (stderr,
367 1.1 christos "Set IMMX[%d] on instr %d for extension %d @ %d\n",
368 1.1 christos immx_count,
369 1.1 christos Extension_BundleIssue[kvx_extension (syllable)],
370 1.1 christos kvx_extension (syllable), i);
371 1.1 christos instr_p->immx_count = immx_count + 1;
372 1.1 christos }
373 1.1 christos }
374 1.1 christos break;
375 1.1 christos
376 1.1 christos case Steering_ALU:
377 1.1 christos if (alu0_taken == 0)
378 1.1 christos {
379 1.1 christos if (debug)
380 1.1 christos fprintf (stderr, "Set valid on ALU0 for instr %d with 0x%x\n",
381 1.1 christos BundleIssue_ALU0, syllable);
382 1.1 christos instr[BundleIssue_ALU0].valid = 1;
383 1.1 christos instr[BundleIssue_ALU0].opcode = syllable;
384 1.1 christos instr[BundleIssue_ALU0].nb_syllables = 1;
385 1.1 christos alu0_taken = 1;
386 1.1 christos }
387 1.1 christos else if (alu1_taken == 0)
388 1.1 christos {
389 1.1 christos if (debug)
390 1.1 christos fprintf (stderr, "Set valid on ALU1 for instr %d with 0x%x\n",
391 1.1 christos BundleIssue_ALU1, syllable);
392 1.1 christos instr[BundleIssue_ALU1].valid = 1;
393 1.1 christos instr[BundleIssue_ALU1].opcode = syllable;
394 1.1 christos instr[BundleIssue_ALU1].nb_syllables = 1;
395 1.1 christos alu1_taken = 1;
396 1.1 christos }
397 1.1 christos else if (mau_taken == 0)
398 1.1 christos {
399 1.1 christos if (debug)
400 1.1 christos fprintf (stderr,
401 1.1 christos "Set valid on MAU (ALU) for instr %d with 0x%x\n",
402 1.1 christos BundleIssue_MAU, syllable);
403 1.1 christos instr[BundleIssue_MAU].valid = 1;
404 1.1 christos instr[BundleIssue_MAU].opcode = syllable;
405 1.1 christos instr[BundleIssue_MAU].nb_syllables = 1;
406 1.1 christos mau_taken = 1;
407 1.1 christos }
408 1.1 christos else if (lsu_taken == 0)
409 1.1 christos {
410 1.1 christos if (debug)
411 1.1 christos fprintf (stderr,
412 1.1 christos "Set valid on LSU (ALU) for instr %d with 0x%x\n",
413 1.1 christos BundleIssue_LSU, syllable);
414 1.1 christos instr[BundleIssue_LSU].valid = 1;
415 1.1 christos instr[BundleIssue_LSU].opcode = syllable;
416 1.1 christos instr[BundleIssue_LSU].nb_syllables = 1;
417 1.1 christos lsu_taken = 1;
418 1.1 christos }
419 1.1 christos else if (kvx_is_nop_opcode (syllable))
420 1.1 christos {
421 1.1 christos if (debug)
422 1.1 christos fprintf (stderr, "Ignoring NOP (ALU) syllable\n");
423 1.1 christos }
424 1.1 christos else
425 1.1 christos {
426 1.1 christos if (debug)
427 1.1 christos fprintf (stderr, "Too many ALU instructions");
428 1.1 christos return false;
429 1.1 christos }
430 1.1 christos break;
431 1.1 christos
432 1.1 christos case Steering_MAU:
433 1.1 christos if (mau_taken == 1)
434 1.1 christos {
435 1.1 christos if (debug)
436 1.1 christos fprintf (stderr, "Too many MAU instructions");
437 1.1 christos return false;
438 1.1 christos }
439 1.1 christos else
440 1.1 christos {
441 1.1 christos if (debug)
442 1.1 christos fprintf (stderr, "Set valid on MAU for instr %d with 0x%x\n",
443 1.1 christos BundleIssue_MAU, syllable);
444 1.1 christos instr[BundleIssue_MAU].valid = 1;
445 1.1 christos instr[BundleIssue_MAU].opcode = syllable;
446 1.1 christos instr[BundleIssue_MAU].nb_syllables = 1;
447 1.1 christos mau_taken = 1;
448 1.1 christos }
449 1.1 christos break;
450 1.1 christos
451 1.1 christos case Steering_LSU:
452 1.1 christos if (lsu_taken == 1)
453 1.1 christos {
454 1.1 christos if (debug)
455 1.1 christos fprintf (stderr, "Too many LSU instructions");
456 1.1 christos return false;
457 1.1 christos }
458 1.1 christos else
459 1.1 christos {
460 1.1 christos if (debug)
461 1.1 christos fprintf (stderr, "Set valid on LSU for instr %d with 0x%x\n",
462 1.1 christos BundleIssue_LSU, syllable);
463 1.1 christos instr[BundleIssue_LSU].valid = 1;
464 1.1 christos instr[BundleIssue_LSU].opcode = syllable;
465 1.1 christos instr[BundleIssue_LSU].nb_syllables = 1;
466 1.1 christos lsu_taken = 1;
467 1.1 christos }
468 1.1 christos }
469 1.1 christos if (debug)
470 1.1 christos fprintf (stderr, "Continue %d < %d?\n", i, wordcount);
471 1.1 christos }
472 1.1 christos
473 1.1 christos /* Fill bundle_insn and count read syllables. */
474 1.1 christos int instr_idx = 0;
475 1.1 christos for (i = 0; i < KVXMAXBUNDLEISSUE; i++)
476 1.1 christos {
477 1.1 christos if (instr[i].valid == 1)
478 1.1 christos {
479 1.1 christos int syllable_idx = 0;
480 1.1 christos
481 1.1 christos /* First copy opcode. */
482 1.1 christos bundle_insn[instr_idx].syllables[syllable_idx++] = instr[i].opcode;
483 1.1 christos bundle_insn[instr_idx].len = 1;
484 1.1 christos
485 1.1 christos for (j = 0; j < 2; j++)
486 1.1 christos {
487 1.1 christos if (instr[i].immx_valid[j])
488 1.1 christos {
489 1.1 christos if (debug)
490 1.1 christos fprintf (stderr, "Instr %d valid immx[%d] is valid\n", i,
491 1.1 christos j);
492 1.1 christos bundle_insn[instr_idx].syllables[syllable_idx++] =
493 1.1 christos instr[i].immx[j];
494 1.1 christos bundle_insn[instr_idx].len++;
495 1.1 christos }
496 1.1 christos }
497 1.1 christos
498 1.1 christos if (debug)
499 1.1 christos fprintf (stderr,
500 1.1 christos "Instr %d valid, copying in bundle_insn (%d syllables <-> %d)\n",
501 1.1 christos i, bundle_insn[instr_idx].len, instr[i].nb_syllables);
502 1.1 christos instr_idx++;
503 1.1 christos }
504 1.1 christos }
505 1.1 christos
506 1.1 christos if (debug)
507 1.1 christos fprintf (stderr, "End => %d instructions\n", instr_idx);
508 1.1 christos
509 1.1 christos *_insncount = instr_idx;
510 1.1 christos return true;
511 1.1 christos }
512 1.1 christos
513 1.1 christos struct decoded_insn
514 1.1 christos {
515 1.1 christos /* The entry in the opc_table. */
516 1.1 christos struct kvxopc *opc;
517 1.1 christos /* The number of operands. */
518 1.1 christos int nb_ops;
519 1.1 christos /* The content of an operands. */
520 1.1 christos struct
521 1.1 christos {
522 1.1 christos enum
523 1.1 christos {
524 1.1 christos CAT_REGISTER,
525 1.1 christos CAT_MODIFIER,
526 1.1 christos CAT_IMMEDIATE,
527 1.1 christos } type;
528 1.1 christos /* The value of the operands. */
529 1.1 christos uint64_t val;
530 1.1 christos /* If it is an immediate, its sign. */
531 1.1 christos int sign;
532 1.1 christos /* If it is an immediate, is it pc relative. */
533 1.1 christos int pcrel;
534 1.1 christos /* The width of the operand. */
535 1.1 christos int width;
536 1.1 christos /* If it is a modifier, the modifier category.
537 1.1 christos An index in the modifier table. */
538 1.1 christos int mod_idx;
539 1.1 christos } operands[KVXMAXOPERANDS];
540 1.1 christos };
541 1.1 christos
542 1.1 christos static int
543 1.1 christos decode_insn (bfd_vma memaddr, insn_t * insn, struct decoded_insn *res)
544 1.1 christos {
545 1.1 christos
546 1.1 christos int found = 0;
547 1.1 christos int idx = 0;
548 1.1 christos for (struct kvxopc * op = env.opc_table;
549 1.1 christos op->as_op && (((char) op->as_op[0]) != 0); op++)
550 1.1 christos {
551 1.1 christos /* Find the format of this insn. */
552 1.1 christos int opcode_match = 1;
553 1.1 christos
554 1.1 christos if (op->wordcount != insn->len)
555 1.1 christos continue;
556 1.1 christos
557 1.1 christos for (int i = 0; i < op->wordcount; i++)
558 1.1 christos if ((op->codewords[i].mask & insn->syllables[i]) !=
559 1.1 christos op->codewords[i].opcode)
560 1.1 christos opcode_match = 0;
561 1.1 christos
562 1.1 christos int encoding_space_flags = env.kvx_arch_size == 32
563 1.1 christos ? kvxOPCODE_FLAG_MODE32 : kvxOPCODE_FLAG_MODE64;
564 1.1 christos
565 1.1 christos for (int i = 0; i < op->wordcount; i++)
566 1.1 christos if (!(op->codewords[i].flags & encoding_space_flags))
567 1.1 christos opcode_match = 0;
568 1.1 christos
569 1.1 christos if (opcode_match)
570 1.1 christos {
571 1.1 christos res->opc = op;
572 1.1 christos
573 1.1 christos for (int i = 0; op->format[i]; i++)
574 1.1 christos {
575 1.1 christos struct kvx_bitfield *bf = op->format[i]->bfield;
576 1.1 christos int bf_nb = op->format[i]->bitfields;
577 1.1 christos int width = op->format[i]->width;
578 1.1 christos int type = op->format[i]->type;
579 1.1 christos const char *type_name = op->format[i]->tname;
580 1.1 christos int flags = op->format[i]->flags;
581 1.1 christos int shift = op->format[i]->shift;
582 1.1 christos int bias = op->format[i]->bias;
583 1.1 christos uint64_t value = 0;
584 1.1 christos
585 1.1 christos for (int bf_idx = 0; bf_idx < bf_nb; bf_idx++)
586 1.1 christos {
587 1.1 christos int insn_idx = (int) bf[bf_idx].to_offset / 32;
588 1.1 christos int to_offset = bf[bf_idx].to_offset % 32;
589 1.1 christos uint64_t encoded_value =
590 1.1 christos insn->syllables[insn_idx] >> to_offset;
591 1.1 christos encoded_value &= (1LL << bf[bf_idx].size) - 1;
592 1.1 christos value |= encoded_value << bf[bf_idx].from_offset;
593 1.1 christos }
594 1.1 christos if (flags & kvxSIGNED)
595 1.1 christos {
596 1.1 christos uint64_t signbit = 1LL << (width - 1);
597 1.1 christos value = (value ^ signbit) - signbit;
598 1.1 christos }
599 1.1 christos value = (value << shift) + bias;
600 1.1 christos
601 1.1 christos #define KVX_PRINT_REG(regfile,value) \
602 1.1 christos if(env.kvx_regfiles[regfile]+value < env.kvx_max_dec_registers) { \
603 1.1 christos res->operands[idx].val = env.kvx_dec_registers[env.kvx_regfiles[regfile]+value]; \
604 1.1 christos res->operands[idx].type = CAT_REGISTER; \
605 1.1 christos idx++; \
606 1.1 christos } else { \
607 1.1 christos res->operands[idx].val = ~0; \
608 1.1 christos res->operands[idx].type = CAT_REGISTER; \
609 1.1 christos idx++; \
610 1.1 christos }
611 1.1 christos
612 1.1 christos if (env.opc_table == kvx_kv3_v1_optab)
613 1.1 christos {
614 1.1 christos switch (type)
615 1.1 christos {
616 1.1 christos case RegClass_kv3_v1_singleReg:
617 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value)
618 1.1 christos break;
619 1.1 christos case RegClass_kv3_v1_pairedReg:
620 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value)
621 1.1 christos break;
622 1.1 christos case RegClass_kv3_v1_quadReg:
623 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value)
624 1.1 christos break;
625 1.1 christos case RegClass_kv3_v1_systemReg:
626 1.1 christos case RegClass_kv3_v1_aloneReg:
627 1.1 christos case RegClass_kv3_v1_onlyraReg:
628 1.1 christos case RegClass_kv3_v1_onlygetReg:
629 1.1 christos case RegClass_kv3_v1_onlysetReg:
630 1.1 christos case RegClass_kv3_v1_onlyfxReg:
631 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value)
632 1.1 christos break;
633 1.1 christos case RegClass_kv3_v1_coproReg0M4:
634 1.1 christos case RegClass_kv3_v1_coproReg1M4:
635 1.1 christos case RegClass_kv3_v1_coproReg2M4:
636 1.1 christos case RegClass_kv3_v1_coproReg3M4:
637 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value)
638 1.1 christos break;
639 1.1 christos case RegClass_kv3_v1_blockRegE:
640 1.1 christos case RegClass_kv3_v1_blockRegO:
641 1.1 christos case RegClass_kv3_v1_blockReg0M4:
642 1.1 christos case RegClass_kv3_v1_blockReg1M4:
643 1.1 christos case RegClass_kv3_v1_blockReg2M4:
644 1.1 christos case RegClass_kv3_v1_blockReg3M4:
645 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value)
646 1.1 christos break;
647 1.1 christos case RegClass_kv3_v1_vectorReg:
648 1.1 christos case RegClass_kv3_v1_vectorRegE:
649 1.1 christos case RegClass_kv3_v1_vectorRegO:
650 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value)
651 1.1 christos break;
652 1.1 christos case RegClass_kv3_v1_tileReg:
653 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value)
654 1.1 christos break;
655 1.1 christos case RegClass_kv3_v1_matrixReg:
656 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value)
657 1.1 christos break;
658 1.1 christos case Immediate_kv3_v1_sysnumber:
659 1.1 christos case Immediate_kv3_v1_signed10:
660 1.1 christos case Immediate_kv3_v1_signed16:
661 1.1 christos case Immediate_kv3_v1_signed27:
662 1.1 christos case Immediate_kv3_v1_wrapped32:
663 1.1 christos case Immediate_kv3_v1_signed37:
664 1.1 christos case Immediate_kv3_v1_signed43:
665 1.1 christos case Immediate_kv3_v1_signed54:
666 1.1 christos case Immediate_kv3_v1_wrapped64:
667 1.1 christos case Immediate_kv3_v1_unsigned6:
668 1.1 christos res->operands[idx].val = value;
669 1.1 christos res->operands[idx].sign = flags & kvxSIGNED;
670 1.1 christos res->operands[idx].width = width;
671 1.1 christos res->operands[idx].type = CAT_IMMEDIATE;
672 1.1 christos res->operands[idx].pcrel = 0;
673 1.1 christos idx++;
674 1.1 christos break;
675 1.1 christos case Immediate_kv3_v1_pcrel17:
676 1.1 christos case Immediate_kv3_v1_pcrel27:
677 1.1 christos res->operands[idx].val = value + memaddr;
678 1.1 christos res->operands[idx].sign = flags & kvxSIGNED;
679 1.1 christos res->operands[idx].width = width;
680 1.1 christos res->operands[idx].type = CAT_IMMEDIATE;
681 1.1 christos res->operands[idx].pcrel = 1;
682 1.1 christos idx++;
683 1.1 christos break;
684 1.1 christos case Modifier_kv3_v1_column:
685 1.1 christos case Modifier_kv3_v1_comparison:
686 1.1 christos case Modifier_kv3_v1_doscale:
687 1.1 christos case Modifier_kv3_v1_exunum:
688 1.1 christos case Modifier_kv3_v1_floatcomp:
689 1.1 christos case Modifier_kv3_v1_qindex:
690 1.1 christos case Modifier_kv3_v1_rectify:
691 1.1 christos case Modifier_kv3_v1_rounding:
692 1.1 christos case Modifier_kv3_v1_roundint:
693 1.1 christos case Modifier_kv3_v1_saturate:
694 1.1 christos case Modifier_kv3_v1_scalarcond:
695 1.1 christos case Modifier_kv3_v1_silent:
696 1.1 christos case Modifier_kv3_v1_simplecond:
697 1.1 christos case Modifier_kv3_v1_speculate:
698 1.1 christos case Modifier_kv3_v1_splat32:
699 1.1 christos case Modifier_kv3_v1_variant:
700 1.1 christos {
701 1.1 christos int sz = 0;
702 1.1 christos int mod_idx = type - Modifier_kv3_v1_column;
703 1.1 christos for (sz = 0; env.kvx_modifiers[mod_idx][sz]; ++sz);
704 1.1 christos const char *mod = value < (unsigned) sz
705 1.1 christos ? env.kvx_modifiers[mod_idx][value] : NULL;
706 1.1 christos if (!mod) goto retry;
707 1.1 christos res->operands[idx].val = value;
708 1.1 christos res->operands[idx].type = CAT_MODIFIER;
709 1.1 christos res->operands[idx].mod_idx = mod_idx;
710 1.1 christos idx++;
711 1.1 christos }
712 1.1 christos break;
713 1.1 christos default:
714 1.1 christos fprintf (stderr, "error: unexpected operand type (%s)\n",
715 1.1 christos type_name);
716 1.1 christos exit (-1);
717 1.1 christos };
718 1.1 christos }
719 1.1 christos else if (env.opc_table == kvx_kv3_v2_optab)
720 1.1 christos {
721 1.1 christos switch (type)
722 1.1 christos {
723 1.1 christos case RegClass_kv3_v2_singleReg:
724 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value)
725 1.1 christos break;
726 1.1 christos case RegClass_kv3_v2_pairedReg:
727 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value)
728 1.1 christos break;
729 1.1 christos case RegClass_kv3_v2_quadReg:
730 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value)
731 1.1 christos break;
732 1.1 christos case RegClass_kv3_v2_systemReg:
733 1.1 christos case RegClass_kv3_v2_aloneReg:
734 1.1 christos case RegClass_kv3_v2_onlyraReg:
735 1.1 christos case RegClass_kv3_v2_onlygetReg:
736 1.1 christos case RegClass_kv3_v2_onlysetReg:
737 1.1 christos case RegClass_kv3_v2_onlyfxReg:
738 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value)
739 1.1 christos break;
740 1.1 christos case RegClass_kv3_v2_coproReg:
741 1.1 christos case RegClass_kv3_v2_coproReg0M4:
742 1.1 christos case RegClass_kv3_v2_coproReg1M4:
743 1.1 christos case RegClass_kv3_v2_coproReg2M4:
744 1.1 christos case RegClass_kv3_v2_coproReg3M4:
745 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value)
746 1.1 christos break;
747 1.1 christos case RegClass_kv3_v2_blockReg:
748 1.1 christos case RegClass_kv3_v2_blockRegE:
749 1.1 christos case RegClass_kv3_v2_blockRegO:
750 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value)
751 1.1 christos break;
752 1.1 christos case RegClass_kv3_v2_vectorReg:
753 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value)
754 1.1 christos break;
755 1.1 christos case RegClass_kv3_v2_tileReg:
756 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value)
757 1.1 christos break;
758 1.1 christos case RegClass_kv3_v2_matrixReg:
759 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value)
760 1.1 christos break;
761 1.1 christos case RegClass_kv3_v2_buffer2Reg:
762 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X2R, value)
763 1.1 christos break;
764 1.1 christos case RegClass_kv3_v2_buffer4Reg:
765 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X4R, value)
766 1.1 christos break;
767 1.1 christos case RegClass_kv3_v2_buffer8Reg:
768 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X8R, value)
769 1.1 christos break;
770 1.1 christos case RegClass_kv3_v2_buffer16Reg:
771 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X16R, value)
772 1.1 christos break;
773 1.1 christos case RegClass_kv3_v2_buffer32Reg:
774 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X32R, value)
775 1.1 christos break;
776 1.1 christos case RegClass_kv3_v2_buffer64Reg:
777 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X64R, value)
778 1.1 christos break;
779 1.1 christos case Immediate_kv3_v2_brknumber:
780 1.1 christos case Immediate_kv3_v2_sysnumber:
781 1.1 christos case Immediate_kv3_v2_signed10:
782 1.1 christos case Immediate_kv3_v2_signed16:
783 1.1 christos case Immediate_kv3_v2_signed27:
784 1.1 christos case Immediate_kv3_v2_wrapped32:
785 1.1 christos case Immediate_kv3_v2_signed37:
786 1.1 christos case Immediate_kv3_v2_signed43:
787 1.1 christos case Immediate_kv3_v2_signed54:
788 1.1 christos case Immediate_kv3_v2_wrapped64:
789 1.1 christos case Immediate_kv3_v2_unsigned6:
790 1.1 christos res->operands[idx].val = value;
791 1.1 christos res->operands[idx].sign = flags & kvxSIGNED;
792 1.1 christos res->operands[idx].width = width;
793 1.1 christos res->operands[idx].type = CAT_IMMEDIATE;
794 1.1 christos res->operands[idx].pcrel = 0;
795 1.1 christos idx++;
796 1.1 christos break;
797 1.1 christos case Immediate_kv3_v2_pcrel27:
798 1.1 christos case Immediate_kv3_v2_pcrel17:
799 1.1 christos res->operands[idx].val = value + memaddr;
800 1.1 christos res->operands[idx].sign = flags & kvxSIGNED;
801 1.1 christos res->operands[idx].width = width;
802 1.1 christos res->operands[idx].type = CAT_IMMEDIATE;
803 1.1 christos res->operands[idx].pcrel = 1;
804 1.1 christos idx++;
805 1.1 christos break;
806 1.1 christos case Modifier_kv3_v2_accesses:
807 1.1 christos case Modifier_kv3_v2_boolcas:
808 1.1 christos case Modifier_kv3_v2_cachelev:
809 1.1 christos case Modifier_kv3_v2_channel:
810 1.1 christos case Modifier_kv3_v2_coherency:
811 1.1 christos case Modifier_kv3_v2_comparison:
812 1.1 christos case Modifier_kv3_v2_conjugate:
813 1.1 christos case Modifier_kv3_v2_doscale:
814 1.1 christos case Modifier_kv3_v2_exunum:
815 1.1 christos case Modifier_kv3_v2_floatcomp:
816 1.1 christos case Modifier_kv3_v2_hindex:
817 1.1 christos case Modifier_kv3_v2_lsomask:
818 1.1 christos case Modifier_kv3_v2_lsumask:
819 1.1 christos case Modifier_kv3_v2_lsupack:
820 1.1 christos case Modifier_kv3_v2_qindex:
821 1.1 christos case Modifier_kv3_v2_rounding:
822 1.1 christos case Modifier_kv3_v2_scalarcond:
823 1.1 christos case Modifier_kv3_v2_shuffleV:
824 1.1 christos case Modifier_kv3_v2_shuffleX:
825 1.1 christos case Modifier_kv3_v2_silent:
826 1.1 christos case Modifier_kv3_v2_simplecond:
827 1.1 christos case Modifier_kv3_v2_speculate:
828 1.1 christos case Modifier_kv3_v2_splat32:
829 1.1 christos case Modifier_kv3_v2_transpose:
830 1.1 christos case Modifier_kv3_v2_variant:
831 1.1 christos {
832 1.1 christos int sz = 0;
833 1.1 christos int mod_idx = type - Modifier_kv3_v2_accesses;
834 1.1 christos for (sz = 0; env.kvx_modifiers[mod_idx][sz];
835 1.1 christos ++sz);
836 1.1 christos const char *mod = value < (unsigned) sz
837 1.1 christos ? env.kvx_modifiers[mod_idx][value] : NULL;
838 1.1 christos if (!mod) goto retry;
839 1.1 christos res->operands[idx].val = value;
840 1.1 christos res->operands[idx].type = CAT_MODIFIER;
841 1.1 christos res->operands[idx].mod_idx = mod_idx;
842 1.1 christos idx++;
843 1.1 christos };
844 1.1 christos break;
845 1.1 christos default:
846 1.1 christos fprintf (stderr,
847 1.1 christos "error: unexpected operand type (%s)\n",
848 1.1 christos type_name);
849 1.1 christos exit (-1);
850 1.1 christos };
851 1.1 christos }
852 1.1 christos else if (env.opc_table == kvx_kv4_v1_optab)
853 1.1 christos {
854 1.1 christos switch (type)
855 1.1 christos {
856 1.1 christos
857 1.1 christos case RegClass_kv4_v1_singleReg:
858 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_GPR, value)
859 1.1 christos break;
860 1.1 christos case RegClass_kv4_v1_pairedReg:
861 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_PGR, value)
862 1.1 christos break;
863 1.1 christos case RegClass_kv4_v1_quadReg:
864 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_QGR, value)
865 1.1 christos break;
866 1.1 christos case RegClass_kv4_v1_systemReg:
867 1.1 christos case RegClass_kv4_v1_aloneReg:
868 1.1 christos case RegClass_kv4_v1_onlyraReg:
869 1.1 christos case RegClass_kv4_v1_onlygetReg:
870 1.1 christos case RegClass_kv4_v1_onlysetReg:
871 1.1 christos case RegClass_kv4_v1_onlyfxReg:
872 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_SFR, value)
873 1.1 christos break;
874 1.1 christos case RegClass_kv4_v1_coproReg:
875 1.1 christos case RegClass_kv4_v1_coproReg0M4:
876 1.1 christos case RegClass_kv4_v1_coproReg1M4:
877 1.1 christos case RegClass_kv4_v1_coproReg2M4:
878 1.1 christos case RegClass_kv4_v1_coproReg3M4:
879 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XCR, value)
880 1.1 christos break;
881 1.1 christos case RegClass_kv4_v1_blockReg:
882 1.1 christos case RegClass_kv4_v1_blockRegE:
883 1.1 christos case RegClass_kv4_v1_blockRegO:
884 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XBR, value)
885 1.1 christos break;
886 1.1 christos case RegClass_kv4_v1_vectorReg:
887 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XVR, value)
888 1.1 christos break;
889 1.1 christos case RegClass_kv4_v1_tileReg:
890 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XTR, value)
891 1.1 christos break;
892 1.1 christos case RegClass_kv4_v1_matrixReg:
893 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_XMR, value)
894 1.1 christos break;
895 1.1 christos case RegClass_kv4_v1_buffer2Reg:
896 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X2R, value)
897 1.1 christos break;
898 1.1 christos case RegClass_kv4_v1_buffer4Reg:
899 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X4R, value)
900 1.1 christos break;
901 1.1 christos case RegClass_kv4_v1_buffer8Reg:
902 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X8R, value)
903 1.1 christos break;
904 1.1 christos case RegClass_kv4_v1_buffer16Reg:
905 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X16R, value)
906 1.1 christos break;
907 1.1 christos case RegClass_kv4_v1_buffer32Reg:
908 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X32R, value)
909 1.1 christos break;
910 1.1 christos case RegClass_kv4_v1_buffer64Reg:
911 1.1 christos KVX_PRINT_REG (KVX_REGFILE_DEC_X64R, value)
912 1.1 christos break;
913 1.1 christos case Immediate_kv4_v1_brknumber:
914 1.1 christos case Immediate_kv4_v1_sysnumber:
915 1.1 christos case Immediate_kv4_v1_signed10:
916 1.1 christos case Immediate_kv4_v1_signed16:
917 1.1 christos case Immediate_kv4_v1_signed27:
918 1.1 christos case Immediate_kv4_v1_wrapped32:
919 1.1 christos case Immediate_kv4_v1_signed37:
920 1.1 christos case Immediate_kv4_v1_signed43:
921 1.1 christos case Immediate_kv4_v1_signed54:
922 1.1 christos case Immediate_kv4_v1_wrapped64:
923 1.1 christos case Immediate_kv4_v1_unsigned6:
924 1.1 christos res->operands[idx].val = value;
925 1.1 christos res->operands[idx].sign = flags & kvxSIGNED;
926 1.1 christos res->operands[idx].width = width;
927 1.1 christos res->operands[idx].type = CAT_IMMEDIATE;
928 1.1 christos res->operands[idx].pcrel = 0;
929 1.1 christos idx++;
930 1.1 christos break;
931 1.1 christos case Immediate_kv4_v1_pcrel27:
932 1.1 christos case Immediate_kv4_v1_pcrel17:
933 1.1 christos res->operands[idx].val = value + memaddr;
934 1.1 christos res->operands[idx].sign = flags & kvxSIGNED;
935 1.1 christos res->operands[idx].width = width;
936 1.1 christos res->operands[idx].type = CAT_IMMEDIATE;
937 1.1 christos res->operands[idx].pcrel = 1;
938 1.1 christos idx++;
939 1.1 christos break;
940 1.1 christos case Modifier_kv4_v1_accesses:
941 1.1 christos case Modifier_kv4_v1_boolcas:
942 1.1 christos case Modifier_kv4_v1_cachelev:
943 1.1 christos case Modifier_kv4_v1_channel:
944 1.1 christos case Modifier_kv4_v1_coherency:
945 1.1 christos case Modifier_kv4_v1_comparison:
946 1.1 christos case Modifier_kv4_v1_conjugate:
947 1.1 christos case Modifier_kv4_v1_doscale:
948 1.1 christos case Modifier_kv4_v1_exunum:
949 1.1 christos case Modifier_kv4_v1_floatcomp:
950 1.1 christos case Modifier_kv4_v1_hindex:
951 1.1 christos case Modifier_kv4_v1_lsomask:
952 1.1 christos case Modifier_kv4_v1_lsumask:
953 1.1 christos case Modifier_kv4_v1_lsupack:
954 1.1 christos case Modifier_kv4_v1_qindex:
955 1.1 christos case Modifier_kv4_v1_rounding:
956 1.1 christos case Modifier_kv4_v1_scalarcond:
957 1.1 christos case Modifier_kv4_v1_shuffleV:
958 1.1 christos case Modifier_kv4_v1_shuffleX:
959 1.1 christos case Modifier_kv4_v1_silent:
960 1.1 christos case Modifier_kv4_v1_simplecond:
961 1.1 christos case Modifier_kv4_v1_speculate:
962 1.1 christos case Modifier_kv4_v1_splat32:
963 1.1 christos case Modifier_kv4_v1_transpose:
964 1.1 christos case Modifier_kv4_v1_variant:
965 1.1 christos {
966 1.1 christos int sz = 0;
967 1.1 christos int mod_idx = type - Modifier_kv4_v1_accesses;
968 1.1 christos for (sz = 0; env.kvx_modifiers[mod_idx][sz]; ++sz);
969 1.1 christos const char *mod = value < (unsigned) sz
970 1.1 christos ? env.kvx_modifiers[mod_idx][value] : NULL;
971 1.1 christos if (!mod) goto retry;
972 1.1 christos res->operands[idx].val = value;
973 1.1 christos res->operands[idx].type = CAT_MODIFIER;
974 1.1 christos res->operands[idx].mod_idx = mod_idx;
975 1.1 christos idx++;
976 1.1 christos }
977 1.1 christos break;
978 1.1 christos default:
979 1.1 christos fprintf (stderr, "error: unexpected operand type (%s)\n",
980 1.1 christos type_name);
981 1.1 christos exit (-1);
982 1.1 christos };
983 1.1 christos }
984 1.1 christos
985 1.1 christos #undef KVX_PRINT_REG
986 1.1 christos }
987 1.1 christos
988 1.1 christos found = 1;
989 1.1 christos break;
990 1.1 christos retry:;
991 1.1 christos idx = 0;
992 1.1 christos continue;
993 1.1 christos }
994 1.1 christos }
995 1.1 christos res->nb_ops = idx;
996 1.1 christos return found;
997 1.1 christos }
998 1.1 christos
999 1.1 christos int
1000 1.1 christos print_insn_kvx (bfd_vma memaddr, struct disassemble_info *info)
1001 1.1 christos {
1002 1.1 christos static int insnindex = 0;
1003 1.1 christos static int insncount = 0;
1004 1.1 christos insn_t *insn;
1005 1.1 christos int readsofar = 0;
1006 1.1 christos int found = 0;
1007 1.1 christos int invalid_bundle = 0;
1008 1.1 christos
1009 1.1 christos if (!env.initialized_p)
1010 1.1 christos kvx_dis_init (info);
1011 1.1 christos
1012 1.1 christos /* Clear instruction information field. */
1013 1.1 christos info->insn_info_valid = 0;
1014 1.1 christos info->branch_delay_insns = 0;
1015 1.1 christos info->data_size = 0;
1016 1.1 christos info->insn_type = dis_noninsn;
1017 1.1 christos info->target = 0;
1018 1.1 christos info->target2 = 0;
1019 1.1 christos
1020 1.1 christos /* Set line length. */
1021 1.1 christos info->bytes_per_line = 16;
1022 1.1 christos
1023 1.1 christos
1024 1.1 christos /* If this is the beginning of the bundle, read BUNDLESIZE words and apply
1025 1.1 christos decentrifugate function. */
1026 1.1 christos if (insnindex == 0)
1027 1.1 christos {
1028 1.1 christos int wordcount;
1029 1.1 christos for (wordcount = 0; wordcount < KVXMAXBUNDLEWORDS; wordcount++)
1030 1.1 christos {
1031 1.1 christos int status;
1032 1.1 christos status =
1033 1.1 christos (*info->read_memory_func) (memaddr + 4 * wordcount,
1034 1.1 christos (bfd_byte *) (bundle_words +
1035 1.1 christos wordcount), 4, info);
1036 1.1 christos if (status != 0)
1037 1.1 christos {
1038 1.1 christos (*info->memory_error_func) (status, memaddr + 4 * wordcount,
1039 1.1 christos info);
1040 1.1 christos return -1;
1041 1.1 christos }
1042 1.1 christos if (!kvx_has_parallel_bit (bundle_words[wordcount]))
1043 1.1 christos break;
1044 1.1 christos }
1045 1.1 christos wordcount++;
1046 1.1 christos invalid_bundle = !kvx_reassemble_bundle (wordcount, &insncount);
1047 1.1 christos }
1048 1.1 christos
1049 1.1 christos assert (insnindex < KVXMAXBUNDLEISSUE);
1050 1.1 christos insn = &(bundle_insn[insnindex]);
1051 1.1 christos readsofar = insn->len * 4;
1052 1.1 christos insnindex++;
1053 1.1 christos
1054 1.1 christos if (opt_pretty)
1055 1.1 christos {
1056 1.1 christos (*info->fprintf_func) (info->stream, "[ ");
1057 1.1 christos for (int i = 0; i < insn->len; i++)
1058 1.1 christos (*info->fprintf_func) (info->stream, "%08x ", insn->syllables[i]);
1059 1.1 christos (*info->fprintf_func) (info->stream, "] ");
1060 1.1 christos }
1061 1.1 christos
1062 1.1 christos /* Check for extension to right iff this is not the end of bundle. */
1063 1.1 christos
1064 1.1 christos struct decoded_insn dec;
1065 1.1 christos memset (&dec, 0, sizeof dec);
1066 1.1 christos if (!invalid_bundle && (found = decode_insn (memaddr, insn, &dec)))
1067 1.1 christos {
1068 1.1 christos int ch;
1069 1.1 christos (*info->fprintf_func) (info->stream, "%s", dec.opc->as_op);
1070 1.1 christos const char *fmtp = dec.opc->fmtstring;
1071 1.1 christos for (int i = 0; i < dec.nb_ops; ++i)
1072 1.1 christos {
1073 1.1 christos /* Print characters in the format string up to the following % or nul. */
1074 1.1 christos while ((ch = *fmtp) && ch != '%')
1075 1.1 christos {
1076 1.1 christos (*info->fprintf_func) (info->stream, "%c", ch);
1077 1.1 christos fmtp++;
1078 1.1 christos }
1079 1.1 christos
1080 1.1 christos /* Skip past %s. */
1081 1.1 christos if (ch == '%')
1082 1.1 christos {
1083 1.1 christos ch = *fmtp++;
1084 1.1 christos fmtp++;
1085 1.1 christos }
1086 1.1 christos
1087 1.1 christos switch (dec.operands[i].type)
1088 1.1 christos {
1089 1.1 christos case CAT_REGISTER:
1090 1.1 christos (*info->fprintf_func) (info->stream, "%s",
1091 1.1 christos env.kvx_registers[dec.operands[i].val].name);
1092 1.1 christos break;
1093 1.1 christos case CAT_MODIFIER:
1094 1.1 christos {
1095 1.1 christos const char *mod = env.kvx_modifiers[dec.operands[i].mod_idx][dec.operands[i].val];
1096 1.1 christos (*info->fprintf_func) (info->stream, "%s", !mod || !strcmp (mod, ".") ? "" : mod);
1097 1.1 christos }
1098 1.1 christos break;
1099 1.1 christos case CAT_IMMEDIATE:
1100 1.1 christos {
1101 1.1 christos if (dec.operands[i].pcrel)
1102 1.1 christos {
1103 1.1 christos /* Fill in instruction information. */
1104 1.1 christos info->insn_info_valid = 1;
1105 1.1 christos info->insn_type =
1106 1.1 christos dec.operands[i].width ==
1107 1.1 christos 17 ? dis_condbranch : dis_branch;
1108 1.1 christos info->target = dec.operands[i].val;
1109 1.1 christos
1110 1.1 christos info->print_address_func (dec.operands[i].val, info);
1111 1.1 christos }
1112 1.1 christos else if (dec.operands[i].sign)
1113 1.1 christos {
1114 1.1 christos if (dec.operands[i].width <= 32)
1115 1.1 christos {
1116 1.1 christos (*info->fprintf_func) (info->stream, "%" PRId32 " (0x%" PRIx32 ")",
1117 1.1 christos (int32_t) dec.operands[i].val,
1118 1.1 christos (int32_t) dec.operands[i].val);
1119 1.1 christos }
1120 1.1 christos else
1121 1.1 christos {
1122 1.1 christos (*info->fprintf_func) (info->stream, "%" PRId64 " (0x%" PRIx64 ")",
1123 1.1 christos dec.operands[i].val,
1124 1.1 christos dec.operands[i].val);
1125 1.1 christos }
1126 1.1 christos }
1127 1.1 christos else
1128 1.1 christos {
1129 1.1 christos if (dec.operands[i].width <= 32)
1130 1.1 christos {
1131 1.1 christos (*info->fprintf_func) (info->stream, "%" PRIu32 " (0x%" PRIx32 ")",
1132 1.1 christos (uint32_t) dec.operands[i].
1133 1.1 christos val,
1134 1.1 christos (uint32_t) dec.operands[i].
1135 1.1 christos val);
1136 1.1 christos }
1137 1.1 christos else
1138 1.1 christos {
1139 1.1 christos (*info->fprintf_func) (info->stream, "%" PRIu64 " (0x%" PRIx64 ")",
1140 1.1 christos (uint64_t) dec.
1141 1.1 christos operands[i].val,
1142 1.1 christos (uint64_t) dec.
1143 1.1 christos operands[i].val);
1144 1.1 christos }
1145 1.1 christos }
1146 1.1 christos }
1147 1.1 christos break;
1148 1.1 christos default:
1149 1.1 christos break;
1150 1.1 christos
1151 1.1 christos }
1152 1.1 christos }
1153 1.1 christos
1154 1.1 christos while ((ch = *fmtp))
1155 1.1 christos {
1156 1.1 christos (*info->fprintf_styled_func) (info->stream, dis_style_text, "%c",
1157 1.1 christos ch);
1158 1.1 christos fmtp++;
1159 1.1 christos }
1160 1.1 christos }
1161 1.1 christos else
1162 1.1 christos {
1163 1.1 christos (*info->fprintf_func) (info->stream, "*** invalid opcode ***\n");
1164 1.1 christos insnindex = 0;
1165 1.1 christos readsofar = 4;
1166 1.1 christos }
1167 1.1 christos
1168 1.1 christos if (found && (insnindex == insncount))
1169 1.1 christos {
1170 1.1 christos (*info->fprintf_func) (info->stream, ";;");
1171 1.1 christos if (!opt_compact_assembly)
1172 1.1 christos (*info->fprintf_func) (info->stream, "\n");
1173 1.1 christos insnindex = 0;
1174 1.1 christos }
1175 1.1 christos
1176 1.1 christos return readsofar;
1177 1.1 christos }
1178 1.1 christos
1179 1.1 christos /* This function searches in the current bundle for the instructions required
1180 1.1 christos by unwinding. For prologue:
1181 1.1 christos (1) addd $r12 = $r12, <res_stack>
1182 1.1 christos (2) get <gpr_ra_reg> = $ra
1183 1.1 christos (3) sd <ofs>[$r12] = <gpr_ra_reg> or sq/so containing <gpr_ra_reg>
1184 1.1 christos (4) sd <ofs>[$r12] = $r14 or sq/so containing r14
1185 1.1 christos (5) addd $r14 = $r12, <fp_ofs> or copyd $r14 = $r12
1186 1.1 christos The only difference seen between the code generated by gcc and clang
1187 1.1 christos is the setting/resetting r14. gcc could also generate copyd $r14=$r12
1188 1.1 christos instead of add addd $r14 = $r12, <ofs> when <ofs> is 0.
1189 1.1 christos Vice-versa, <ofs> is not guaranteed to be 0 for clang, so, clang
1190 1.1 christos could also generate addd instead of copyd
1191 1.1 christos (6) call, icall, goto, igoto, cb., ret
1192 1.1 christos For epilogue:
1193 1.1 christos (1) addd $r12 = $r12, <res_stack>
1194 1.1 christos (2) addd $r12 = $r14, <offset> or copyd $r12 = $r14
1195 1.1 christos Same comment as prologue (5).
1196 1.1 christos (3) ret, goto
1197 1.1 christos (4) call, icall, igoto, cb. */
1198 1.1 christos
1199 1.1 christos int
1200 1.1 christos decode_prologue_epilogue_bundle (bfd_vma memaddr,
1201 1.1 christos struct disassemble_info *info,
1202 1.1 christos struct kvx_prologue_epilogue_bundle *peb)
1203 1.1 christos {
1204 1.1 christos int i, nb_insn, nb_syl;
1205 1.1 christos
1206 1.1 christos peb->nb_insn = 0;
1207 1.1 christos
1208 1.1 christos if (info->arch != bfd_arch_kvx)
1209 1.1 christos return -1;
1210 1.1 christos
1211 1.1 christos if (!env.initialized_p)
1212 1.1 christos kvx_dis_init (info);
1213 1.1 christos
1214 1.1 christos /* Read the bundle. */
1215 1.1 christos for (nb_syl = 0; nb_syl < KVXMAXBUNDLEWORDS; nb_syl++)
1216 1.1 christos {
1217 1.1 christos if ((*info->read_memory_func) (memaddr + 4 * nb_syl,
1218 1.1 christos (bfd_byte *) &bundle_words[nb_syl], 4,
1219 1.1 christos info))
1220 1.1 christos return -1;
1221 1.1 christos if (!kvx_has_parallel_bit (bundle_words[nb_syl]))
1222 1.1 christos break;
1223 1.1 christos }
1224 1.1 christos nb_syl++;
1225 1.1 christos if (!kvx_reassemble_bundle (nb_syl, &nb_insn))
1226 1.1 christos return -1;
1227 1.1 christos
1228 1.1 christos /* Check for extension to right if this is not the end of bundle
1229 1.1 christos find the format of this insn. */
1230 1.1 christos for (int idx_insn = 0; idx_insn < nb_insn; idx_insn++)
1231 1.1 christos {
1232 1.1 christos insn_t *insn = &bundle_insn[idx_insn];
1233 1.1 christos int is_add = 0, is_get = 0, is_a_peb_insn = 0, is_copyd = 0;
1234 1.1 christos
1235 1.1 christos struct decoded_insn dec;
1236 1.1 christos memset (&dec, 0, sizeof dec);
1237 1.1 christos if (!decode_insn (memaddr, insn, &dec))
1238 1.1 christos continue;
1239 1.1 christos
1240 1.1 christos const char *op_name = dec.opc->as_op;
1241 1.1 christos struct kvx_prologue_epilogue_insn *crt_peb_insn;
1242 1.1 christos
1243 1.1 christos crt_peb_insn = &peb->insn[peb->nb_insn];
1244 1.1 christos crt_peb_insn->nb_gprs = 0;
1245 1.1 christos
1246 1.1 christos if (!strcmp (op_name, "addd"))
1247 1.1 christos is_add = 1;
1248 1.1 christos else if (!strcmp (op_name, "copyd"))
1249 1.1 christos is_copyd = 1;
1250 1.1 christos else if (!strcmp (op_name, "get"))
1251 1.1 christos is_get = 1;
1252 1.1 christos else if (!strcmp (op_name, "sd"))
1253 1.1 christos {
1254 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SD;
1255 1.1 christos is_a_peb_insn = 1;
1256 1.1 christos }
1257 1.1 christos else if (!strcmp (op_name, "sq"))
1258 1.1 christos {
1259 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SQ;
1260 1.1 christos is_a_peb_insn = 1;
1261 1.1 christos }
1262 1.1 christos else if (!strcmp (op_name, "so"))
1263 1.1 christos {
1264 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_SO;
1265 1.1 christos is_a_peb_insn = 1;
1266 1.1 christos }
1267 1.1 christos else if (!strcmp (op_name, "ret"))
1268 1.1 christos {
1269 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_RET;
1270 1.1 christos is_a_peb_insn = 1;
1271 1.1 christos }
1272 1.1 christos else if (!strcmp (op_name, "goto"))
1273 1.1 christos {
1274 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_GOTO;
1275 1.1 christos is_a_peb_insn = 1;
1276 1.1 christos }
1277 1.1 christos else if (!strcmp (op_name, "igoto"))
1278 1.1 christos {
1279 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_IGOTO;
1280 1.1 christos is_a_peb_insn = 1;
1281 1.1 christos }
1282 1.1 christos else if (!strcmp (op_name, "call") || !strcmp (op_name, "icall"))
1283 1.1 christos {
1284 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_CALL;
1285 1.1 christos is_a_peb_insn = 1;
1286 1.1 christos }
1287 1.1 christos else if (!strncmp (op_name, "cb", 2))
1288 1.1 christos {
1289 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_CB;
1290 1.1 christos is_a_peb_insn = 1;
1291 1.1 christos }
1292 1.1 christos else
1293 1.1 christos continue;
1294 1.1 christos
1295 1.1 christos for (i = 0; dec.opc->format[i]; i++)
1296 1.1 christos {
1297 1.1 christos struct kvx_operand *fmt = dec.opc->format[i];
1298 1.1 christos struct kvx_bitfield *bf = fmt->bfield;
1299 1.1 christos int bf_nb = fmt->bitfields;
1300 1.1 christos int width = fmt->width;
1301 1.1 christos int type = fmt->type;
1302 1.1 christos int flags = fmt->flags;
1303 1.1 christos int shift = fmt->shift;
1304 1.1 christos int bias = fmt->bias;
1305 1.1 christos uint64_t encoded_value, value = 0;
1306 1.1 christos
1307 1.1 christos for (int bf_idx = 0; bf_idx < bf_nb; bf_idx++)
1308 1.1 christos {
1309 1.1 christos int insn_idx = (int) bf[bf_idx].to_offset / 32;
1310 1.1 christos int to_offset = bf[bf_idx].to_offset % 32;
1311 1.1 christos encoded_value = insn->syllables[insn_idx] >> to_offset;
1312 1.1 christos encoded_value &= (1LL << bf[bf_idx].size) - 1;
1313 1.1 christos value |= encoded_value << bf[bf_idx].from_offset;
1314 1.1 christos }
1315 1.1 christos if (flags & kvxSIGNED)
1316 1.1 christos {
1317 1.1 christos uint64_t signbit = 1LL << (width - 1);
1318 1.1 christos value = (value ^ signbit) - signbit;
1319 1.1 christos }
1320 1.1 christos value = (value << shift) + bias;
1321 1.1 christos
1322 1.1 christos #define chk_type(core_, val_) \
1323 1.1 christos (env.opc_table == kvx_## core_ ##_optab && type == (val_))
1324 1.1 christos
1325 1.1 christos if (chk_type (kv3_v1, RegClass_kv3_v1_singleReg)
1326 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_singleReg)
1327 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_singleReg))
1328 1.1 christos {
1329 1.1 christos if (env.kvx_regfiles[KVX_REGFILE_DEC_GPR] + value
1330 1.1 christos >= env.kvx_max_dec_registers)
1331 1.1 christos return -1;
1332 1.1 christos if (is_add && i < 2)
1333 1.1 christos {
1334 1.1 christos if (i == 0)
1335 1.1 christos {
1336 1.1 christos if (value == KVX_GPR_REG_SP)
1337 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_SP;
1338 1.1 christos else if (value == KVX_GPR_REG_FP)
1339 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_FP;
1340 1.1 christos else
1341 1.1 christos is_add = 0;
1342 1.1 christos }
1343 1.1 christos else if (i == 1)
1344 1.1 christos {
1345 1.1 christos if (value == KVX_GPR_REG_SP)
1346 1.1 christos is_a_peb_insn = 1;
1347 1.1 christos else if (value == KVX_GPR_REG_FP
1348 1.1 christos && crt_peb_insn->insn_type
1349 1.1 christos == KVX_PROL_EPIL_INSN_ADD_SP)
1350 1.1 christos {
1351 1.1 christos crt_peb_insn->insn_type
1352 1.1 christos = KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP;
1353 1.1 christos is_a_peb_insn = 1;
1354 1.1 christos }
1355 1.1 christos else
1356 1.1 christos is_add = 0;
1357 1.1 christos }
1358 1.1 christos }
1359 1.1 christos else if (is_copyd && i < 2)
1360 1.1 christos {
1361 1.1 christos if (i == 0)
1362 1.1 christos {
1363 1.1 christos if (value == KVX_GPR_REG_FP)
1364 1.1 christos {
1365 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_ADD_FP;
1366 1.1 christos crt_peb_insn->immediate = 0;
1367 1.1 christos }
1368 1.1 christos else if (value == KVX_GPR_REG_SP)
1369 1.1 christos {
1370 1.1 christos crt_peb_insn->insn_type
1371 1.1 christos = KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP;
1372 1.1 christos crt_peb_insn->immediate = 0;
1373 1.1 christos }
1374 1.1 christos else
1375 1.1 christos is_copyd = 0;
1376 1.1 christos }
1377 1.1 christos else if (i == 1)
1378 1.1 christos {
1379 1.1 christos if (value == KVX_GPR_REG_SP
1380 1.1 christos && crt_peb_insn->insn_type
1381 1.1 christos == KVX_PROL_EPIL_INSN_ADD_FP)
1382 1.1 christos is_a_peb_insn = 1;
1383 1.1 christos else if (value == KVX_GPR_REG_FP
1384 1.1 christos && crt_peb_insn->insn_type
1385 1.1 christos == KVX_PROL_EPIL_INSN_RESTORE_SP_FROM_FP)
1386 1.1 christos is_a_peb_insn = 1;
1387 1.1 christos else
1388 1.1 christos is_copyd = 0;
1389 1.1 christos }
1390 1.1 christos }
1391 1.1 christos else
1392 1.1 christos crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value;
1393 1.1 christos }
1394 1.1 christos else if (chk_type (kv3_v1, RegClass_kv3_v1_pairedReg)
1395 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_pairedReg)
1396 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_pairedReg))
1397 1.1 christos crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value * 2;
1398 1.1 christos else if (chk_type (kv3_v1, RegClass_kv3_v1_quadReg)
1399 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_quadReg)
1400 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_quadReg))
1401 1.1 christos crt_peb_insn->gpr_reg[crt_peb_insn->nb_gprs++] = value * 4;
1402 1.1 christos else if (chk_type (kv3_v1, RegClass_kv3_v1_systemReg)
1403 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_systemReg)
1404 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_systemReg)
1405 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_aloneReg)
1406 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_aloneReg)
1407 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_aloneReg)
1408 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_onlyraReg)
1409 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_onlyraReg)
1410 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_onlygetReg)
1411 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_onlygetReg)
1412 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_onlygetReg)
1413 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_onlygetReg)
1414 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_onlysetReg)
1415 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_onlysetReg)
1416 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_onlysetReg)
1417 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_onlyfxReg)
1418 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_onlyfxReg)
1419 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_onlyfxReg))
1420 1.1 christos {
1421 1.1 christos if (env.kvx_regfiles[KVX_REGFILE_DEC_GPR] + value
1422 1.1 christos >= env.kvx_max_dec_registers)
1423 1.1 christos return -1;
1424 1.1 christos if (is_get && !strcmp (env.kvx_registers[env.kvx_dec_registers[env.kvx_regfiles[KVX_REGFILE_DEC_SFR] + value]].name, "$ra"))
1425 1.1 christos {
1426 1.1 christos crt_peb_insn->insn_type = KVX_PROL_EPIL_INSN_GET_RA;
1427 1.1 christos is_a_peb_insn = 1;
1428 1.1 christos }
1429 1.1 christos }
1430 1.1 christos else if (chk_type (kv3_v1, RegClass_kv3_v1_coproReg)
1431 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_coproReg)
1432 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_coproReg)
1433 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_blockReg)
1434 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_blockReg)
1435 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_blockReg)
1436 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_vectorReg)
1437 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_vectorReg)
1438 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_vectorReg)
1439 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_tileReg)
1440 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_tileReg)
1441 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_tileReg)
1442 1.1 christos || chk_type (kv3_v1, RegClass_kv3_v1_matrixReg)
1443 1.1 christos || chk_type (kv3_v2, RegClass_kv3_v2_matrixReg)
1444 1.1 christos || chk_type (kv4_v1, RegClass_kv4_v1_matrixReg)
1445 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_scalarcond)
1446 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_column)
1447 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_comparison)
1448 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_doscale)
1449 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_exunum)
1450 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_floatcomp)
1451 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_qindex)
1452 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_rectify)
1453 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_rounding)
1454 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_roundint)
1455 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_saturate)
1456 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_scalarcond)
1457 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_silent)
1458 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_simplecond)
1459 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_speculate)
1460 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_splat32)
1461 1.1 christos || chk_type (kv3_v1, Modifier_kv3_v1_variant)
1462 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_accesses)
1463 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_boolcas)
1464 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_cachelev)
1465 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_channel)
1466 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_coherency)
1467 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_comparison)
1468 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_conjugate)
1469 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_doscale)
1470 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_exunum)
1471 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_floatcomp)
1472 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_hindex)
1473 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_lsomask)
1474 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_lsumask)
1475 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_lsupack)
1476 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_qindex)
1477 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_rounding)
1478 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_scalarcond)
1479 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_shuffleV)
1480 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_shuffleX)
1481 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_silent)
1482 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_simplecond)
1483 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_speculate)
1484 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_splat32)
1485 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_transpose)
1486 1.1 christos || chk_type (kv3_v2, Modifier_kv3_v2_variant)
1487 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_accesses)
1488 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_boolcas)
1489 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_cachelev)
1490 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_channel)
1491 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_coherency)
1492 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_comparison)
1493 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_conjugate)
1494 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_doscale)
1495 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_exunum)
1496 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_floatcomp)
1497 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_hindex)
1498 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_lsomask)
1499 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_lsumask)
1500 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_lsupack)
1501 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_qindex)
1502 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_rounding)
1503 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_scalarcond)
1504 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_shuffleV)
1505 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_shuffleX)
1506 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_silent)
1507 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_simplecond)
1508 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_speculate)
1509 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_splat32)
1510 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_transpose)
1511 1.1 christos || chk_type (kv4_v1, Modifier_kv4_v1_variant))
1512 1.1 christos {
1513 1.1 christos /* Do nothing. */
1514 1.1 christos }
1515 1.1 christos else if (chk_type (kv3_v1, Immediate_kv3_v1_sysnumber)
1516 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_sysnumber)
1517 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_sysnumber)
1518 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_wrapped8)
1519 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_wrapped8)
1520 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_signed10)
1521 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_signed10)
1522 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_signed10)
1523 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_signed16)
1524 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_signed16)
1525 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_signed16)
1526 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_signed27)
1527 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_signed27)
1528 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_signed27)
1529 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_wrapped32)
1530 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_wrapped32)
1531 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_wrapped32)
1532 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_signed37)
1533 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_signed37)
1534 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_signed37)
1535 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_signed43)
1536 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_signed43)
1537 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_signed43)
1538 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_signed54)
1539 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_signed54)
1540 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_signed54)
1541 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_wrapped64)
1542 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_wrapped64)
1543 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_wrapped64)
1544 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_unsigned6)
1545 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_unsigned6)
1546 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_unsigned6))
1547 1.1 christos crt_peb_insn->immediate = value;
1548 1.1 christos else if (chk_type (kv3_v1, Immediate_kv3_v1_pcrel17)
1549 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_pcrel17)
1550 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_pcrel17)
1551 1.1 christos || chk_type (kv3_v1, Immediate_kv3_v1_pcrel27)
1552 1.1 christos || chk_type (kv3_v2, Immediate_kv3_v2_pcrel27)
1553 1.1 christos || chk_type (kv4_v1, Immediate_kv4_v1_pcrel27))
1554 1.1 christos crt_peb_insn->immediate = value + memaddr;
1555 1.1 christos else
1556 1.1 christos return -1;
1557 1.1 christos }
1558 1.1 christos
1559 1.1 christos if (is_a_peb_insn)
1560 1.1 christos peb->nb_insn++;
1561 1.1 christos continue;
1562 1.1 christos }
1563 1.1 christos
1564 1.1 christos return nb_syl * 4;
1565 1.1 christos #undef chk_type
1566 1.1 christos }
1567 1.1 christos
1568 1.1 christos void
1569 1.1 christos print_kvx_disassembler_options (FILE * stream)
1570 1.1 christos {
1571 1.1 christos fprintf (stream, _("\n\
1572 1.1 christos The following KVX specific disassembler options are supported for use\n\
1573 1.1 christos with the -M switch (multiple options should be separated by commas):\n"));
1574 1.1 christos
1575 1.1 christos fprintf (stream, _("\n\
1576 1.1 christos pretty Print 32-bit words in natural order corresponding to \
1577 1.1 christos re-ordered instruction.\n"));
1578 1.1 christos
1579 1.1 christos fprintf (stream, _("\n\
1580 1.1 christos compact-assembly Do not emit a new line between bundles of instructions.\
1581 1.1 christos \n"));
1582 1.1 christos
1583 1.1 christos fprintf (stream, _("\n\
1584 1.1 christos no-compact-assembly Emit a new line between bundles of instructions.\n"));
1585 1.1 christos
1586 1.1 christos fprintf (stream, _("\n"));
1587 1.1 christos }
1588