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