asan: null deref in coff_write_relocs
[binutils-gdb.git] / opcodes / nfp-dis.c
1 /* Print NFP instructions for objdump.
2 Copyright (C) 2017-2022 Free Software Foundation, Inc.
3 Contributed by Francois H. Theron <francois.theron@netronome.com>
4
5 This file is part of the GNU opcodes library.
6
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22 /* There will be many magic numbers here that are based on hardware.
23 Making #define macros for each encoded bit field will probably reduce
24 readability far more than the simple numbers will, so we make sure that
25 the context of the magic numbers make it clear what they are used for. */
26
27 #include "sysdep.h"
28 #include <stdio.h>
29 #include "disassemble.h"
30 #include "libiberty.h"
31 #include "elf/nfp.h"
32 #include "opcode/nfp.h"
33 #include "opintl.h"
34 #include "elf-bfd.h"
35 #include "bfd.h"
36 #include <stdint.h>
37
38 #define _NFP_ERR_STOP -1
39 #define _NFP_ERR_CONT -8
40
41 #define _BTST(v, b) (((v) >> b) & 1)
42 #define _BF(v, msb, lsb) (((v) >> (lsb)) & \
43 ((1U << ((msb) - (lsb) + 1)) - 1))
44 #define _BFS(v, msb, lsb, lshift) (_BF(v, msb, lsb) << (lshift))
45
46 #define _NFP_ME27_28_CSR_CTX_ENABLES 0x18
47 #define _NFP_ME27_28_CSR_MISC_CONTROL 0x160
48
49 #define _NFP_ISLAND_MAX 64
50 #define _NFP_ME_MAX 12
51
52 typedef struct
53 {
54 unsigned char ctx4_mode:1;
55 unsigned char addr_3rdparty32:1;
56 unsigned char scs_cnt:2;
57 unsigned char _future:4;
58 }
59 nfp_priv_mecfg;
60
61 typedef struct
62 {
63 unsigned char show_pc;
64 unsigned char ctx_mode;
65 }
66 nfp_opts;
67
68 /* mecfgs[island][menum][is-text] */
69 typedef struct
70 {
71 nfp_priv_mecfg mecfgs[_NFP_ISLAND_MAX][_NFP_ME_MAX][2];
72 }
73 nfp_priv_data;
74
75 static const char *nfp_mealu_shf_op[8] =
76 {
77 /* 0b000 (0) */ "B",
78 /* 0b001 (1) */ "~B",
79 /* 0b010 (2) */ "AND",
80 /* 0b011 (3) */ "~AND",
81 /* 0b100 (4) */ "AND~",
82 /* 0b101 (5) */ "OR",
83 /* 0b110 (6) */ "asr",
84 /* 0b111 (7) */ "byte_align"
85 };
86
87 static const char *nfp_me27_28_alu_op[32] =
88 {
89 /* 0b00000 (0) */ "B",
90 /* 0b00001 (1) */ "+",
91 NULL,
92 /* 0b00011 (3) */ "pop_count3",
93 /* 0b00100 (4) */ "~B",
94 /* 0b00101 (5) */ "+16",
95 /* 0b00110 (6) */ "pop_count1",
96 /* 0b00111 (7) */ "pop_count2",
97 /* 0b01000 (8) */ "AND",
98 /* 0b01001 (9) */ "+8",
99 NULL,
100 /* 0b01011 (11) */ "cam_clear",
101 /* 0b01100 (12) */ "~AND",
102 /* 0b01101 (13) */ "-carry",
103 /* 0b01110 (14) */ "ffs",
104 /* 0b01111 (15) */ "cam_read_tag",
105 /* 0b10000 (16) */ "AND~",
106 /* 0b10001 (17) */ "+carry",
107 /* 0b10010 (18) */ "CRC",
108 /* 0b10011 (19) */ "cam_write",
109 /* 0b10100 (20) */ "OR",
110 /* 0b10101 (21) */ "-",
111 NULL,
112 /* 0b10111 (23) */ "cam_lookup",
113 /* 0b11000 (24) */ "XOR",
114 /* 0b11001 (25) */ "B-A",
115 NULL,
116 /* 0b11011 (27) */ "cam_write_state",
117 NULL,
118 NULL,
119 NULL,
120 /* 0b11111 (31) */ "cam_read_state"
121 };
122
123 static const char *nfp_me27_28_crc_op[8] =
124 {
125 /* 0b000 (0) */ "--",
126 NULL,
127 /* 0b010 (2) */ "crc_ccitt",
128 NULL,
129 /* 0b100 (4) */ "crc_32",
130 /* 0b101 (5) */ "crc_iscsi",
131 /* 0b110 (6) */ "crc_10",
132 /* 0b111 (7) */ "crc_5"
133 };
134
135 static const char *nfp_me27_28_crc_bytes[8] =
136 {
137 /* 0b000 (0) */ "bytes_0_3",
138 /* 0b001 (1) */ "bytes_1_3",
139 /* 0b010 (2) */ "bytes_2_3",
140 /* 0b011 (3) */ "byte_3",
141 /* 0b100 (4) */ "bytes_0_2",
142 /* 0b101 (5) */ "bytes_0_1",
143 /* 0b110 (6) */ "byte_0"
144 };
145
146 static const char *nfp_me27_28_mecsrs[] =
147 {
148 /* 0x000 (0) */ "UstorAddr",
149 /* 0x004 (1) */ "UstorDataLwr",
150 /* 0x008 (2) */ "UstorDataUpr",
151 /* 0x00c (3) */ "UstorErrStat",
152 /* 0x010 (4) */ "ALUOut",
153 /* 0x014 (5) */ "CtxArbCtrl",
154 /* 0x018 (6) */ "CtxEnables",
155 /* 0x01c (7) */ "CondCodeEn",
156 /* 0x020 (8) */ "CSRCtxPtr",
157 /* 0x024 (9) */ "PcBreakpoint0",
158 /* 0x028 (10) */ "PcBreakpoint1",
159 /* 0x02c (11) */ "PcBreakpointStatus",
160 /* 0x030 (12) */ "RegErrStatus",
161 /* 0x034 (13) */ "LMErrStatus",
162 /* 0x038 (14) */ "LMeccErrorMask",
163 NULL,
164 /* 0x040 (16) */ "IndCtxStatus",
165 /* 0x044 (17) */ "ActCtxStatus",
166 /* 0x048 (18) */ "IndCtxSglEvt",
167 /* 0x04c (19) */ "ActCtxSglEvt",
168 /* 0x050 (20) */ "IndCtxWkpEvt",
169 /* 0x054 (21) */ "ActCtxWkpEvt",
170 /* 0x058 (22) */ "IndCtxFtrCnt",
171 /* 0x05c (23) */ "ActCtxFtrCnt",
172 /* 0x060 (24) */ "IndLMAddr0",
173 /* 0x064 (25) */ "ActLMAddr0",
174 /* 0x068 (26) */ "IndLMAddr1",
175 /* 0x06c (27) */ "ActLMAddr1",
176 /* 0x070 (28) */ "ByteIndex",
177 /* 0x074 (29) */ "XferIndex",
178 /* 0x078 (30) */ "IndFtrCntSgl",
179 /* 0x07c (31) */ "ActFtrCntSgl",
180 /* 0x080 (32) */ "NNPut",
181 /* 0x084 (33) */ "NNGet",
182 NULL,
183 NULL,
184 /* 0x090 (36) */ "IndLMAddr2",
185 /* 0x094 (37) */ "ActLMAddr2",
186 /* 0x098 (38) */ "IndLMAddr3",
187 /* 0x09c (39) */ "ActLMAddr3",
188 /* 0x0a0 (40) */ "IndLMAddr2BytIdx",
189 /* 0x0a4 (41) */ "ActLMAddr2BytIdx",
190 /* 0x0a8 (42) */ "IndLMAddr3BytIdx",
191 /* 0x0ac (43) */ "ActLMAddr3BytIdx",
192 /* 0x0b0 (44) */ "IndPredCC",
193 NULL,
194 NULL,
195 NULL,
196 /* 0x0c0 (48) */ "TimestampLow",
197 /* 0x0c4 (49) */ "TimestampHgh",
198 NULL,
199 NULL,
200 NULL,
201 NULL,
202 NULL,
203 NULL,
204 /* 0x0e0 (56) */ "IndLMAddr0BytIdx",
205 /* 0x0e4 (57) */ "ActLMAddr0BytIdx",
206 /* 0x0e8 (58) */ "IndLMAddr1BytIdx",
207 /* 0x0ec (59) */ "ActLMAddr1BytIdx",
208 NULL,
209 /* 0x0f4 (61) */ "XfrAndBytIdx",
210 NULL,
211 NULL,
212 /* 0x100 (64) */ "NxtNghbrSgl",
213 /* 0x104 (65) */ "PrvNghbrSgl",
214 /* 0x108 (66) */ "SameMESignal",
215 NULL,
216 NULL,
217 NULL,
218 NULL,
219 NULL,
220 NULL,
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 NULL,
226 NULL,
227 NULL,
228 /* 0x140 (80) */ "CRCRemainder",
229 /* 0x144 (81) */ "ProfileCnt",
230 /* 0x148 (82) */ "PseudoRndNum",
231 NULL,
232 NULL,
233 NULL,
234 NULL,
235 NULL,
236 /* 0x160 (88) */ "MiscControl",
237 /* 0x164 (89) */ "PcBreakpoint0Mask",
238 /* 0x168 (90) */ "PcBreakpoint1Mask",
239 NULL,
240 /* 0x170 (92) */ "Mailbox0",
241 /* 0x174 (93) */ "Mailbox1",
242 /* 0x178 (94) */ "Mailbox2",
243 /* 0x17c (95) */ "Mailbox3",
244 NULL,
245 NULL,
246 NULL,
247 NULL,
248 /* 0x190 (100) */ "CmdIndirectRef0"
249 };
250
251 const char *nfp_me27_28_br_ops[32] =
252 {
253 /* 0b00000 (0) */ "beq",
254 /* 0b00001 (1) */ "bne",
255 /* 0b00010 (2) */ "bmi",
256 /* 0b00011 (3) */ "bpl",
257 /* 0b00100 (4) */ "bcs",
258 /* 0b00101 (5) */ "bcc",
259 /* 0b00110 (6) */ "bvs",
260 /* 0b00111 (7) */ "bvc",
261 /* 0b01000 (8) */ "bge",
262 /* 0b01001 (9) */ "blt",
263 /* 0b01010 (10) */ "ble",
264 /* 0b01011 (11) */ "bgt",
265 /* (12) */ NULL,
266 /* (13) */ NULL,
267 /* (14) */ NULL,
268 /* (15) */ NULL,
269 /* 0b10000 (16) */ "br=ctx",
270 /* 0b10001 (17) */ "br!=ctx",
271 /* 0b10010 (18) */ "br_signal",
272 /* 0b10011 (19) */ "br_!signal",
273 /* 0b10100 (20) */ "br_inp_state",
274 /* 0b10101 (21) */ "br_!inp_state",
275 /* 0b10110 (22) */ "br_cls_state",
276 /* 0b10111 (23) */ "br_!cls_state",
277 /* 0b11000 (24) */ "br",
278 /* (25) */ NULL,
279 /* (26) */ NULL,
280 /* (27) */ NULL,
281 /* (28) */ NULL,
282 /* (29) */ NULL,
283 /* (30) */ NULL,
284 /* (31) */ NULL
285 };
286
287 static const char *nfp_me27_br_inpstates[16] =
288 {
289 /* 0 */ "nn_empty",
290 /* 1 */ "nn_full",
291 /* 2 */ "scr_ring0_status",
292 /* 3 */ "scr_ring1_status",
293 /* 4 */ "scr_ring2_status",
294 /* 5 */ "scr_ring3_status",
295 /* 6 */ "scr_ring4_status",
296 /* 7 */ "scr_ring5_status",
297 /* 8 */ "scr_ring6_status",
298 /* 9 */ "scr_ring7_status",
299 /* 10 */ "scr_ring8_status",
300 /* 11 */ "scr_ring9_status",
301 /* 12 */ "scr_ring10_status",
302 /* 13 */ "scr_ring11_status",
303 /* 14 */ "fci_not_empty",
304 /* 15 */ "fci_full"
305 };
306
307 static const char *nfp_me28_br_inpstates[16] =
308 {
309 /* 0 */ "nn_empty",
310 /* 1 */ "nn_full",
311 /* 2 */ "ctm_ring0_status",
312 /* 3 */ "ctm_ring1_status",
313 /* 4 */ "ctm_ring2_status",
314 /* 5 */ "ctm_ring3_status",
315 /* 6 */ "ctm_ring4_status",
316 /* 7 */ "ctm_ring5_status",
317 /* 8 */ "ctm_ring6_status",
318 /* 9 */ "ctm_ring7_status",
319 /* 10 */ "ctm_ring8_status",
320 /* 11 */ "ctm_ring9_status",
321 /* 12 */ "ctm_ring10_status",
322 /* 13 */ "ctm_ring11_status",
323 /* 14 */ "ctm_ring12_status",
324 /* 15 */ "ctm_ring13_status"
325 };
326
327 static const char *nfp_me27_28_mult_steps[8] =
328 {
329 /* 0 */ "step1",
330 /* 1 */ "step2",
331 /* 2 */ "step3",
332 /* 3 */ "step4",
333 /* 4 */ "last",
334 /* 5 */ "last2",
335 NULL,
336 NULL
337 };
338
339 static const char *nfp_me27_28_mult_types[4] =
340 {
341 "start",
342 "24x8",
343 "16x16",
344 "32x32"
345 };
346
347 /* The cmd_mnemonics arrays are sorted here in its definition so that we can
348 use bsearch () on the first three fields. There can be multiple matches
349 and we assume that bsearch can return any of them, so we manually step
350 back to the first one. */
351
352 static const nfp_cmd_mnemonic nfp_me27_mnemonics[] =
353 {
354 {NFP_3200_CPPTGT_MSF0, 0, 0, 0, 0, "read"},
355 {NFP_3200_CPPTGT_MSF0, 0, 2, 0, 0, "read64"},
356 {NFP_3200_CPPTGT_MSF0, 1, 0, 0, 0, "write"},
357 {NFP_3200_CPPTGT_MSF0, 1, 1, 0, 0, "fast_wr"},
358 {NFP_3200_CPPTGT_MSF0, 1, 2, 0, 0, "write64"},
359 {NFP_3200_CPPTGT_QDR, 0, 0, 0, 0, "read"},
360 {NFP_3200_CPPTGT_QDR, 1, 0, 0, 0, "write"},
361 {NFP_3200_CPPTGT_QDR, 2, 0, 0, 0, "write_atomic"},
362 {NFP_3200_CPPTGT_QDR, 2, 1, 0, 0, "swap"},
363 {NFP_3200_CPPTGT_QDR, 3, 0, 0, 0, "set"},
364 {NFP_3200_CPPTGT_QDR, 3, 1, 0, 0, "test_and_set"},
365 {NFP_3200_CPPTGT_QDR, 4, 0, 0, 0, "clr"},
366 {NFP_3200_CPPTGT_QDR, 4, 1, 0, 0, "test_and_clr"},
367 {NFP_3200_CPPTGT_QDR, 5, 0, 0, 0, "add"},
368 {NFP_3200_CPPTGT_QDR, 5, 1, 0, 0, "test_and_add"},
369 {NFP_3200_CPPTGT_QDR, 6, 0, 0, 0, "read_queue"},
370 {NFP_3200_CPPTGT_QDR, 6, 1, 0, 0, "read_queue_ring"},
371 {NFP_3200_CPPTGT_QDR, 6, 2, 0, 0, "write_queue"},
372 {NFP_3200_CPPTGT_QDR, 6, 3, 0, 0, "write_queue_ring"},
373 {NFP_3200_CPPTGT_QDR, 7, 0, 0, 0, "incr"},
374 {NFP_3200_CPPTGT_QDR, 7, 1, 0, 0, "test_and_incr"},
375 {NFP_3200_CPPTGT_QDR, 8, 0, 0, 0, "decr"},
376 {NFP_3200_CPPTGT_QDR, 8, 1, 0, 0, "test_and_decr"},
377 {NFP_3200_CPPTGT_QDR, 9, 0, 0, 0, "put"},
378 {NFP_3200_CPPTGT_QDR, 9, 1, 0, 0, "get"},
379 {NFP_3200_CPPTGT_QDR, 9, 2, 0, 0, "put_imm"},
380 {NFP_3200_CPPTGT_QDR, 9, 3, 0, 0, "pop"},
381 {NFP_3200_CPPTGT_QDR, 10, 0, 0, 0, "journal"},
382 {NFP_3200_CPPTGT_QDR, 10, 1, 0, 0, "fast_journal"},
383 {NFP_3200_CPPTGT_QDR, 11, 0, 0, 0, "dequeue"},
384 {NFP_3200_CPPTGT_QDR, 12, 0, 0, 0, "enqueue"},
385 {NFP_3200_CPPTGT_QDR, 12, 1, 0, 0, "enueue_tail"},
386 {NFP_3200_CPPTGT_QDR, 12, 2, 0, 0, "nfp_enqueue"},
387 {NFP_3200_CPPTGT_QDR, 12, 3, 0, 0, "nfp_enueue_tail"},
388 {NFP_3200_CPPTGT_QDR, 13, 0, 0, 0, "csr_wr"},
389 {NFP_3200_CPPTGT_QDR, 13, 1, 0, 0, "csr_rd"},
390 {NFP_3200_CPPTGT_QDR, 14, 0, 0, 0, "wr_qdesc"},
391 {NFP_3200_CPPTGT_QDR, 14, 1, 0, 0, "nfp_wr_qdesc"},
392 {NFP_3200_CPPTGT_QDR, 14, 2, 0, 0, "wr_qdesc_count"},
393 {NFP_3200_CPPTGT_QDR, 14, 3, 0, 0, "push_qdesc"},
394 {NFP_3200_CPPTGT_QDR, 15, 0, 0, 0, "rd_qdesc_other"},
395 {NFP_3200_CPPTGT_QDR, 15, 1, 0, 0, "rd_qdesc_tail"},
396 {NFP_3200_CPPTGT_QDR, 15, 2, 0, 0, "rd_qdesc_head"},
397 {NFP_3200_CPPTGT_QDR, 15, 3, 0, 0, "nfp_rd_qdesc"},
398 {NFP_3200_CPPTGT_MSF1, 0, 0, 0, 0, "read"},
399 {NFP_3200_CPPTGT_MSF1, 0, 2, 0, 0, "read64"},
400 {NFP_3200_CPPTGT_MSF1, 1, 0, 0, 0, "write"},
401 {NFP_3200_CPPTGT_MSF1, 1, 1, 0, 0, "fast_wr"},
402 {NFP_3200_CPPTGT_MSF1, 1, 2, 0, 0, "write64"},
403 {NFP_3200_CPPTGT_HASH, 0, 0, 0, 0, "hash_48"},
404 {NFP_3200_CPPTGT_HASH, 0, 1, 0, 0, "hash_64"},
405 {NFP_3200_CPPTGT_HASH, 0, 2, 0, 0, "hash_128"},
406 {NFP_3200_CPPTGT_MU, 0, 0, 0, 0, "read"},
407 {NFP_3200_CPPTGT_MU, 0, 1, 0, 0, "read_le"},
408 {NFP_3200_CPPTGT_MU, 0, 2, 0, 0, "read_swap"},
409 {NFP_3200_CPPTGT_MU, 0, 3, 0, 0, "read_swap_le"},
410 {NFP_3200_CPPTGT_MU, 1, 0, 0, 0, "write"},
411 {NFP_3200_CPPTGT_MU, 1, 1, 0, 0, "write_le"},
412 {NFP_3200_CPPTGT_MU, 1, 2, 0, 0, "write_swap"},
413 {NFP_3200_CPPTGT_MU, 1, 3, 0, 0, "write_swap_le"},
414 {NFP_3200_CPPTGT_MU, 2, 0, 0, 0, "write8"},
415 {NFP_3200_CPPTGT_MU, 2, 1, 0, 0, "write8_le"},
416 {NFP_3200_CPPTGT_MU, 2, 2, 0, 0, "write8_swap"},
417 {NFP_3200_CPPTGT_MU, 2, 3, 0, 0, "write8_swap_le"},
418 {NFP_3200_CPPTGT_MU, 3, 0, 0, 0, "read_atomic"},
419 {NFP_3200_CPPTGT_MU, 3, 1, 0, 0, "read8"},
420 {NFP_3200_CPPTGT_MU, 3, 2, 0, 0, "compare_write"},
421 {NFP_3200_CPPTGT_MU, 3, 3, 0, 0, "test_and_compare_write"},
422 {NFP_3200_CPPTGT_MU, 4, 0, 0, 0, "write_atomic"},
423 {NFP_3200_CPPTGT_MU, 4, 1, 0, 0, "swap"},
424 {NFP_3200_CPPTGT_MU, 4, 2, 0, 0, "write_atomic_imm"},
425 {NFP_3200_CPPTGT_MU, 4, 3, 0, 0, "swap_imm"},
426 {NFP_3200_CPPTGT_MU, 5, 0, 0, 0, "set"},
427 {NFP_3200_CPPTGT_MU, 5, 1, 0, 0, "test_and_set"},
428 {NFP_3200_CPPTGT_MU, 5, 2, 0, 0, "set_imm"},
429 {NFP_3200_CPPTGT_MU, 5, 3, 0, 0, "test_and_set_imm"},
430 {NFP_3200_CPPTGT_MU, 6, 0, 0, 0, "clr"},
431 {NFP_3200_CPPTGT_MU, 6, 1, 0, 0, "test_and_clr"},
432 {NFP_3200_CPPTGT_MU, 6, 2, 0, 0, "clr_imm"},
433 {NFP_3200_CPPTGT_MU, 6, 3, 0, 0, "test_and_clr_imm"},
434 {NFP_3200_CPPTGT_MU, 7, 0, 0, 4, "add"},
435 {NFP_3200_CPPTGT_MU, 7, 0, 4, 4, "add64"},
436 {NFP_3200_CPPTGT_MU, 7, 1, 0, 4, "test_and_add"},
437 {NFP_3200_CPPTGT_MU, 7, 1, 4, 4, "test_and_add64"},
438 {NFP_3200_CPPTGT_MU, 7, 2, 0, 4, "add_imm"},
439 {NFP_3200_CPPTGT_MU, 7, 2, 4, 4, "add64_imm"},
440 {NFP_3200_CPPTGT_MU, 7, 3, 0, 4, "test_and_add_imm"},
441 {NFP_3200_CPPTGT_MU, 7, 3, 4, 4, "test_and_add64_imm"},
442 {NFP_3200_CPPTGT_MU, 8, 0, 0, 4, "add_sat"},
443 {NFP_3200_CPPTGT_MU, 8, 0, 4, 4, "add64_sat"},
444 {NFP_3200_CPPTGT_MU, 8, 1, 0, 4, "test_and_add_sat"},
445 {NFP_3200_CPPTGT_MU, 8, 1, 4, 4, "test_and_add64_sat"},
446 {NFP_3200_CPPTGT_MU, 8, 2, 0, 4, "add_imm_sat"},
447 {NFP_3200_CPPTGT_MU, 8, 2, 4, 4, "add_imm_sat"},
448 {NFP_3200_CPPTGT_MU, 8, 3, 0, 0, "test_and_add_sat_imm"},
449 {NFP_3200_CPPTGT_MU, 9, 0, 0, 4, "sub"},
450 {NFP_3200_CPPTGT_MU, 9, 0, 4, 4, "sub64"},
451 {NFP_3200_CPPTGT_MU, 9, 1, 0, 4, "test_and_sub"},
452 {NFP_3200_CPPTGT_MU, 9, 1, 4, 4, "test_and_sub64"},
453 {NFP_3200_CPPTGT_MU, 9, 2, 0, 4, "sub_imm"},
454 {NFP_3200_CPPTGT_MU, 9, 2, 4, 4, "sub64_imm"},
455 {NFP_3200_CPPTGT_MU, 9, 3, 0, 0, "tes_and_sub_imm"},
456 {NFP_3200_CPPTGT_MU, 10, 0, 0, 4, "sub_sat"},
457 {NFP_3200_CPPTGT_MU, 10, 0, 4, 4, "sub64_sat"},
458 {NFP_3200_CPPTGT_MU, 10, 1, 0, 4, "test_and_sub_sat"},
459 {NFP_3200_CPPTGT_MU, 10, 1, 4, 4, "test_and_sub64_sat"},
460 {NFP_3200_CPPTGT_MU, 10, 2, 0, 4, "sub_imm_sat"},
461 {NFP_3200_CPPTGT_MU, 10, 2, 4, 4, "sub64_imm_sat"},
462 {NFP_3200_CPPTGT_MU, 10, 3, 0, 0, "test_and_sub_sat_imm"},
463 {NFP_3200_CPPTGT_MU, 11, 0, 0, 0, "release_ticket"},
464 {NFP_3200_CPPTGT_MU, 11, 1, 0, 0, "release_ticket_ind"},
465 {NFP_3200_CPPTGT_MU, 12, 0, 0, 0, "cam_lookup"},
466 {NFP_3200_CPPTGT_MU, 12, 1, 0, 0, "cam_lookup_add"},
467 {NFP_3200_CPPTGT_MU, 12, 2, 0, 0, "tcam_lookup"},
468 {NFP_3200_CPPTGT_MU, 12, 3, 0, 3, "lock"},
469 {NFP_3200_CPPTGT_MU, 12, 3, 2, 3, "cam_lookup_add_inc"},
470 {NFP_3200_CPPTGT_MU, 13, 0, 0, 4, "microq128_get"},
471 {NFP_3200_CPPTGT_MU, 13, 0, 4, 4, "microq256_get"},
472 {NFP_3200_CPPTGT_MU, 13, 1, 0, 4, "microq128_pop"},
473 {NFP_3200_CPPTGT_MU, 13, 1, 4, 4, "microq256_pop"},
474 {NFP_3200_CPPTGT_MU, 13, 2, 0, 4, "microq128_put"},
475 {NFP_3200_CPPTGT_MU, 13, 2, 4, 4, "microq256_put"},
476 {NFP_3200_CPPTGT_MU, 14, 0, 0, 4, "queue128_lock"},
477 {NFP_3200_CPPTGT_MU, 14, 0, 4, 4, "queue256_lock"},
478 {NFP_3200_CPPTGT_MU, 14, 1, 0, 4, "queue128_unlock"},
479 {NFP_3200_CPPTGT_MU, 14, 1, 4, 4, "queue256_unlock"},
480 {NFP_3200_CPPTGT_MU, 15, 0, 0, 0, "xor"},
481 {NFP_3200_CPPTGT_MU, 15, 1, 0, 0, "test_and_xor"},
482 {NFP_3200_CPPTGT_MU, 15, 2, 0, 0, "xor_imm"},
483 {NFP_3200_CPPTGT_MU, 15, 3, 0, 0, "test_and_xor_imm"},
484 {NFP_3200_CPPTGT_MU, 16, 0, 0, 0, "rd_qdesc"},
485 {NFP_3200_CPPTGT_MU, 16, 1, 0, 0, "wr_qdesc"},
486 {NFP_3200_CPPTGT_MU, 16, 2, 0, 0, "push_qdesc"},
487 {NFP_3200_CPPTGT_MU, 16, 3, 0, 0, "tag_writeback"},
488 {NFP_3200_CPPTGT_MU, 17, 0, 0, 0, "enqueue"},
489 {NFP_3200_CPPTGT_MU, 17, 1, 0, 0, "enqueue_tail"},
490 {NFP_3200_CPPTGT_MU, 17, 2, 0, 0, "dequeue"},
491 {NFP_3200_CPPTGT_MU, 18, 0, 0, 0, "read_queue"},
492 {NFP_3200_CPPTGT_MU, 18, 1, 0, 0, "read_queue_ring"},
493 {NFP_3200_CPPTGT_MU, 18, 2, 0, 0, "write_queue"},
494 {NFP_3200_CPPTGT_MU, 18, 3, 0, 0, "write_queue_ring"},
495 {NFP_3200_CPPTGT_MU, 19, 0, 0, 0, "add_tail"},
496 {NFP_3200_CPPTGT_MU, 19, 1, 0, 0, "qadd_thread"},
497 {NFP_3200_CPPTGT_MU, 19, 2, 0, 0, "qadd_work"},
498 {NFP_3200_CPPTGT_MU, 19, 3, 0, 0, "qadd_work_imm"},
499 {NFP_3200_CPPTGT_MU, 20, 0, 0, 0, "put"},
500 {NFP_3200_CPPTGT_MU, 20, 1, 0, 0, "put_tag"},
501 {NFP_3200_CPPTGT_MU, 20, 2, 0, 0, "journal"},
502 {NFP_3200_CPPTGT_MU, 20, 3, 0, 0, "journal_tag"},
503 {NFP_3200_CPPTGT_MU, 21, 0, 0, 0, "get"},
504 {NFP_3200_CPPTGT_MU, 21, 1, 0, 0, "get_eop"},
505 {NFP_3200_CPPTGT_MU, 21, 2, 0, 0, "get_safe"},
506 {NFP_3200_CPPTGT_MU, 21, 3, 0, 0, "get_tag_safe"},
507 {NFP_3200_CPPTGT_MU, 22, 0, 0, 0, "pop"},
508 {NFP_3200_CPPTGT_MU, 22, 1, 0, 0, "pop_eop"},
509 {NFP_3200_CPPTGT_MU, 22, 2, 0, 0, "pop_safe"},
510 {NFP_3200_CPPTGT_MU, 22, 3, 0, 0, "pop_tag_safe"},
511 {NFP_3200_CPPTGT_MU, 23, 0, 0, 0, "fast_journal"},
512 {NFP_3200_CPPTGT_MU, 23, 1, 0, 0, "fast_journal_sig"},
513 {NFP_3200_CPPTGT_GS, 0, 0, 0, 0, "read"},
514 {NFP_3200_CPPTGT_GS, 1, 0, 0, 0, "write"},
515 {NFP_3200_CPPTGT_GS, 2, 0, 0, 0, "write_atomic"},
516 {NFP_3200_CPPTGT_GS, 2, 1, 0, 0, "swap"},
517 {NFP_3200_CPPTGT_GS, 3, 0, 0, 0, "set"},
518 {NFP_3200_CPPTGT_GS, 3, 1, 0, 0, "test_and_set"},
519 {NFP_3200_CPPTGT_GS, 4, 0, 0, 0, "clr"},
520 {NFP_3200_CPPTGT_GS, 4, 1, 0, 0, "test_and_clr"},
521 {NFP_3200_CPPTGT_GS, 5, 0, 0, 0, "add"},
522 {NFP_3200_CPPTGT_GS, 5, 1, 0, 0, "test_and_add"},
523 {NFP_3200_CPPTGT_GS, 6, 0, 0, 0, "sub"},
524 {NFP_3200_CPPTGT_GS, 6, 1, 0, 0, "test_and_sub"},
525 {NFP_3200_CPPTGT_GS, 7, 0, 0, 0, "inc"},
526 {NFP_3200_CPPTGT_GS, 7, 1, 0, 0, "test_and_inc"},
527 {NFP_3200_CPPTGT_GS, 8, 0, 0, 0, "dec"},
528 {NFP_3200_CPPTGT_GS, 8, 1, 0, 0, "test_and_dec"},
529 {NFP_3200_CPPTGT_GS, 9, 0, 0, 0, "get"},
530 {NFP_3200_CPPTGT_GS, 10, 0, 0, 0, "put"},
531 {NFP_3200_CPPTGT_PCIE, 0, 0, 0, 0, "read"},
532 {NFP_3200_CPPTGT_PCIE, 1, 0, 0, 0, "write"},
533 {NFP_3200_CPPTGT_PCIE, 2, 0, 0, 0, "read_internal"},
534 {NFP_3200_CPPTGT_PCIE, 3, 0, 0, 0, "write_internal"},
535 {NFP_3200_CPPTGT_ARM, 0, 0, 0, 0, "read"},
536 {NFP_3200_CPPTGT_ARM, 1, 0, 0, 0, "write"},
537 {NFP_3200_CPPTGT_CRYPTO, 0, 0, 0, 0, "read"},
538 {NFP_3200_CPPTGT_CRYPTO, 1, 0, 0, 0, "write"},
539 {NFP_3200_CPPTGT_CRYPTO, 2, 0, 0, 0, "write_fifo"},
540 {NFP_3200_CPPTGT_CAP, 0, 0, 0, 0, "read_enum"},
541 {NFP_3200_CPPTGT_CAP, 0, 1, 0, 0, "read"},
542 {NFP_3200_CPPTGT_CAP, 0, 2, 0, 0, "read_reflect"},
543 {NFP_3200_CPPTGT_CAP, 1, 0, 0, 0, "write_enum"},
544 {NFP_3200_CPPTGT_CAP, 1, 1, 0, 0, "write"},
545 {NFP_3200_CPPTGT_CAP, 1, 2, 0, 0, "write_reflect"},
546 {NFP_3200_CPPTGT_CAP, 2, 0, 0, 0, "fast_wr_alu"},
547 {NFP_3200_CPPTGT_CAP, 3, 0, 0, 0, "fast_wr"},
548 {NFP_3200_CPPTGT_CT, 1, 0, 0, 0, "write"},
549 {NFP_3200_CPPTGT_CLS, 0, 0, 0, 0, "read_be"},
550 {NFP_3200_CPPTGT_CLS, 0, 1, 0, 0, "read_le"},
551 {NFP_3200_CPPTGT_CLS, 0, 2, 0, 0, "test_and_compare_write"},
552 {NFP_3200_CPPTGT_CLS, 0, 3, 0, 0, "xor"},
553 {NFP_3200_CPPTGT_CLS, 1, 0, 0, 0, "write_be"},
554 {NFP_3200_CPPTGT_CLS, 1, 1, 0, 0, "write_le"},
555 {NFP_3200_CPPTGT_CLS, 1, 2, 0, 0, "write8_be"},
556 {NFP_3200_CPPTGT_CLS, 1, 3, 0, 0, "write8_le"},
557 {NFP_3200_CPPTGT_CLS, 2, 0, 0, 0, "set"},
558 {NFP_3200_CPPTGT_CLS, 2, 1, 0, 0, "clr"},
559 {NFP_3200_CPPTGT_CLS, 2, 2, 0, 0, "test_and_set"},
560 {NFP_3200_CPPTGT_CLS, 2, 3, 0, 0, "test_and_clr"},
561 {NFP_3200_CPPTGT_CLS, 3, 0, 0, 0, "set_imm"},
562 {NFP_3200_CPPTGT_CLS, 3, 1, 0, 0, "clr_imm"},
563 {NFP_3200_CPPTGT_CLS, 3, 2, 0, 0, "test_and_set_imm"},
564 {NFP_3200_CPPTGT_CLS, 3, 3, 0, 0, "test_and_clr_imm"},
565 {NFP_3200_CPPTGT_CLS, 4, 0, 0, 0, "add"},
566 {NFP_3200_CPPTGT_CLS, 4, 1, 0, 0, "add64"},
567 {NFP_3200_CPPTGT_CLS, 4, 2, 0, 0, "add_sat"},
568 {NFP_3200_CPPTGT_CLS, 4, 3, 0, 0, "test_and_add_sat"},
569 {NFP_3200_CPPTGT_CLS, 5, 0, 0, 0, "add_imm"},
570 {NFP_3200_CPPTGT_CLS, 5, 1, 0, 0, "add64_imm"},
571 {NFP_3200_CPPTGT_CLS, 5, 2, 0, 0, "add_imm_sat"},
572 {NFP_3200_CPPTGT_CLS, 5, 3, 0, 0, "test_and_add_imm_sat"},
573 {NFP_3200_CPPTGT_CLS, 6, 0, 0, 0, "sub"},
574 {NFP_3200_CPPTGT_CLS, 6, 1, 0, 0, "sub64"},
575 {NFP_3200_CPPTGT_CLS, 6, 2, 0, 0, "sub_sat"},
576 {NFP_3200_CPPTGT_CLS, 6, 3, 0, 0, "test_and_sub_sat"},
577 {NFP_3200_CPPTGT_CLS, 7, 0, 0, 0, "sub_imm"},
578 {NFP_3200_CPPTGT_CLS, 7, 1, 0, 0, "sub64_imm"},
579 {NFP_3200_CPPTGT_CLS, 7, 2, 0, 0, "sub_imm_sat"},
580 {NFP_3200_CPPTGT_CLS, 7, 3, 0, 0, "test_and_sub_imm_sat"},
581 {NFP_3200_CPPTGT_CLS, 8, 0, 0, 0, "queue_lock"},
582 {NFP_3200_CPPTGT_CLS, 8, 1, 0, 0, "queue_unlock"},
583 {NFP_3200_CPPTGT_CLS, 8, 2, 0, 0, "hash_mask"},
584 {NFP_3200_CPPTGT_CLS, 8, 3, 0, 0, "hash_mask_clear"},
585 {NFP_3200_CPPTGT_CLS, 9, 0, 0, 0, "get"},
586 {NFP_3200_CPPTGT_CLS, 9, 1, 0, 0, "pop"},
587 {NFP_3200_CPPTGT_CLS, 9, 2, 0, 0, "get_safe"},
588 {NFP_3200_CPPTGT_CLS, 9, 3, 0, 0, "pop_safe"},
589 {NFP_3200_CPPTGT_CLS, 10, 0, 0, 0, "put"},
590 {NFP_3200_CPPTGT_CLS, 10, 1, 0, 0, "put_offset"},
591 {NFP_3200_CPPTGT_CLS, 10, 2, 0, 0, "journal"},
592 {NFP_3200_CPPTGT_CLS, 10, 3, 0, 0, "add_tail"},
593 {NFP_3200_CPPTGT_CLS, 11, 0, 0, 0, "cam_lookup32"},
594 {NFP_3200_CPPTGT_CLS, 11, 1, 0, 0, "cam_lookup32_add"},
595 {NFP_3200_CPPTGT_CLS, 11, 2, 0, 0, "cam_lookup24"},
596 {NFP_3200_CPPTGT_CLS, 11, 3, 0, 0, "cam_lookup24_add"},
597 {NFP_3200_CPPTGT_CLS, 12, 0, 0, 0, "cam_lookup8"},
598 {NFP_3200_CPPTGT_CLS, 12, 1, 0, 0, "cam_lookup8_add"},
599 {NFP_3200_CPPTGT_CLS, 12, 2, 0, 0, "cam_lookup16"},
600 {NFP_3200_CPPTGT_CLS, 12, 3, 0, 0, "cam_lookup16_add"},
601 {NFP_3200_CPPTGT_CLS, 13, 0, 0, 0, "tcam_lookup32"},
602 {NFP_3200_CPPTGT_CLS, 13, 1, 0, 0, "tcam_lookup24"},
603 {NFP_3200_CPPTGT_CLS, 13, 2, 0, 0, "tcam_lookup16"},
604 {NFP_3200_CPPTGT_CLS, 13, 3, 0, 0, "tcam_lookup8"},
605 {NFP_3200_CPPTGT_CLS, 14, 0, 0, 0, "reflect_from_sig_src"},
606 {NFP_3200_CPPTGT_CLS, 14, 1, 0, 0, "reflect_from_sig_dst"},
607 {NFP_3200_CPPTGT_CLS, 14, 2, 0, 0, "reflect_from_sig_both"},
608 {NFP_3200_CPPTGT_CLS, 15, 0, 0, 0, "reflect_to_sig_src"},
609 {NFP_3200_CPPTGT_CLS, 15, 1, 0, 0, "reflect_to_sig_dst"},
610 {NFP_3200_CPPTGT_CLS, 15, 2, 0, 0, "reflect_to_sig_both"}
611 };
612
613 static const nfp_cmd_mnemonic nfp_me28_mnemonics[] =
614 {
615 {NFP_6000_CPPTGT_NBI, 0, 0, 0, 0, "read"},
616 {NFP_6000_CPPTGT_NBI, 1, 0, 0, 0, "write"},
617 {NFP_6000_CPPTGT_NBI, 3, 0, 0, 0, "packet_ready_drop"},
618 {NFP_6000_CPPTGT_NBI, 3, 1, 0, 0, "packet_ready_unicast"},
619 {NFP_6000_CPPTGT_NBI, 3, 2, 0, 0, "packet_ready_multicast_dont_free"},
620 {NFP_6000_CPPTGT_NBI, 3, 3, 0, 0, "packet_ready_multicast_free_on_last"},
621 {NFP_6000_CPPTGT_ILA, 0, 0, 0, 0, "read"},
622 {NFP_6000_CPPTGT_ILA, 0, 1, 0, 0, "read_check_error"},
623 {NFP_6000_CPPTGT_ILA, 1, 0, 0, 0, "write"},
624 {NFP_6000_CPPTGT_ILA, 1, 1, 0, 0, "write_check_error"},
625 {NFP_6000_CPPTGT_ILA, 2, 0, 0, 0, "read_int"},
626 {NFP_6000_CPPTGT_ILA, 3, 0, 0, 7, "write_int"},
627 {NFP_6000_CPPTGT_ILA, 3, 0, 3, 7, "write_dma"},
628 {NFP_6000_CPPTGT_MU, 0, 0, 0, 0, "read"},
629 {NFP_6000_CPPTGT_MU, 0, 1, 0, 0, "read_le"},
630 {NFP_6000_CPPTGT_MU, 0, 2, 0, 0, "read_swap"},
631 {NFP_6000_CPPTGT_MU, 0, 3, 0, 0, "read_swap_le"},
632 {NFP_6000_CPPTGT_MU, 1, 0, 0, 0, "write"},
633 {NFP_6000_CPPTGT_MU, 1, 1, 0, 0, "write_le"},
634 {NFP_6000_CPPTGT_MU, 1, 2, 0, 0, "write_swap"},
635 {NFP_6000_CPPTGT_MU, 1, 3, 0, 0, "write_swap_le"},
636 {NFP_6000_CPPTGT_MU, 2, 0, 0, 0, "write8"},
637 {NFP_6000_CPPTGT_MU, 2, 1, 0, 0, "write8_le"},
638 {NFP_6000_CPPTGT_MU, 2, 2, 0, 0, "write8_swap"},
639 {NFP_6000_CPPTGT_MU, 2, 3, 0, 0, "write8_swap_le"},
640 {NFP_6000_CPPTGT_MU, 3, 0, 0, 0, "atomic_read"},
641 {NFP_6000_CPPTGT_MU, 3, 1, 0, 0, "read8"},
642 {NFP_6000_CPPTGT_MU, 3, 2, 0, 0,
643 "compare_write_or_incr/mask_compare_write"},
644 {NFP_6000_CPPTGT_MU, 3, 3, 0, 0,
645 "test_compare_write_or_incr/test_mask_compare_write"},
646 {NFP_6000_CPPTGT_MU, 4, 0, 0, 0, "atomic_write"},
647 {NFP_6000_CPPTGT_MU, 4, 1, 0, 0, "swap"},
648 {NFP_6000_CPPTGT_MU, 4, 2, 0, 0, "atomic_write_imm"},
649 {NFP_6000_CPPTGT_MU, 4, 3, 0, 0, "swap_imm"},
650 {NFP_6000_CPPTGT_MU, 5, 0, 0, 0, "set"},
651 {NFP_6000_CPPTGT_MU, 5, 1, 0, 0, "test_set"},
652 {NFP_6000_CPPTGT_MU, 5, 2, 0, 0, "set_imm"},
653 {NFP_6000_CPPTGT_MU, 5, 3, 0, 0, "test_set_imm"},
654 {NFP_6000_CPPTGT_MU, 6, 0, 0, 0, "clr"},
655 {NFP_6000_CPPTGT_MU, 6, 1, 0, 0, "test_clr"},
656 {NFP_6000_CPPTGT_MU, 6, 2, 0, 0, "clr_imm"},
657 {NFP_6000_CPPTGT_MU, 6, 3, 0, 0, "test_clr_imm"},
658 {NFP_6000_CPPTGT_MU, 7, 0, 0, 4, "add"},
659 {NFP_6000_CPPTGT_MU, 7, 0, 4, 4, "add64"},
660 {NFP_6000_CPPTGT_MU, 7, 1, 0, 4, "test_add"},
661 {NFP_6000_CPPTGT_MU, 7, 1, 4, 4, "test_add64"},
662 {NFP_6000_CPPTGT_MU, 7, 2, 0, 4, "add_imm"},
663 {NFP_6000_CPPTGT_MU, 7, 2, 4, 4, "add64_imm"},
664 {NFP_6000_CPPTGT_MU, 7, 3, 0, 4, "test_add_imm"},
665 {NFP_6000_CPPTGT_MU, 7, 3, 4, 4, "test_add64_imm"},
666 {NFP_6000_CPPTGT_MU, 8, 0, 0, 4, "addsat"},
667 {NFP_6000_CPPTGT_MU, 8, 0, 4, 4, "addsat64"},
668 {NFP_6000_CPPTGT_MU, 8, 1, 0, 4, "test_addsat"},
669 {NFP_6000_CPPTGT_MU, 8, 1, 4, 4, "test_addsat64"},
670 {NFP_6000_CPPTGT_MU, 8, 2, 0, 4, "addsat_imm"},
671 {NFP_6000_CPPTGT_MU, 8, 2, 4, 4, "addsat64_imm"},
672 {NFP_6000_CPPTGT_MU, 8, 3, 0, 4, "test_addsat_imm"},
673 {NFP_6000_CPPTGT_MU, 8, 3, 4, 4, "test_addsat64_imm"},
674 {NFP_6000_CPPTGT_MU, 9, 0, 0, 4, "sub"},
675 {NFP_6000_CPPTGT_MU, 9, 0, 4, 4, "sub64"},
676 {NFP_6000_CPPTGT_MU, 9, 1, 0, 4, "test_sub"},
677 {NFP_6000_CPPTGT_MU, 9, 1, 4, 4, "test_sub64"},
678 {NFP_6000_CPPTGT_MU, 9, 2, 0, 4, "sub_imm"},
679 {NFP_6000_CPPTGT_MU, 9, 2, 4, 4, "sub64_imm"},
680 {NFP_6000_CPPTGT_MU, 9, 3, 0, 4, "test_sub_imm"},
681 {NFP_6000_CPPTGT_MU, 9, 3, 4, 4, "test_sub64_imm"},
682 {NFP_6000_CPPTGT_MU, 10, 0, 0, 4, "subsat"},
683 {NFP_6000_CPPTGT_MU, 10, 0, 4, 4, "subsat64"},
684 {NFP_6000_CPPTGT_MU, 10, 1, 0, 4, "test_subsat"},
685 {NFP_6000_CPPTGT_MU, 10, 1, 4, 4, "test_subsat64"},
686 {NFP_6000_CPPTGT_MU, 10, 2, 0, 4, "subsat_imm"},
687 {NFP_6000_CPPTGT_MU, 10, 2, 4, 4, "subsat64_imm"},
688 {NFP_6000_CPPTGT_MU, 10, 3, 0, 4, "test_subsat_imm"},
689 {NFP_6000_CPPTGT_MU, 10, 3, 4, 4, "test_subsat64_imm"},
690 {NFP_6000_CPPTGT_MU, 11, 0, 0, 0, "ticket_release"},
691 {NFP_6000_CPPTGT_MU, 11, 1, 0, 0, "ticket_release_ind"},
692 {NFP_6000_CPPTGT_MU, 12, 0, 0, 7, "cam128_lookup8/cam384_lookup8"},
693 {NFP_6000_CPPTGT_MU, 12, 0, 1, 7, "cam128_lookup16/cam384_lookup16"},
694 {NFP_6000_CPPTGT_MU, 12, 0, 2, 7, "cam128_lookup24/cam384_lookup24"},
695 {NFP_6000_CPPTGT_MU, 12, 0, 3, 7, "cam128_lookup32/cam384_lookup32"},
696 {NFP_6000_CPPTGT_MU, 12, 0, 4, 7, "cam256_lookup8/cam512_lookup8"},
697 {NFP_6000_CPPTGT_MU, 12, 0, 5, 7, "cam256_lookup16/cam512_lookup16"},
698 {NFP_6000_CPPTGT_MU, 12, 0, 6, 7, "cam256_lookup24/cam512_lookup24"},
699 {NFP_6000_CPPTGT_MU, 12, 0, 7, 7, "cam256_lookup32/cam512_lookup32"},
700 {NFP_6000_CPPTGT_MU, 12, 1, 0, 7,
701 "cam128_lookup8_add/cam384_lookup8_add"},
702 {NFP_6000_CPPTGT_MU, 12, 1, 1, 7,
703 "cam128_lookup16_add/cam384_lookup16_add"},
704 {NFP_6000_CPPTGT_MU, 12, 1, 2, 7,
705 "cam128_lookup24_add/cam384_lookup24_add"},
706 {NFP_6000_CPPTGT_MU, 12, 1, 3, 7,
707 "cam128_lookup32_add/cam384_lookup32_add"},
708 {NFP_6000_CPPTGT_MU, 12, 1, 4, 7,
709 "cam256_lookup8_add/cam512_lookup8_add"},
710 {NFP_6000_CPPTGT_MU, 12, 1, 5, 7,
711 "cam256_lookup16_add/cam512_lookup16_add"},
712 {NFP_6000_CPPTGT_MU, 12, 1, 6, 7,
713 "cam256_lookup24_add/cam512_lookup24_add"},
714 {NFP_6000_CPPTGT_MU, 12, 1, 7, 7,
715 "cam256_lookup32_add/cam512_lookup32_add"},
716 {NFP_6000_CPPTGT_MU, 12, 2, 0, 7, "tcam128_lookup8/tcam384_lookup8"},
717 {NFP_6000_CPPTGT_MU, 12, 2, 1, 7, "tcam128_lookup16/tcam384_lookup16"},
718 {NFP_6000_CPPTGT_MU, 12, 2, 2, 7, "tcam128_lookup24/tcam384_lookup24"},
719 {NFP_6000_CPPTGT_MU, 12, 2, 3, 7, "tcam128_lookup32/tcam384_lookup32"},
720 {NFP_6000_CPPTGT_MU, 12, 2, 4, 7, "tcam256_lookup8/tcam512_lookup8"},
721 {NFP_6000_CPPTGT_MU, 12, 2, 5, 7, "tcam256_lookup16/tcam512_lookup16"},
722 {NFP_6000_CPPTGT_MU, 12, 2, 6, 7, "tcam256_lookup24/tcam512_lookup24"},
723 {NFP_6000_CPPTGT_MU, 12, 2, 7, 7, "tcam256_lookup32/tcam512_lookup32"},
724 {NFP_6000_CPPTGT_MU, 12, 3, 0, 7, "lock128/lock384"},
725 {NFP_6000_CPPTGT_MU, 12, 3, 2, 7,
726 "cam128_lookup24_add_inc/cam384_lookup24_add_inc"},
727 {NFP_6000_CPPTGT_MU, 12, 3, 4, 7, "lock256/lock512"},
728 {NFP_6000_CPPTGT_MU, 12, 3, 6, 7,
729 "cam256_lookup24_add_inc/cam512_lookup24_add_inc"},
730 {NFP_6000_CPPTGT_MU, 13, 0, 0, 7, "microq128_get"},
731 {NFP_6000_CPPTGT_MU, 13, 0, 4, 7, "microq256_get"},
732 {NFP_6000_CPPTGT_MU, 13, 1, 0, 7, "microq128_pop"},
733 {NFP_6000_CPPTGT_MU, 13, 1, 4, 7, "microq256_pop"},
734 {NFP_6000_CPPTGT_MU, 13, 2, 0, 7, "microq128_put"},
735 {NFP_6000_CPPTGT_MU, 13, 2, 4, 7, "microq256_put"},
736 {NFP_6000_CPPTGT_MU, 14, 0, 0, 7, "queue128_lock"},
737 {NFP_6000_CPPTGT_MU, 14, 0, 4, 7, "queue256_lock"},
738 {NFP_6000_CPPTGT_MU, 14, 1, 0, 7, "queue128_unlock"},
739 {NFP_6000_CPPTGT_MU, 14, 1, 4, 7, "queue256_unlock"},
740 {NFP_6000_CPPTGT_MU, 15, 0, 0, 0, "xor"},
741 {NFP_6000_CPPTGT_MU, 15, 1, 0, 0, "test_xor"},
742 {NFP_6000_CPPTGT_MU, 15, 2, 0, 0, "xor_imm"},
743 {NFP_6000_CPPTGT_MU, 15, 3, 0, 0, "test_xor_imm"},
744 {NFP_6000_CPPTGT_MU, 16, 0, 0, 0,
745 "ctm.packet_wait_packet_status/emem.rd_qdesc/imem.stats_log"},
746 {NFP_6000_CPPTGT_MU, 16, 1, 0, 0,
747 "ctm.packet_read_packet_status/emem.wr_qdesc/imem.stats_log_sat"},
748 {NFP_6000_CPPTGT_MU, 16, 2, 0, 0,
749 "emem.push_qdesc/imem.stats_log_event"},
750 {NFP_6000_CPPTGT_MU, 16, 3, 0, 0, "imem.stats_log_sat_event"},
751 {NFP_6000_CPPTGT_MU, 17, 0, 0, 0,
752 "ctm.packet_alloc/emem.enqueue/imem.stats_push"},
753 {NFP_6000_CPPTGT_MU, 17, 1, 0, 0,
754 "ctm.packet_credit_get/emem.enqueue_tail/imem.stats_push_clear"},
755 {NFP_6000_CPPTGT_MU, 17, 2, 0, 0, "ctm.packet_alloc_poll/emem.dequeue"},
756 {NFP_6000_CPPTGT_MU, 17, 3, 0, 0, "ctm.packet_add_thread"},
757 {NFP_6000_CPPTGT_MU, 18, 0, 0, 0,
758 "ctm.packet_free/emem.read_queue/imem.lb_write_desc"},
759 {NFP_6000_CPPTGT_MU, 18, 1, 0, 0,
760 "ctm.packet_free_and_signal/emem.read_queue_ring/imem.lb_read_desc"},
761 {NFP_6000_CPPTGT_MU, 18, 2, 0, 0,
762 "ctm.packet_free_and_return_pointer/emem.write_queue"},
763 {NFP_6000_CPPTGT_MU, 18, 3, 0, 0,
764 "ctm.packet_return_pointer/emem.write_queue_ring"},
765 {NFP_6000_CPPTGT_MU, 19, 0, 0, 0,
766 "ctm.packet_complete_drop/emem.add_tail/imem.lb_write_idtable"},
767 {NFP_6000_CPPTGT_MU, 19, 1, 0, 0,
768 "ctm.packet_complete_unicast/emem.qadd_thread/imem.lb_read_idtable"},
769 {NFP_6000_CPPTGT_MU, 19, 2, 0, 0,
770 "ctm.packet_complete_multicast/emem.qadd_work"},
771 {NFP_6000_CPPTGT_MU, 19, 3, 0, 0,
772 "ctm.packet_complete_multicast_free/emem.qadd_work_imm"},
773 {NFP_6000_CPPTGT_MU, 20, 0, 0, 0,
774 "ctm.pe_dma_to_memory_packet/emem.put/imem.lb_bucket_write_local"},
775 {NFP_6000_CPPTGT_MU, 20, 1, 0, 0,
776 "ctm.pe_dma_to_memory_packet_swap/imem.lb_bucket_write_dcache"},
777 {NFP_6000_CPPTGT_MU, 20, 2, 0, 0,
778 "ctm.pe_dma_to_memory_packet_free/emem.journal"},
779 {NFP_6000_CPPTGT_MU, 20, 3, 0, 0,
780 "ctm.pe_dma_to_memory_packet_free_swap"},
781 {NFP_6000_CPPTGT_MU, 21, 0, 0, 0,
782 "ctm.pe_dma_to_memory_indirect/emem.get/imem.lb_bucket_read_local"},
783 {NFP_6000_CPPTGT_MU, 21, 1, 0, 0,
784 "ctm.pe_dma_to_memory_indirect_swap/emem.get_eop/"
785 "imem.lb_bucket_read_dcache"},
786 {NFP_6000_CPPTGT_MU, 21, 2, 0, 0,
787 "ctm.pe_dma_to_memory_indirect_free/emem.get_freely"},
788 {NFP_6000_CPPTGT_MU, 21, 3, 0, 0,
789 "ctm.pe_dma_to_memory_indirect_free_swap"},
790 {NFP_6000_CPPTGT_MU, 22, 0, 0, 0,
791 "ctm.pe_dma_to_memory_buffer/emem.pop/imem.lb_lookup_bundleid"},
792 {NFP_6000_CPPTGT_MU, 22, 1, 0, 0,
793 "ctm.pe_dma_to_memory_buffer_le/emem.pop_eop/imem.lb_lookup_dcache"},
794 {NFP_6000_CPPTGT_MU, 22, 2, 0, 0,
795 "ctm.pe_dma_to_memory_buffer_swap/emem.pop_freely/imem.lb_lookup_idtable"},
796 {NFP_6000_CPPTGT_MU, 22, 3, 0, 0, "ctm.pe_dma_to_memory_buffer_le_swap"},
797 {NFP_6000_CPPTGT_MU, 23, 0, 0, 0,
798 "ctm.pe_dma_from_memory_buffer/emem.fast_journal/imem.lb_push_stats_local"},
799 {NFP_6000_CPPTGT_MU, 23, 1, 0, 0,
800 "ctm.pe_dma_from_memory_buffer_le/emem.fast_journal_sig/"
801 "imem.lb_push_stats_dcache"},
802 {NFP_6000_CPPTGT_MU, 23, 2, 0, 0,
803 "ctm.pe_dma_from_memory_buffer_swap/imem.lb_push_stats_local_clr"},
804 {NFP_6000_CPPTGT_MU, 23, 3, 0, 0,
805 "ctm.pe_dma_from_memory_buffer_le_swap/imem.lb_push_stats_dcache_clr"},
806 {NFP_6000_CPPTGT_MU, 26, 0, 0, 0, "emem.lookup/imem.lookup"},
807 {NFP_6000_CPPTGT_MU, 28, 0, 0, 0, "read32"},
808 {NFP_6000_CPPTGT_MU, 28, 1, 0, 0, "read32_le"},
809 {NFP_6000_CPPTGT_MU, 28, 2, 0, 0, "read32_swap"},
810 {NFP_6000_CPPTGT_MU, 28, 3, 0, 0, "read32_swap_le"},
811 {NFP_6000_CPPTGT_MU, 29, 1, 0, 0, "cam_lookup_add_lock"},
812 {NFP_6000_CPPTGT_MU, 29, 2, 0, 0, "cam_lookup_add_extend"},
813 {NFP_6000_CPPTGT_MU, 29, 3, 0, 0, "cam_lookup_add_inc"},
814 {NFP_6000_CPPTGT_MU, 30, 2, 0, 0, "meter"},
815 {NFP_6000_CPPTGT_MU, 31, 0, 0, 0, "write32"},
816 {NFP_6000_CPPTGT_MU, 31, 1, 0, 0, "write32_le"},
817 {NFP_6000_CPPTGT_MU, 31, 2, 0, 0, "write32_swap"},
818 {NFP_6000_CPPTGT_MU, 31, 3, 0, 0, "write32_swap_le"},
819 {NFP_6000_CPPTGT_PCIE, 0, 0, 0, 0, "read"},
820 {NFP_6000_CPPTGT_PCIE, 0, 1, 0, 0, "read_rid"},
821 {NFP_6000_CPPTGT_PCIE, 1, 0, 0, 0, "write"},
822 {NFP_6000_CPPTGT_PCIE, 1, 1, 0, 0, "write_rid"},
823 {NFP_6000_CPPTGT_PCIE, 1, 2, 0, 0, "write_vdm"},
824 {NFP_6000_CPPTGT_PCIE, 2, 0, 0, 0, "read_int"},
825 {NFP_6000_CPPTGT_PCIE, 3, 0, 0, 0, "write_int"},
826 {NFP_6000_CPPTGT_ARM, 0, 0, 0, 0, "read"},
827 {NFP_6000_CPPTGT_ARM, 1, 0, 0, 0, "write"},
828 {NFP_6000_CPPTGT_CRYPTO, 0, 0, 0, 0, "read"},
829 {NFP_6000_CPPTGT_CRYPTO, 1, 0, 0, 0, "write"},
830 {NFP_6000_CPPTGT_CRYPTO, 2, 0, 0, 0, "write_fifo"},
831 {NFP_6000_CPPTGT_CTXPB, 0, 0, 0, 0, "xpb_read"},
832 {NFP_6000_CPPTGT_CTXPB, 0, 1, 0, 0, "ring_get"},
833 {NFP_6000_CPPTGT_CTXPB, 0, 2, 0, 0, "interthread_signal"},
834 {NFP_6000_CPPTGT_CTXPB, 1, 0, 0, 0, "xpb_write"},
835 {NFP_6000_CPPTGT_CTXPB, 1, 1, 0, 0, "ring_put"},
836 {NFP_6000_CPPTGT_CTXPB, 1, 2, 0, 0, "ctnn_write"},
837 {NFP_6000_CPPTGT_CTXPB, 2, 0, 0, 0, "reflect_read_none"},
838 {NFP_6000_CPPTGT_CTXPB, 2, 1, 0, 0, "reflect_read_sig_init"},
839 {NFP_6000_CPPTGT_CTXPB, 2, 2, 0, 0, "reflect_read_sig_remote"},
840 {NFP_6000_CPPTGT_CTXPB, 2, 3, 0, 0, "reflect_read_sig_both"},
841 {NFP_6000_CPPTGT_CTXPB, 3, 0, 0, 0, "reflect_write_none"},
842 {NFP_6000_CPPTGT_CTXPB, 3, 1, 0, 0, "reflect_write_sig_init"},
843 {NFP_6000_CPPTGT_CTXPB, 3, 2, 0, 0, "reflect_write_sig_remote"},
844 {NFP_6000_CPPTGT_CTXPB, 3, 3, 0, 0, "reflect_write_sig_both"},
845 {NFP_6000_CPPTGT_CLS, 0, 0, 0, 0, "read"},
846 {NFP_6000_CPPTGT_CLS, 0, 1, 0, 0, "read_le"},
847 {NFP_6000_CPPTGT_CLS, 0, 2, 0, 0, "swap/test_compare_write"},
848 {NFP_6000_CPPTGT_CLS, 0, 3, 0, 0, "xor"},
849 {NFP_6000_CPPTGT_CLS, 1, 0, 0, 0, "write"},
850 {NFP_6000_CPPTGT_CLS, 1, 1, 0, 0, "write_le"},
851 {NFP_6000_CPPTGT_CLS, 1, 2, 0, 0, "write8_be"},
852 {NFP_6000_CPPTGT_CLS, 1, 3, 0, 0, "write8_le"},
853 {NFP_6000_CPPTGT_CLS, 2, 0, 0, 0, "set"},
854 {NFP_6000_CPPTGT_CLS, 2, 1, 0, 0, "clr"},
855 {NFP_6000_CPPTGT_CLS, 2, 2, 0, 0, "test_set"},
856 {NFP_6000_CPPTGT_CLS, 2, 3, 0, 0, "test_clr"},
857 {NFP_6000_CPPTGT_CLS, 3, 0, 0, 0, "set_imm"},
858 {NFP_6000_CPPTGT_CLS, 3, 1, 0, 0, "clr_imm"},
859 {NFP_6000_CPPTGT_CLS, 3, 2, 0, 0, "test_set_imm"},
860 {NFP_6000_CPPTGT_CLS, 3, 3, 0, 0, "test_clr_imm"},
861 {NFP_6000_CPPTGT_CLS, 4, 0, 0, 0, "add"},
862 {NFP_6000_CPPTGT_CLS, 4, 1, 0, 0, "add64"},
863 {NFP_6000_CPPTGT_CLS, 4, 2, 0, 0, "addsat"},
864 {NFP_6000_CPPTGT_CLS, 5, 0, 0, 0, "add_imm"},
865 {NFP_6000_CPPTGT_CLS, 5, 1, 0, 0, "add64_imm"},
866 {NFP_6000_CPPTGT_CLS, 5, 2, 0, 0, "addsat_imm"},
867 {NFP_6000_CPPTGT_CLS, 6, 0, 0, 0, "sub"},
868 {NFP_6000_CPPTGT_CLS, 6, 1, 0, 0, "sub64"},
869 {NFP_6000_CPPTGT_CLS, 6, 2, 0, 0, "subsat"},
870 {NFP_6000_CPPTGT_CLS, 7, 0, 0, 0, "sub_imm"},
871 {NFP_6000_CPPTGT_CLS, 7, 1, 0, 0, "sub64_imm"},
872 {NFP_6000_CPPTGT_CLS, 7, 2, 0, 0, "subsat_imm"},
873 {NFP_6000_CPPTGT_CLS, 8, 0, 0, 0, "queue_lock"},
874 {NFP_6000_CPPTGT_CLS, 8, 1, 0, 0, "queue_unlock"},
875 {NFP_6000_CPPTGT_CLS, 8, 2, 0, 0, "hash_mask"},
876 {NFP_6000_CPPTGT_CLS, 8, 3, 0, 0, "hash_mask_clear"},
877 {NFP_6000_CPPTGT_CLS, 9, 0, 0, 0, "get"},
878 {NFP_6000_CPPTGT_CLS, 9, 1, 0, 0, "pop"},
879 {NFP_6000_CPPTGT_CLS, 9, 2, 0, 0, "get_safe"},
880 {NFP_6000_CPPTGT_CLS, 9, 3, 0, 0, "pop_safe"},
881 {NFP_6000_CPPTGT_CLS, 10, 0, 0, 0, "ring_put"},
882 {NFP_6000_CPPTGT_CLS, 10, 2, 0, 0, "ring_journal"},
883 {NFP_6000_CPPTGT_CLS, 11, 0, 0, 0, "cam_lookup32"},
884 {NFP_6000_CPPTGT_CLS, 11, 1, 0, 0, "cam_lookup32_add"},
885 {NFP_6000_CPPTGT_CLS, 11, 2, 0, 0, "cam_lookup24"},
886 {NFP_6000_CPPTGT_CLS, 11, 3, 0, 0, "cam_lookup24_add"},
887 {NFP_6000_CPPTGT_CLS, 12, 0, 0, 0, "cam_lookup8"},
888 {NFP_6000_CPPTGT_CLS, 12, 1, 0, 0, "cam_lookup8_add"},
889 {NFP_6000_CPPTGT_CLS, 12, 2, 0, 0, "cam_lookup16"},
890 {NFP_6000_CPPTGT_CLS, 12, 3, 0, 0, "cam_lookup16_add"},
891 {NFP_6000_CPPTGT_CLS, 13, 0, 0, 0, "tcam_lookup32"},
892 {NFP_6000_CPPTGT_CLS, 13, 1, 0, 0, "tcam_lookup24"},
893 {NFP_6000_CPPTGT_CLS, 13, 2, 0, 0, "tcam_lookup16"},
894 {NFP_6000_CPPTGT_CLS, 13, 3, 0, 0, "tcam_lookup8"},
895 {NFP_6000_CPPTGT_CLS, 14, 0, 0, 0, "reflect_write_sig_local"},
896 {NFP_6000_CPPTGT_CLS, 14, 1, 0, 0, "reflect_write_sig_remote"},
897 {NFP_6000_CPPTGT_CLS, 14, 2, 0, 0, "reflect_write_sig_both"},
898 {NFP_6000_CPPTGT_CLS, 15, 0, 0, 0, "reflect_read_sig_remote"},
899 {NFP_6000_CPPTGT_CLS, 15, 1, 0, 0, "reflect_read_sig_local"},
900 {NFP_6000_CPPTGT_CLS, 15, 2, 0, 0, "reflect_read_sig_both"},
901 {NFP_6000_CPPTGT_CLS, 16, 1, 0, 0, "cam_lookup32_add_lock"},
902 {NFP_6000_CPPTGT_CLS, 16, 2, 0, 0, "cam_lookup24_add_inc"},
903 {NFP_6000_CPPTGT_CLS, 16, 3, 0, 0, "cam_lookup32_add_extend"},
904 {NFP_6000_CPPTGT_CLS, 17, 0, 0, 0, "meter"},
905 {NFP_6000_CPPTGT_CLS, 17, 2, 0, 0, "statistic"},
906 {NFP_6000_CPPTGT_CLS, 17, 3, 0, 0, "statistic_imm"},
907 {NFP_6000_CPPTGT_CLS, 20, 0, 0, 0, "test_add"},
908 {NFP_6000_CPPTGT_CLS, 20, 1, 0, 0, "test_add64"},
909 {NFP_6000_CPPTGT_CLS, 20, 2, 0, 0, "test_addsat"},
910 {NFP_6000_CPPTGT_CLS, 21, 0, 0, 0, "test_add_imm"},
911 {NFP_6000_CPPTGT_CLS, 21, 1, 0, 0, "test_add64_imm"},
912 {NFP_6000_CPPTGT_CLS, 21, 2, 0, 0, "test_addsat_imm"},
913 {NFP_6000_CPPTGT_CLS, 22, 0, 0, 0, "test_sub"},
914 {NFP_6000_CPPTGT_CLS, 22, 1, 0, 0, "test_sub64"},
915 {NFP_6000_CPPTGT_CLS, 22, 2, 0, 0, "test_subsat"},
916 {NFP_6000_CPPTGT_CLS, 23, 0, 0, 0, "test_sub_imm"},
917 {NFP_6000_CPPTGT_CLS, 23, 1, 0, 0, "test_sub64_imm"},
918 {NFP_6000_CPPTGT_CLS, 23, 2, 0, 0, "test_subsat_imm"},
919 {NFP_6000_CPPTGT_CLS, 24, 0, 0, 0, "ring_read"},
920 {NFP_6000_CPPTGT_CLS, 24, 1, 0, 0, "ring_write"},
921 {NFP_6000_CPPTGT_CLS, 24, 2, 0, 0, "ring_ordered_lock"},
922 {NFP_6000_CPPTGT_CLS, 24, 3, 0, 0, "ring_ordered_unlock"},
923 {NFP_6000_CPPTGT_CLS, 25, 0, 0, 0, "ring_workq_add_thread"},
924 {NFP_6000_CPPTGT_CLS, 25, 1, 0, 0, "ring_workq_add_work"}
925 };
926
927 static int
928 nfp_me_print_invalid (uint64_t instr, struct disassemble_info *dinfo)
929 {
930 const char * err_msg = N_("<invalid_instruction>:");
931 dinfo->fprintf_func (dinfo->stream, "%s 0x%" PRIx64, err_msg, instr);
932 return _NFP_ERR_CONT;
933 }
934
935 static bool
936 nfp_me_is_imm_opnd10 (unsigned int opnd)
937 {
938 return _BF (opnd, 9, 8) == 0x3;
939 }
940
941 static bool
942 nfp_me_is_imm_opnd8 (unsigned int opnd)
943 {
944 return _BTST (opnd, 5);
945 }
946
947 static unsigned int
948 nfp_me_imm_opnd10 (unsigned int opnd)
949 {
950 return nfp_me_is_imm_opnd10 (opnd) ? (opnd & 0xff) : ~0U;
951 }
952
953 static unsigned int
954 nfp_me_imm_opnd8 (unsigned int opnd, unsigned int imm8_msb)
955 {
956 unsigned int v = (imm8_msb << 7) | _BFS (opnd, 7, 6, 5) | _BF (opnd, 4, 0);
957
958 return nfp_me_is_imm_opnd8 (opnd) ? v : ~0U;
959 }
960
961 /* Print an unrestricted/10-bit operand.
962 This can mostly be generic across NFP families at the moment. */
963 static bool
964 nfp_me_print_opnd10 (unsigned int opnd, char bank, int num_ctx, int lmem_ext,
965 struct disassemble_info *dinfo)
966 {
967 unsigned int n = _BF (opnd, (num_ctx == 8) ? 3 : 4, 0);
968
969 /* Absolute GPR. */
970 if (_BF (opnd, 9, 7) == 0x1)
971 dinfo->fprintf_func (dinfo->stream, "@gpr%c_%d", bank, _BF (opnd, 6, 0));
972
973 /* Relative GPR. */
974 else if (_BF (opnd, 9, 6) == 0x0)
975 dinfo->fprintf_func (dinfo->stream, "gpr%c_%d", bank, n);
976
977 /* Indexed Xfer. */
978 else if (_BF (opnd, 9, 7) == 0x2)
979 {
980 dinfo->fprintf_func (dinfo->stream, "*$index");
981 if (_BF (opnd, 2, 1) == 0x1)
982 dinfo->fprintf_func (dinfo->stream, "++");
983 else if (_BF (opnd, 2, 1) == 0x2)
984 dinfo->fprintf_func (dinfo->stream, "--");
985 }
986
987 /* Relative Xfer. */
988 else if (_BF (opnd, 9, 7) == 0x3)
989 {
990 if (_BTST (opnd, 6))
991 n += (num_ctx == 8 ? 16 : 32);
992 dinfo->fprintf_func (dinfo->stream, "$xfer_%d", n);
993 }
994
995 /* Indexed Next Neighbour. */
996 else if (_BF (opnd, 9, 6) == 0x9)
997 {
998 dinfo->fprintf_func (dinfo->stream, "*n$index");
999 if (_BTST (opnd, 1))
1000 dinfo->fprintf_func (dinfo->stream, "++");
1001 }
1002
1003 /* Relative Next Neighbour. */
1004 else if (_BF (opnd, 9, 6) == 0xa)
1005 {
1006 dinfo->fprintf_func (dinfo->stream, "n$reg_%d", n);
1007 }
1008
1009 /* Indexed LMEM. */
1010 else if (_BF (opnd, 9, 6) == 0x8)
1011 {
1012 n = _BF (opnd, 5, 5) + (lmem_ext * 2);
1013 dinfo->fprintf_func (dinfo->stream, "*l$index%d", n);
1014 if (_BTST (opnd, 4))
1015 dinfo->fprintf_func (dinfo->stream, _BTST (opnd, 0) ? "--" : "++");
1016 else if (_BF (opnd, 3, 0))
1017 dinfo->fprintf_func (dinfo->stream, "[%d]", _BF (opnd, 3, 0));
1018 }
1019
1020 /* 8-bit Constant value. */
1021 else if (_BF (opnd, 9, 8) == 0x3)
1022 dinfo->fprintf_func (dinfo->stream, "0x%x", _BF (opnd, 7, 0));
1023
1024 else
1025 {
1026 dinfo->fprintf_func (dinfo->stream, "<opnd:0x%x>", opnd);
1027 return false;
1028 }
1029
1030 return true;
1031 }
1032
1033 /* Print a restricted/8-bit operand.
1034 This can mostly be generic across NFP families at the moment. */
1035
1036 static bool
1037 nfp_me_print_opnd8 (unsigned int opnd, char bank, int num_ctx, int lmem_ext,
1038 unsigned int imm8_msb, struct disassemble_info *dinfo)
1039 {
1040 unsigned int n = _BF (opnd, (num_ctx == 8) ? 3 : 4, 0);
1041
1042 /* Relative GPR. */
1043 if (_BF (opnd, 7, 5) == 0x0)
1044 dinfo->fprintf_func (dinfo->stream, "gpr%c_%d", bank, n);
1045
1046 /* Relative Xfer. */
1047 else if (_BF (opnd, 7, 5) == 0x4)
1048 dinfo->fprintf_func (dinfo->stream, "$xfer_%d", n);
1049
1050 /* Relative Xfer. */
1051 else if (_BF (opnd, 7, 5) == 0x6)
1052 {
1053 n += (num_ctx == 8 ? 16 : 32);
1054 dinfo->fprintf_func (dinfo->stream, "$xfer_%d", n);
1055 }
1056
1057 /* Indexed Xfer. */
1058 else if ((_BF (opnd, 7, 4) == 0x4) && (!_BTST (opnd, 0)))
1059 {
1060 dinfo->fprintf_func (dinfo->stream, "*$index");
1061 if (_BF (opnd, 2, 1) == 0x1)
1062 dinfo->fprintf_func (dinfo->stream, "++");
1063 else if (_BF (opnd, 2, 1) == 0x2)
1064 dinfo->fprintf_func (dinfo->stream, "--");
1065 }
1066
1067 /* Indexed NN. */
1068 else if ((_BF (opnd, 7, 4) == 0x4) && (_BTST (opnd, 0)))
1069 {
1070 dinfo->fprintf_func (dinfo->stream, "*n$index");
1071 if (_BTST (opnd, 1))
1072 dinfo->fprintf_func (dinfo->stream, "++");
1073 }
1074
1075 /* Indexed LMEM. */
1076 else if (_BF (opnd, 7, 4) == 0x5)
1077 {
1078 n = _BF (opnd, 3, 3) + (lmem_ext * 2);
1079 dinfo->fprintf_func (dinfo->stream, "*l$index%d", n);
1080 if (_BF (opnd, 2, 0))
1081 dinfo->fprintf_func (dinfo->stream, "[%d]", _BF (opnd, 2, 0));
1082 }
1083
1084 /* 7+1-bit Constant value. */
1085 else if (_BTST (opnd, 5))
1086 {
1087 n = (imm8_msb << 7) | _BFS (opnd, 7, 6, 5) | _BF (opnd, 4, 0);
1088 dinfo->fprintf_func (dinfo->stream, "0x%x", n);
1089 }
1090
1091 else
1092 {
1093 dinfo->fprintf_func (dinfo->stream, "<opnd:0x%x>", opnd);
1094 return false;
1095 }
1096
1097 return true;
1098 }
1099
1100 static int
1101 nfp_me27_28_print_alu_shf (uint64_t instr, unsigned int pred_cc,
1102 unsigned int dst_lmext, unsigned int src_lmext,
1103 unsigned int gpr_wrboth,
1104 int num_ctx, struct disassemble_info *dinfo)
1105 {
1106 unsigned int op = _BF (instr, 35, 33);
1107 unsigned int srcA = _BF (instr, 7, 0);
1108 unsigned int srcB = _BF (instr, 17, 10);
1109 unsigned int dst = _BF (instr, 27, 20);
1110 unsigned int sc = _BF (instr, 9, 8);
1111 unsigned int imm_msb = _BTST (instr, 18);
1112 unsigned int swap = _BTST (instr, 19);
1113 unsigned int shift = _BF (instr, 32, 28);
1114 char dst_bank = 'A' + _BTST (instr, 36);
1115 unsigned int nocc = _BTST (instr, 40);
1116 bool err = false;
1117
1118 if (swap)
1119 {
1120 unsigned int tmp = srcA;
1121 srcA = srcB;
1122 srcB = tmp;
1123 }
1124
1125 /* alu_shf, dbl_shf, asr. */
1126 if (op < 7)
1127 {
1128 if (sc == 3)
1129 dinfo->fprintf_func (dinfo->stream, "dbl_shf[");
1130 else if (op == 6)
1131 dinfo->fprintf_func (dinfo->stream, "asr[");
1132 else
1133 dinfo->fprintf_func (dinfo->stream, "alu_shf[");
1134
1135 /* dest operand */
1136 if (nfp_me_is_imm_opnd8 (dst))
1137 dinfo->fprintf_func (dinfo->stream, "--");
1138 else
1139 err = err || !nfp_me_print_opnd8 (dst, dst_bank, num_ctx,
1140 dst_lmext, imm_msb, dinfo);
1141
1142 dinfo->fprintf_func (dinfo->stream, ", ");
1143
1144 /* A operand. */
1145 if (op != 6)
1146 {
1147 if ((op < 2) && (sc != 3)) /* Not dbl_shf. */
1148 dinfo->fprintf_func (dinfo->stream, "--"); /* B or ~B operator. */
1149 else
1150 err = err || !nfp_me_print_opnd8 (srcA, (swap) ? 'B' : 'A',
1151 num_ctx, src_lmext, imm_msb,
1152 dinfo);
1153
1154 dinfo->fprintf_func (dinfo->stream, ", ");
1155
1156 /* Operator (not for dbl_shf). */
1157 if (sc != 3)
1158 {
1159 dinfo->fprintf_func (dinfo->stream, "%s, ",
1160 nfp_mealu_shf_op[op]);
1161 }
1162 }
1163
1164 /* B operand. */
1165 err = err || !nfp_me_print_opnd8 (srcB, (swap) ? 'A' : 'B',
1166 num_ctx, src_lmext, imm_msb, dinfo);
1167
1168 dinfo->fprintf_func (dinfo->stream, ", ");
1169
1170 /* Shift */
1171 if (sc == 0)
1172 dinfo->fprintf_func (dinfo->stream, ">>rot%d", shift);
1173 else if (sc == 2)
1174 {
1175 if (shift)
1176 dinfo->fprintf_func (dinfo->stream, "<<%d", (32 - shift));
1177 else
1178 dinfo->fprintf_func (dinfo->stream, "<<indirect");
1179 }
1180 else
1181 {
1182 if (shift)
1183 dinfo->fprintf_func (dinfo->stream, ">>%d", shift);
1184 else
1185 dinfo->fprintf_func (dinfo->stream, ">>indirect");
1186 }
1187 }
1188 /* Byte Align. */
1189 else if (op == 7)
1190 {
1191 dinfo->fprintf_func (dinfo->stream, "byte_align_%s[",
1192 ((sc == 2) ? "le" : "be"));
1193
1194 /* Dest operand. */
1195 if (nfp_me_is_imm_opnd8 (dst))
1196 dinfo->fprintf_func (dinfo->stream, "--");
1197 else
1198 err = err || !nfp_me_print_opnd8 (dst, dst_bank, num_ctx,
1199 dst_lmext, imm_msb, dinfo);
1200
1201 dinfo->fprintf_func (dinfo->stream, ", ");
1202
1203 if (sc == 2)
1204 err = err || !nfp_me_print_opnd8 (srcA, (swap) ? 'B' : 'A', num_ctx,
1205 0, imm_msb, dinfo);
1206 else
1207 err = err || !nfp_me_print_opnd8 (srcB, (swap) ? 'A' : 'B', num_ctx,
1208 0, imm_msb, dinfo);
1209 }
1210
1211 dinfo->fprintf_func (dinfo->stream, "]");
1212 if (nocc)
1213 dinfo->fprintf_func (dinfo->stream, ", no_cc");
1214 if (gpr_wrboth)
1215 dinfo->fprintf_func (dinfo->stream, ", gpr_wrboth");
1216 if (pred_cc)
1217 dinfo->fprintf_func (dinfo->stream, ", predicate_cc");
1218
1219 if (err)
1220 return _NFP_ERR_CONT;
1221 return 0;
1222 }
1223
1224 static int
1225 nfp_me27_28_print_alu (uint64_t instr, unsigned int pred_cc,
1226 unsigned int dst_lmext, unsigned int src_lmext,
1227 unsigned int gpr_wrboth,
1228 int num_ctx, struct disassemble_info *dinfo)
1229 {
1230 unsigned int op = _BF (instr, 35, 31);
1231 unsigned int srcA = _BF (instr, 9, 0);
1232 unsigned int srcB = _BF (instr, 19, 10);
1233 unsigned int dst = _BF (instr, 29, 20);
1234 unsigned int swap = _BTST (instr, 30);
1235 char dst_bank = 'A' + _BTST (instr, 36);
1236 unsigned int nocc = _BTST (instr, 40);
1237 int do_close_bracket = 1;
1238 bool err = false;
1239
1240 if (swap)
1241 {
1242 unsigned int tmp = srcA;
1243 srcA = srcB;
1244 srcB = tmp;
1245 }
1246
1247 switch (op)
1248 {
1249 case 3: /* pop_count3[dst, srcB] */
1250 case 6: /* pop_count1[srcB] */
1251 case 7: /* pop_count2[srcB] */
1252 case 14: /* ffs[dst, srcB] */
1253 case 15: /* cam_read_tag[dst, srcB] */
1254 case 31: /* cam_read_state[dst, srcB] */
1255 dinfo->fprintf_func (dinfo->stream, "%s[", nfp_me27_28_alu_op[op]);
1256
1257 /* No dest for pop_count1/2. */
1258 if ((op != 6) && (op != 7))
1259 {
1260 /* dest operand */
1261 if (nfp_me_is_imm_opnd10 (dst))
1262 dinfo->fprintf_func (dinfo->stream, "--");
1263 else
1264 err = err || !nfp_me_print_opnd10 (dst, dst_bank, num_ctx,
1265 dst_lmext, dinfo);
1266
1267 dinfo->fprintf_func (dinfo->stream, ", ");
1268 }
1269
1270 /* B operand. */
1271 err = err || !nfp_me_print_opnd10 (srcB, (swap) ? 'A' : 'B',
1272 num_ctx, src_lmext, dinfo);
1273 break;
1274
1275 /* cam_clear. */
1276 case 11:
1277 do_close_bracket = 0;
1278 dinfo->fprintf_func (dinfo->stream, "cam_clear");
1279 break;
1280
1281 /* cam_lookup. */
1282 case 23:
1283 do_close_bracket = 0;
1284 dinfo->fprintf_func (dinfo->stream, "%s[", nfp_me27_28_alu_op[op]);
1285
1286 /* Dest operand. */
1287 if (nfp_me_is_imm_opnd10 (dst))
1288 dinfo->fprintf_func (dinfo->stream, "--");
1289 else
1290 err = err || !nfp_me_print_opnd10 (dst, dst_bank, num_ctx,
1291 dst_lmext, dinfo);
1292
1293 dinfo->fprintf_func (dinfo->stream, ", ");
1294
1295 /* A operand. */
1296 err = err || !nfp_me_print_opnd10 (srcA, (swap) ? 'B' : 'A',
1297 num_ctx, src_lmext, dinfo);
1298
1299 dinfo->fprintf_func (dinfo->stream, "]");
1300
1301 if (_BF (srcB, 1, 0))
1302 {
1303 unsigned int n = _BTST (srcB, 1);
1304 if (_BTST (srcB, 4)) /* Only for MEv28. */
1305 n += 2;
1306 dinfo->fprintf_func (dinfo->stream, ", lm_addr%d[%d]", n,
1307 _BF (srcB, 3, 2));
1308 }
1309
1310 break;
1311
1312 case 19: /* cam_write. */
1313 case 27: /* cam_write_state. */
1314 dinfo->fprintf_func (dinfo->stream, "%s[", nfp_me27_28_alu_op[op]);
1315 err = err || !nfp_me_print_opnd10 (srcB, (swap) ? 'A' : 'B',
1316 num_ctx, src_lmext, dinfo);
1317 dinfo->fprintf_func (dinfo->stream, ", ");
1318 if (op == 19)
1319 {
1320 err = err || !nfp_me_print_opnd10 (srcA, (swap) ? 'B' : 'A',
1321 num_ctx, src_lmext, dinfo);
1322 dinfo->fprintf_func (dinfo->stream, ", ");
1323 }
1324 dinfo->fprintf_func (dinfo->stream, "%d", (dst & 0xf));
1325 break;
1326
1327 /* CRC. */
1328 case 18:
1329 do_close_bracket = 0;
1330 dinfo->fprintf_func (dinfo->stream, "crc_%s[",
1331 _BTST (srcA, 3) ? "le" : "be");
1332 if (!nfp_me27_28_crc_op[_BF (srcA, 7, 5)])
1333 {
1334 dinfo->fprintf_func (dinfo->stream, _(", <invalid CRC operator>, "));
1335 err = true;
1336 }
1337 else
1338 {
1339 dinfo->fprintf_func (dinfo->stream, "%s, ",
1340 nfp_me27_28_crc_op[_BF (srcA, 7, 5)]);
1341 }
1342
1343 /* Dest operand. */
1344 if (nfp_me_is_imm_opnd10 (dst))
1345 dinfo->fprintf_func (dinfo->stream, "--");
1346 else
1347 err = err || !nfp_me_print_opnd10 (dst, dst_bank, num_ctx,
1348 dst_lmext, dinfo);
1349
1350 dinfo->fprintf_func (dinfo->stream, ", ");
1351
1352 /* B operand. */
1353 err = err || !nfp_me_print_opnd10 (srcB, (swap) ? 'A' : 'B',
1354 num_ctx, src_lmext, dinfo);
1355
1356 dinfo->fprintf_func (dinfo->stream, "]");
1357 if (_BF (srcA, 2, 0))
1358 dinfo->fprintf_func (dinfo->stream, ", %s",
1359 nfp_me27_28_crc_bytes[_BF (srcA, 2, 0)]);
1360 if (_BTST (srcA, 4))
1361 dinfo->fprintf_func (dinfo->stream, ", bit_swap");
1362 break;
1363
1364 default:
1365 /* s += 'alu[%s, %s, %s, %s]' % (dst, srcAs, op, srcBs). */
1366 dinfo->fprintf_func (dinfo->stream, "alu[");
1367
1368 /* Dest operand. */
1369 if (nfp_me_is_imm_opnd10 (dst))
1370 dinfo->fprintf_func (dinfo->stream, "--");
1371 else
1372 err = err || !nfp_me_print_opnd10 (dst, dst_bank, num_ctx,
1373 dst_lmext, dinfo);
1374 dinfo->fprintf_func (dinfo->stream, ", ");
1375
1376 /* A operand. */
1377 if ((op == 0) || (op == 4)) /* B only operators. */
1378 dinfo->fprintf_func (dinfo->stream, "--");
1379 else
1380 err = err || !nfp_me_print_opnd10 (srcA, (swap) ? 'B' : 'A',
1381 num_ctx, src_lmext, dinfo);
1382
1383 if (!nfp_me27_28_alu_op[op])
1384 {
1385 dinfo->fprintf_func (dinfo->stream, ", <operator:0x%x>, ", op);
1386 err = true;
1387 }
1388 else
1389 {
1390 dinfo->fprintf_func (dinfo->stream, ", %s, ",
1391 nfp_me27_28_alu_op[op]);
1392 }
1393
1394 /* B operand. */
1395 err = err || !nfp_me_print_opnd10 (srcB, (swap) ? 'A' : 'B',
1396 num_ctx, src_lmext, dinfo);
1397 break;
1398 }
1399
1400 if (do_close_bracket)
1401 dinfo->fprintf_func (dinfo->stream, "]");
1402
1403 if (nocc)
1404 dinfo->fprintf_func (dinfo->stream, ", no_cc");
1405 if (gpr_wrboth)
1406 dinfo->fprintf_func (dinfo->stream, ", gpr_wrboth");
1407 if (pred_cc)
1408 dinfo->fprintf_func (dinfo->stream, ", predicate_cc");
1409
1410 if (err)
1411 return _NFP_ERR_CONT;
1412 return 0;
1413 }
1414
1415 static int
1416 nfp_me27_28_print_immed (uint64_t instr, unsigned int pred_cc,
1417 unsigned int dst_lmext,
1418 unsigned int gpr_wrboth,
1419 int num_ctx, struct disassemble_info *dinfo)
1420 {
1421 unsigned int srcA = _BF (instr, 9, 0);
1422 unsigned int srcB = _BF (instr, 19, 10);
1423 unsigned int imm = _BF (instr, 27, 20);
1424 unsigned int by = _BTST (instr, 29);
1425 unsigned int wd = _BTST (instr, 30);
1426 unsigned int inv = _BTST (instr, 31);
1427 unsigned int byte_shift = _BF (instr, 34, 33);
1428 bool err = false;
1429
1430 if (nfp_me_is_imm_opnd10 (srcB))
1431 {
1432 imm = (imm << 8) | nfp_me_imm_opnd10 (srcB);
1433 if (nfp_me_is_imm_opnd10 (srcA) && (imm == 0))
1434 {
1435 dinfo->fprintf_func (dinfo->stream, "nop");
1436 return 0;
1437 }
1438 }
1439 else
1440 {
1441 imm = (imm << 8) | nfp_me_imm_opnd10 (srcA);
1442 }
1443
1444 if (inv)
1445 imm = (imm ^ 0xffff) | 0xffff0000U;
1446
1447 if (by)
1448 {
1449 dinfo->fprintf_func (dinfo->stream, "immed_b%d[", byte_shift);
1450 imm &= 0xff;
1451 }
1452 else if (wd)
1453 {
1454 dinfo->fprintf_func (dinfo->stream, "immed_w%d[", (byte_shift / 2));
1455 imm &= 0xffff;
1456 }
1457 else
1458 dinfo->fprintf_func (dinfo->stream, "immed[");
1459
1460 /* Dest. */
1461 if (nfp_me_is_imm_opnd10 (srcA) && nfp_me_is_imm_opnd10 (srcB))
1462 dinfo->fprintf_func (dinfo->stream, "--"); /* No Dest. */
1463 else if (nfp_me_is_imm_opnd10 (srcA))
1464 err = err || !nfp_me_print_opnd10 (srcB, 'B', num_ctx, dst_lmext, dinfo);
1465 else
1466 err = err || !nfp_me_print_opnd10 (srcA, 'A', num_ctx, dst_lmext, dinfo);
1467
1468 dinfo->fprintf_func (dinfo->stream, ", 0x%x", imm);
1469
1470 if ((!by) && (!wd) && (byte_shift))
1471 dinfo->fprintf_func (dinfo->stream, ", <<%d", (byte_shift * 8));
1472
1473 dinfo->fprintf_func (dinfo->stream, "]");
1474
1475 if (gpr_wrboth)
1476 dinfo->fprintf_func (dinfo->stream, ", gpr_wrboth");
1477 if (pred_cc)
1478 dinfo->fprintf_func (dinfo->stream, ", predicate_cc");
1479
1480 if (err)
1481 return _NFP_ERR_CONT;
1482 return 0;
1483 }
1484
1485 static int
1486 nfp_me27_28_print_ld_field (uint64_t instr, unsigned int pred_cc,
1487 unsigned int dst_lmext, unsigned int src_lmext,
1488 unsigned int gpr_wrboth,
1489 int num_ctx, struct disassemble_info *dinfo)
1490 {
1491 unsigned int load_cc = _BTST (instr, 34);
1492 unsigned int shift = _BF (instr, 32, 28);
1493 unsigned int byte_mask = _BF (instr, 27, 24);
1494 unsigned int zerof = _BTST (instr, 20);
1495 unsigned int swap = _BTST (instr, 19);
1496 unsigned int imm_msb = _BTST (instr, 18);
1497 unsigned int src = _BF (instr, 17, 10);
1498 unsigned int sc = _BF (instr, 9, 8);
1499 unsigned int dst = _BF (instr, 7, 0);
1500 bool err = false;
1501
1502 if (swap)
1503 {
1504 unsigned int tmp = src;
1505 src = dst;
1506 dst = tmp;
1507 }
1508
1509 if (zerof)
1510 dinfo->fprintf_func (dinfo->stream, "ld_field_w_clr[");
1511 else
1512 dinfo->fprintf_func (dinfo->stream, "ld_field[");
1513
1514 err = err || !nfp_me_print_opnd8 (dst, (swap) ? 'B' : 'A', num_ctx,
1515 dst_lmext, imm_msb, dinfo);
1516 dinfo->fprintf_func (dinfo->stream, ", %d%d%d%d, ",
1517 _BTST (byte_mask, 3),
1518 _BTST (byte_mask, 2),
1519 _BTST (byte_mask, 1), _BTST (byte_mask, 0));
1520 err = err || !nfp_me_print_opnd8 (src, (swap) ? 'A' : 'B', num_ctx,
1521 src_lmext, imm_msb, dinfo);
1522
1523 if ((sc == 0) && (shift != 0))
1524 dinfo->fprintf_func (dinfo->stream, ", >>rot%d", shift);
1525 else if (sc == 1)
1526 {
1527 if (shift)
1528 dinfo->fprintf_func (dinfo->stream, ", >>%d", shift);
1529 else
1530 dinfo->fprintf_func (dinfo->stream, ", >>indirect");
1531 }
1532 else if (sc == 2)
1533 {
1534 if (shift)
1535 dinfo->fprintf_func (dinfo->stream, ", <<%d", (32 - shift));
1536 else
1537 dinfo->fprintf_func (dinfo->stream, ", <<indirect");
1538 }
1539 else if (sc == 3)
1540 dinfo->fprintf_func (dinfo->stream, ", >>dbl%d", shift);
1541
1542 dinfo->fprintf_func (dinfo->stream, "]");
1543
1544 if (load_cc)
1545 dinfo->fprintf_func (dinfo->stream, ", load_cc");
1546 if (gpr_wrboth)
1547 dinfo->fprintf_func (dinfo->stream, ", gpr_wrboth");
1548 if (pred_cc)
1549 dinfo->fprintf_func (dinfo->stream, ", predicate_cc");
1550
1551 if (err)
1552 return _NFP_ERR_CONT;
1553 return 0;
1554 }
1555
1556 static int
1557 nfp_me27_28_print_ctx_arb (uint64_t instr, struct disassemble_info *dinfo)
1558 {
1559 unsigned int resume_addr = _BFS (instr, 40, 40, 13) | _BF (instr, 34, 22);
1560 unsigned int defer = _BF (instr, 21, 20);
1561 unsigned int no_load = _BTST (instr, 19);
1562 unsigned int resume = _BTST (instr, 18);
1563 unsigned int bpt = _BTST (instr, 17);
1564 unsigned int sig_or = _BTST (instr, 16);
1565 unsigned int ev_mask = _BF (instr, 15, 0);
1566
1567 dinfo->fprintf_func (dinfo->stream, "ctx_arb[");
1568 if (bpt)
1569 dinfo->fprintf_func (dinfo->stream, "bpt");
1570 else if (ev_mask == 1)
1571 dinfo->fprintf_func (dinfo->stream, "voluntary");
1572 else if ((!no_load) && (ev_mask == 0))
1573 {
1574 dinfo->fprintf_func (dinfo->stream, "kill");
1575 sig_or = 0;
1576 }
1577 else if (ev_mask == 0)
1578 dinfo->fprintf_func (dinfo->stream, "--");
1579 else
1580 {
1581 int first_print = 1;
1582 unsigned int n;
1583
1584 for (n = 1; n < 16; n++)
1585 {
1586 if (!_BTST (ev_mask, n))
1587 continue;
1588 dinfo->fprintf_func (dinfo->stream, "%ssig%d",
1589 (first_print) ? "" : ", ", n);
1590 first_print = 0;
1591 }
1592 }
1593
1594 dinfo->fprintf_func (dinfo->stream, "]");
1595
1596 if (sig_or)
1597 dinfo->fprintf_func (dinfo->stream, ", any");
1598 if (resume)
1599 dinfo->fprintf_func (dinfo->stream, ", br[.%d]", resume_addr);
1600 if (defer)
1601 dinfo->fprintf_func (dinfo->stream, ", defer[%d]", defer);
1602
1603 return 0;
1604 }
1605
1606 static int
1607 nfp_me27_28_print_local_csr (uint64_t instr,
1608 unsigned int src_lmext,
1609 int num_ctx, struct disassemble_info *dinfo)
1610 {
1611 unsigned int srcA = _BF (instr, 9, 0);
1612 unsigned int srcB = _BF (instr, 19, 10);
1613 unsigned int wr = _BTST (instr, 21);
1614 unsigned int csr_num = _BF (instr, 32, 22);
1615 unsigned int src = srcA;
1616 char src_bank = 'A';
1617 bool err = false;
1618
1619 if (nfp_me_is_imm_opnd10 (srcA) && !nfp_me_is_imm_opnd10 (srcB))
1620 {
1621 src_bank = 'B';
1622 src = srcB;
1623 }
1624
1625 /* MEv28 does not have urd/uwr. */
1626 if (csr_num == 1)
1627 {
1628 if (wr)
1629 {
1630 dinfo->fprintf_func (dinfo->stream, "uwr[*u$index%d++, ",
1631 (int) _BTST (instr, 20));
1632 err = err || !nfp_me_print_opnd10 (src, src_bank, num_ctx,
1633 src_lmext, dinfo);
1634 }
1635 else
1636 {
1637 dinfo->fprintf_func (dinfo->stream, "urd[");
1638 err = err || !nfp_me_print_opnd10 (src, src_bank, num_ctx,
1639 src_lmext, dinfo);
1640 dinfo->fprintf_func (dinfo->stream, ", *u$index%d++",
1641 (int) _BTST (instr, 20));
1642 }
1643 dinfo->fprintf_func (dinfo->stream, "]");
1644 }
1645 else
1646 {
1647 const char *nm = NULL;
1648
1649 if (csr_num < ARRAY_SIZE (nfp_me27_28_mecsrs))
1650 nm = nfp_me27_28_mecsrs[csr_num];
1651
1652 dinfo->fprintf_func (dinfo->stream, "local_csr_%s[",
1653 (wr) ? "wr" : "rd");
1654 if (nm)
1655 dinfo->fprintf_func (dinfo->stream, "%s", nm);
1656 else
1657 dinfo->fprintf_func (dinfo->stream, "0x%x", (csr_num * 4));
1658
1659 if (wr)
1660 {
1661 dinfo->fprintf_func (dinfo->stream, ", ");
1662 err = err || !nfp_me_print_opnd10 (src, src_bank, num_ctx,
1663 src_lmext, dinfo);
1664 }
1665 dinfo->fprintf_func (dinfo->stream, "]");
1666 }
1667
1668 if (err)
1669 return _NFP_ERR_CONT;
1670 return 0;
1671 }
1672
1673 static int
1674 nfp_me27_28_print_branch (uint64_t instr,
1675 const char *br_inpstates[16],
1676 struct disassemble_info *dinfo)
1677 {
1678 unsigned int br_op = _BF (instr, 4, 0);
1679 unsigned int ctx_sig_state = _BF (instr, 17, 14);
1680 unsigned int defer = _BF (instr, 21, 20);
1681 unsigned int br_addr = _BFS (instr, 40, 40, 13) | _BF (instr, 34, 22);
1682 int ret = 0;
1683
1684 if (!nfp_me27_28_br_ops[br_op])
1685 {
1686 dinfo->fprintf_func (dinfo->stream, _("<invalid branch>["));
1687 ret = _NFP_ERR_CONT;
1688 }
1689 else
1690 dinfo->fprintf_func (dinfo->stream, "%s[", nfp_me27_28_br_ops[br_op]);
1691
1692 switch (br_op)
1693 {
1694 case 16: /* br=ctx */
1695 case 17: /* br!=ctx */
1696 case 18: /* br_signal */
1697 case 19: /* br_!signal */
1698 dinfo->fprintf_func (dinfo->stream, "%d, ", ctx_sig_state);
1699 break;
1700 case 20: /* "br_inp_state" */
1701 case 21: /* "br_!inp_state" */
1702 dinfo->fprintf_func (dinfo->stream, "%s, ",
1703 br_inpstates[ctx_sig_state]);
1704 break;
1705 case 22: /* "br_cls_state" */
1706 case 23: /* "br_!cls_state" */
1707 dinfo->fprintf_func (dinfo->stream, "cls_ring%d_status, ",
1708 ctx_sig_state);
1709 break;
1710 default:
1711 break;
1712 }
1713
1714 dinfo->fprintf_func (dinfo->stream, ".%d]", br_addr);
1715
1716 if (defer)
1717 dinfo->fprintf_func (dinfo->stream, ", defer[%d]", defer);
1718
1719 return ret;
1720 }
1721
1722 static int
1723 nfp_me27_28_print_br_byte (uint64_t instr,
1724 unsigned int src_lmext, int num_ctx,
1725 struct disassemble_info *dinfo)
1726 {
1727 unsigned int srcA = _BF (instr, 7, 0);
1728 unsigned int by = _BF (instr, 9, 8);
1729 unsigned int srcB = _BF (instr, 17, 10);
1730 unsigned int imm_msb = _BTST (instr, 18);
1731 unsigned int eq = _BTST (instr, 19);
1732 unsigned int defer = _BF (instr, 21, 20);
1733 unsigned int br_addr = _BFS (instr, 40, 40, 13) | _BF (instr, 34, 22);
1734 bool err = false;
1735
1736 if (eq)
1737 dinfo->fprintf_func (dinfo->stream, "br=byte[");
1738 else
1739 dinfo->fprintf_func (dinfo->stream, "br!=byte[");
1740
1741 if (nfp_me_is_imm_opnd8 (srcA))
1742 err = err || !nfp_me_print_opnd8 (srcB, 'B', num_ctx,
1743 src_lmext, imm_msb, dinfo);
1744 else
1745 err = err || !nfp_me_print_opnd8 (srcA, 'A', num_ctx,
1746 src_lmext, imm_msb, dinfo);
1747
1748 dinfo->fprintf_func (dinfo->stream, ", %d, ", by);
1749
1750 if (nfp_me_is_imm_opnd8 (srcA))
1751 err = err || !nfp_me_print_opnd8 (srcA, 'A', num_ctx,
1752 src_lmext, imm_msb, dinfo);
1753 else
1754 err = err || !nfp_me_print_opnd8 (srcB, 'B', num_ctx,
1755 src_lmext, imm_msb, dinfo);
1756
1757 dinfo->fprintf_func (dinfo->stream, ", .%d]", br_addr);
1758
1759 if (defer)
1760 dinfo->fprintf_func (dinfo->stream, ", defer[%d]", defer);
1761
1762 if (err)
1763 return _NFP_ERR_CONT;
1764 return 0;
1765 }
1766
1767 static int
1768 nfp_me27_28_print_br_bit (uint64_t instr, unsigned int src_lmext,
1769 int num_ctx, struct disassemble_info *dinfo)
1770 {
1771 unsigned int srcA = _BF (instr, 7, 0);
1772 unsigned int srcB = _BF (instr, 17, 10);
1773 unsigned int b = _BTST (instr, 18);
1774 unsigned int defer = _BF (instr, 21, 20);
1775 unsigned int br_addr = _BFS (instr, 40, 40, 13) | _BF (instr, 34, 22);
1776 bool err = false;
1777
1778 if (b)
1779 dinfo->fprintf_func (dinfo->stream, "br_bset[");
1780 else
1781 dinfo->fprintf_func (dinfo->stream, "br_bclr[");
1782
1783 if (nfp_me_is_imm_opnd8 (srcA))
1784 {
1785 err = err
1786 || !nfp_me_print_opnd8 (srcB, 'B', num_ctx, src_lmext, 0, dinfo);
1787 b = (nfp_me_imm_opnd8 (srcA, 0) - 1) & 0x1f;
1788 }
1789 else
1790 {
1791 err = err
1792 || !nfp_me_print_opnd8 (srcA, 'A', num_ctx, src_lmext, 0, dinfo);
1793 b = (nfp_me_imm_opnd8 (srcB, 0) - 1) & 0x1f;
1794 }
1795
1796 dinfo->fprintf_func (dinfo->stream, ", %d, .%d]", b, br_addr);
1797
1798 if (defer)
1799 dinfo->fprintf_func (dinfo->stream, ", defer[%d]", defer);
1800
1801 if (err)
1802 return _NFP_ERR_CONT;
1803 return 0;
1804 }
1805
1806 static int
1807 nfp_me27_28_print_br_alu (uint64_t instr, unsigned int src_lmext,
1808 int num_ctx, struct disassemble_info *dinfo)
1809 {
1810 unsigned int srcA = _BF (instr, 9, 0);
1811 unsigned int srcB = _BF (instr, 19, 10);
1812 unsigned int defer = _BF (instr, 21, 20);
1813 unsigned int imm = _BF (instr, 30, 22);
1814 bool err = false;
1815
1816 if (nfp_me_is_imm_opnd10 (srcA))
1817 imm = (imm << 8) | nfp_me_imm_opnd10 (srcA);
1818 else
1819 imm = (imm << 8) | nfp_me_imm_opnd10 (srcB);
1820
1821 if (!imm)
1822 dinfo->fprintf_func (dinfo->stream, "rtn[");
1823 else
1824 dinfo->fprintf_func (dinfo->stream, "jump[");
1825
1826 if (nfp_me_is_imm_opnd10 (srcA))
1827 err = err || !nfp_me_print_opnd10 (srcB, 'B', num_ctx, src_lmext, dinfo);
1828 else
1829 err = err || !nfp_me_print_opnd10 (srcA, 'A', num_ctx, src_lmext, dinfo);
1830
1831 if (imm)
1832 dinfo->fprintf_func (dinfo->stream, ", .%d", imm);
1833
1834 dinfo->fprintf_func (dinfo->stream, "]");
1835
1836 if (defer)
1837 dinfo->fprintf_func (dinfo->stream, ", defer[%d]", defer);
1838
1839 if (err)
1840 return _NFP_ERR_CONT;
1841 return 0;
1842 }
1843
1844 static int
1845 nfp_me27_28_print_mult (uint64_t instr, unsigned int pred_cc,
1846 unsigned int dst_lmext, unsigned int src_lmext,
1847 unsigned int gpr_wrboth,
1848 int num_ctx, struct disassemble_info *dinfo)
1849 {
1850 unsigned int srcA = _BF (instr, 9, 0);
1851 unsigned int srcB = _BF (instr, 19, 10);
1852 unsigned int mstep = _BF (instr, 22, 20);
1853 char dst_bank = 'A' + _BTST (instr, 23);
1854 unsigned int swap = _BTST (instr, 30);
1855 unsigned int mtype = _BF (instr, 32, 31);
1856 unsigned int nocc = _BTST (instr, 40);
1857 bool err = false;
1858
1859 if (swap)
1860 {
1861 unsigned int tmp = srcA;
1862 srcA = srcB;
1863 srcB = tmp;
1864 }
1865
1866 dinfo->fprintf_func (dinfo->stream, "mul_step[");
1867
1868 if (mstep >= 4)
1869 err = err
1870 || !nfp_me_print_opnd10 (srcA, dst_bank, num_ctx, dst_lmext, dinfo);
1871 else
1872 err = err || !nfp_me_print_opnd10 (srcA, (swap) ? 'B' : 'A', num_ctx,
1873 src_lmext, dinfo);
1874
1875 dinfo->fprintf_func (dinfo->stream, ", ");
1876
1877 if (mstep >= 4)
1878 dinfo->fprintf_func (dinfo->stream, "--");
1879 else
1880 err = err || !nfp_me_print_opnd10 (srcB, (swap) ? 'A' : 'B', num_ctx,
1881 src_lmext, dinfo);
1882
1883 dinfo->fprintf_func (dinfo->stream, "], %s", nfp_me27_28_mult_types[mtype]);
1884 if (mtype > 0)
1885 {
1886 const char *s = nfp_me27_28_mult_steps[mstep];
1887 if (!s)
1888 {
1889 s = "<invalid mul_step>";
1890 err = true;
1891 }
1892 dinfo->fprintf_func (dinfo->stream, "_%s", s);
1893 }
1894
1895 if (nocc)
1896 dinfo->fprintf_func (dinfo->stream, ", no_cc");
1897 if (gpr_wrboth)
1898 dinfo->fprintf_func (dinfo->stream, ", gpr_wrboth");
1899 if (pred_cc)
1900 dinfo->fprintf_func (dinfo->stream, ", predicate_cc");
1901
1902 if (err)
1903 return _NFP_ERR_CONT;
1904 return 0;
1905 }
1906
1907 static int
1908 _nfp_cmp_mnmnc (const void *arg_a, const void *arg_b)
1909 {
1910 const nfp_cmd_mnemonic *a = arg_a;
1911 const nfp_cmd_mnemonic *b = arg_b;
1912
1913 if (a->cpp_target != b->cpp_target)
1914 return (a->cpp_target > b->cpp_target) - (a->cpp_target < b->cpp_target);
1915
1916 if (a->cpp_action != b->cpp_action)
1917 return (a->cpp_action > b->cpp_action) - (a->cpp_action < b->cpp_action);
1918
1919 return (a->cpp_token > b->cpp_token) - (a->cpp_token < b->cpp_token);
1920 }
1921
1922 static const char *
1923 nfp_me_find_mnemonic (unsigned int cpp_tgt, unsigned int cpp_act,
1924 unsigned int cpp_tok, unsigned int cpp_len,
1925 const nfp_cmd_mnemonic * mnemonics,
1926 size_t mnemonics_cnt)
1927 {
1928 nfp_cmd_mnemonic search_key = { cpp_tgt, cpp_act, cpp_tok, 0, 0, NULL };
1929 const nfp_cmd_mnemonic *cmd = NULL;
1930
1931 cmd = bsearch (&search_key, mnemonics, mnemonics_cnt,
1932 sizeof (nfp_cmd_mnemonic), _nfp_cmp_mnmnc);
1933
1934 if (!cmd)
1935 return NULL;
1936
1937 /* Make sure we backtrack to the first entry that still matches the three
1938 bsearched fields - then we simply iterate and compare cpp_len. */
1939 while ((cmd > mnemonics) && (_nfp_cmp_mnmnc (&cmd[-1], &search_key) == 0))
1940 --cmd;
1941
1942 /* Now compare by cpp_len and make sure we stay in range. */
1943 for (; (cmd < (mnemonics + mnemonics_cnt))
1944 && (_nfp_cmp_mnmnc (cmd, &search_key) == 0); ++cmd)
1945 {
1946 if ((cpp_len & cmd->len_mask) == cmd->len_fixed)
1947 return cmd->mnemonic;
1948 }
1949
1950 return NULL;
1951 }
1952
1953 /* NFP-32xx (ME Version 2.7). */
1954
1955 static int
1956 nfp_me27_print_cmd (uint64_t instr, int third_party_32bit,
1957 int num_ctx, struct disassemble_info *dinfo)
1958 {
1959 unsigned int srcA = _BF (instr, 7, 0);
1960 unsigned int ctxswap_defer = _BF (instr, 9, 8);
1961 unsigned int srcB = _BF (instr, 17, 10);
1962 unsigned int token = _BF (instr, 19, 18);
1963 unsigned int xfer = _BFS (instr, 40, 40, 5) | _BF (instr, 24, 20);
1964 unsigned int cpp_len = _BF (instr, 27, 25);
1965 unsigned int sig = _BF (instr, 31, 28);
1966 unsigned int tgtcmd = _BF (instr, 38, 32);
1967 unsigned int indref = _BTST (instr, 41);
1968 unsigned int mode = _BF (instr, 44, 42);
1969
1970 bool err = false;
1971 int cpp_target = -1;
1972 int cpp_action = -1;
1973 const char *mnemonic = NULL;
1974 unsigned int imm;
1975 unsigned int valBA;
1976 int visswap = ((mode == 1) || (mode == 3));
1977
1978 imm = (sig << 10) | (cpp_len << 7) | ((xfer & 0x1f) << 2) | token;
1979 valBA = (srcB << 8) | srcA;
1980
1981 if (mode == 6)
1982 {
1983 token = 0;
1984 sig = 0;
1985 xfer = 0;
1986 }
1987
1988 /* Convert tgtcmd to action/token tuple. */
1989 if (_BF (tgtcmd, 6, 5) == 0x0)
1990 {
1991 switch (_BF (tgtcmd, 4, 2))
1992 {
1993 case 0:
1994 cpp_target = NFP_3200_CPPTGT_CAP;
1995 dinfo->fprintf_func (dinfo->stream, "cap[");
1996 break;
1997 case 1:
1998 cpp_target = NFP_3200_CPPTGT_MSF0;
1999 dinfo->fprintf_func (dinfo->stream, "msf0[");
2000 break;
2001 case 2:
2002 cpp_target = NFP_3200_CPPTGT_MSF1;
2003 dinfo->fprintf_func (dinfo->stream, "msf1[");
2004 break;
2005 case 3:
2006 cpp_target = NFP_3200_CPPTGT_PCIE;
2007 dinfo->fprintf_func (dinfo->stream, "pcie[");
2008 break;
2009 case 4:
2010 cpp_target = NFP_3200_CPPTGT_HASH;
2011 break;
2012 case 5:
2013 cpp_target = NFP_3200_CPPTGT_CRYPTO;
2014 dinfo->fprintf_func (dinfo->stream, "crypto[");
2015 break;
2016 case 6:
2017 cpp_target = NFP_3200_CPPTGT_ARM;
2018 dinfo->fprintf_func (dinfo->stream, "arm[");
2019 break;
2020 case 7:
2021 cpp_target = NFP_3200_CPPTGT_CT;
2022 dinfo->fprintf_func (dinfo->stream, "ct[");
2023 break;
2024 }
2025 cpp_action = _BF (tgtcmd, 1, 0);
2026 }
2027 else
2028 {
2029 switch (_BF (tgtcmd, 6, 4))
2030 {
2031 case 2:
2032 cpp_target = NFP_3200_CPPTGT_GS;
2033 dinfo->fprintf_func (dinfo->stream, "scratch[");
2034 break;
2035 case 3:
2036 cpp_target = NFP_3200_CPPTGT_QDR; /* A.k.a. SRAM. */
2037 dinfo->fprintf_func (dinfo->stream, "sram[");
2038 break;
2039 case 4:
2040 case 5:
2041 cpp_target = NFP_3200_CPPTGT_MU;
2042 dinfo->fprintf_func (dinfo->stream, "mem[");
2043 break;
2044 case 6:
2045 case 7:
2046 cpp_target = NFP_3200_CPPTGT_CLS;
2047 dinfo->fprintf_func (dinfo->stream, "cls[");
2048 break;
2049 }
2050 cpp_action = _BF (tgtcmd, 3, 0);
2051 }
2052
2053 if (cpp_target < 0)
2054 {
2055 dinfo->fprintf_func (dinfo->stream, _("<invalid cmd target %d:%d:%d>[]"),
2056 cpp_target, cpp_action, token);
2057 return _NFP_ERR_CONT;
2058 }
2059
2060 mnemonic = nfp_me_find_mnemonic (cpp_target, cpp_action, token, cpp_len,
2061 nfp_me27_mnemonics,
2062 ARRAY_SIZE (nfp_me27_mnemonics));
2063
2064 if (!mnemonic)
2065 {
2066 dinfo->fprintf_func (dinfo->stream, _("<invalid cmd action %d:%d:%d>[]"),
2067 cpp_target, cpp_action, token);
2068 return _NFP_ERR_CONT;
2069 }
2070
2071 if (cpp_target == NFP_3200_CPPTGT_HASH)
2072 {
2073 dinfo->fprintf_func (dinfo->stream, "%s[$xfer_%d, %d",
2074 mnemonic, xfer, cpp_len);
2075 goto print_opt_toks;
2076 }
2077
2078 dinfo->fprintf_func (dinfo->stream, "%s, ", mnemonic);
2079
2080 if (visswap)
2081 {
2082 unsigned int tmp = srcA;
2083 srcA = srcB;
2084 srcB = tmp;
2085 }
2086
2087 switch (mode)
2088 {
2089 case 0: /* (A << 8) + B. */
2090 case 1: /* (B << 8) + A. */
2091 dinfo->fprintf_func (dinfo->stream, "$xfer_%d, ", xfer);
2092 err = err
2093 || !nfp_me_print_opnd8 (srcA, 'A' + visswap, num_ctx, 0, 0, dinfo);
2094 dinfo->fprintf_func (dinfo->stream, ", <<8, ");
2095 err = err
2096 || !nfp_me_print_opnd8 (srcB, 'B' - visswap, num_ctx, 0, 0, dinfo);
2097 dinfo->fprintf_func (dinfo->stream, ", %d", (cpp_len + 1));
2098 break;
2099 case 2: /* Accelerated 3rd party (A[ << 8]) + B. */
2100 case 3: /* Accelerated 3rd party (B[ << 8]) + A. */
2101 dinfo->fprintf_func (dinfo->stream, "0x%x, ", (indref << 6) | xfer);
2102 err = err
2103 || !nfp_me_print_opnd8 (srcA, 'A' + visswap, num_ctx, 0, 0, dinfo);
2104 if (third_party_32bit)
2105 dinfo->fprintf_func (dinfo->stream, ", ");
2106 else
2107 dinfo->fprintf_func (dinfo->stream, ", <<8, ");
2108 err = err
2109 || !nfp_me_print_opnd8 (srcB, 'B' - visswap, num_ctx, 0, 0, dinfo);
2110 dinfo->fprintf_func (dinfo->stream, ", %d", (cpp_len + 1));
2111 break;
2112 case 4: /* A + B. */
2113 dinfo->fprintf_func (dinfo->stream, "$xfer_%d, ", xfer);
2114 err = err || !nfp_me_print_opnd8 (srcA, 'A', num_ctx, 0, 0, dinfo);
2115 dinfo->fprintf_func (dinfo->stream, ", ");
2116 err = err || !nfp_me_print_opnd8 (srcB, 'B', num_ctx, 0, 0, dinfo);
2117 dinfo->fprintf_func (dinfo->stream, ", %d", (cpp_len + 1));
2118 break;
2119 case 5: /* Immediate address. */
2120 dinfo->fprintf_func (dinfo->stream, "$xfer_%d, 0x%x, %d", xfer, valBA,
2121 (cpp_len + 1));
2122 break;
2123 case 6: /* Immediate address and data. */
2124 dinfo->fprintf_func (dinfo->stream, "0x%x, 0x%x", valBA, imm);
2125 break;
2126 case 7: /* Immediate data. */
2127 dinfo->fprintf_func (dinfo->stream, "0x%x, --, %d",
2128 ((xfer << 16) | valBA), (cpp_len + 1));
2129 break;
2130 }
2131
2132 print_opt_toks:
2133 dinfo->fprintf_func (dinfo->stream, "]");
2134
2135 if (indref && (mode != 2) && (mode != 3))
2136 dinfo->fprintf_func (dinfo->stream, ", indirect_ref");
2137
2138 if (ctxswap_defer != 3)
2139 {
2140 dinfo->fprintf_func (dinfo->stream, ", ctx_swap[");
2141 if (sig)
2142 dinfo->fprintf_func (dinfo->stream, "sig%d]", sig);
2143 else
2144 dinfo->fprintf_func (dinfo->stream, "--]");
2145
2146 if (ctxswap_defer != 0)
2147 dinfo->fprintf_func (dinfo->stream, ", defer[%d]", ctxswap_defer);
2148 }
2149 else if (sig)
2150 dinfo->fprintf_func (dinfo->stream, ", sig_done[sig%d]", sig);
2151
2152 if (err)
2153 return _NFP_ERR_CONT;
2154 return 0;
2155 }
2156
2157 static int
2158 nfp_me27_print_alu_shf (uint64_t instr, int num_ctx,
2159 struct disassemble_info *dinfo)
2160 {
2161 return nfp_me27_28_print_alu_shf (instr, 0, 0, 0, 0, num_ctx, dinfo);
2162 }
2163
2164 static int
2165 nfp_me27_print_alu (uint64_t instr, int num_ctx,
2166 struct disassemble_info *dinfo)
2167 {
2168 return nfp_me27_28_print_alu_shf (instr, 0, 0, 0, 0, num_ctx, dinfo);
2169 }
2170
2171 static int
2172 nfp_me27_print_immed (uint64_t instr, int num_ctx,
2173 struct disassemble_info *dinfo)
2174 {
2175 return nfp_me27_28_print_immed (instr, 0, 0, 0, num_ctx, dinfo);
2176 }
2177
2178 static int
2179 nfp_me27_print_ld_field (uint64_t instr, int num_ctx,
2180 struct disassemble_info *dinfo)
2181 {
2182 return nfp_me27_28_print_ld_field (instr, 0, 0, 0, 0, num_ctx, dinfo);
2183 }
2184
2185 static int
2186 nfp_me27_print_ctx_arb (uint64_t instr, struct disassemble_info *dinfo)
2187 {
2188 return nfp_me27_28_print_ctx_arb (instr, dinfo);
2189 }
2190
2191 static int
2192 nfp_me27_print_local_csr (uint64_t instr, int num_ctx,
2193 struct disassemble_info *dinfo)
2194 {
2195 return nfp_me27_28_print_local_csr (instr, 0, num_ctx, dinfo);
2196 }
2197
2198 static int
2199 nfp_me27_print_branch (uint64_t instr, struct disassemble_info *dinfo)
2200 {
2201 return nfp_me27_28_print_branch (instr, nfp_me27_br_inpstates, dinfo);
2202 }
2203
2204 static int
2205 nfp_me27_print_br_byte (uint64_t instr, int num_ctx,
2206 struct disassemble_info *dinfo)
2207 {
2208 return nfp_me27_28_print_br_byte (instr, 0, num_ctx, dinfo);
2209 }
2210
2211 static int
2212 nfp_me27_print_br_bit (uint64_t instr, int num_ctx,
2213 struct disassemble_info *dinfo)
2214 {
2215 return nfp_me27_28_print_br_bit (instr, 0, num_ctx, dinfo);
2216 }
2217
2218 static int
2219 nfp_me27_print_br_alu (uint64_t instr, int num_ctx,
2220 struct disassemble_info *dinfo)
2221 {
2222 return nfp_me27_28_print_br_alu (instr, 0, num_ctx, dinfo);
2223 }
2224
2225 static int
2226 nfp_me27_print_mult (uint64_t instr, int num_ctx,
2227 struct disassemble_info *dinfo)
2228 {
2229 return nfp_me27_28_print_mult (instr, 0, 0, 0, 0, num_ctx, dinfo);
2230 }
2231
2232 /*NFP-6xxx/4xxx (ME Version 2.8). */
2233
2234 static int
2235 nfp_me28_print_cmd (uint64_t instr, int third_party_32bit,
2236 int num_ctx, struct disassemble_info *dinfo)
2237 {
2238 unsigned int srcA = _BF (instr, 7, 0);
2239 unsigned int ctxswap_defer = _BF (instr, 9, 8);
2240 unsigned int srcB = _BF (instr, 17, 10);
2241 unsigned int token = _BF (instr, 19, 18);
2242 unsigned int xfer = _BFS (instr, 40, 40, 5) | _BF (instr, 24, 20);
2243 unsigned int cpp_len = _BF (instr, 27, 25);
2244 unsigned int sig = _BF (instr, 31, 28);
2245 unsigned int tgtcmd = _BF (instr, 38, 32);
2246 unsigned int indref = _BTST (instr, 41);
2247 unsigned int mode = _BF (instr, 44, 42);
2248
2249 bool err = false;
2250 int cpp_target = -1;
2251 int cpp_action = -1;
2252 const char *mnemonic = NULL;
2253 unsigned int imm;
2254 unsigned int valBA;
2255 int visswap = ((mode == 1) || (mode == 3));
2256
2257 imm = (sig << 10) | (cpp_len << 7) | ((xfer & 0x1f) << 2) | token;
2258 valBA = (srcB << 8) | srcA;
2259
2260 if (mode == 6)
2261 {
2262 token = 0;
2263 sig = 0;
2264 xfer = 0;
2265 }
2266
2267 /* Convert tgtcmd to action/token tuple. */
2268 if (_BF (tgtcmd, 6, 5) == 0x0)
2269 {
2270 switch (_BF (tgtcmd, 4, 2))
2271 {
2272 case 0:
2273 cpp_target = NFP_6000_CPPTGT_ILA;
2274 dinfo->fprintf_func (dinfo->stream, "ila[");
2275 break;
2276 case 1:
2277 cpp_target = NFP_6000_CPPTGT_NBI;
2278 dinfo->fprintf_func (dinfo->stream, "nbi[");
2279 break;
2280 case 3:
2281 cpp_target = NFP_6000_CPPTGT_PCIE;
2282 dinfo->fprintf_func (dinfo->stream, "pcie[");
2283 break;
2284 case 5:
2285 cpp_target = NFP_6000_CPPTGT_CRYPTO;
2286 dinfo->fprintf_func (dinfo->stream, "crypto[");
2287 break;
2288 case 6:
2289 cpp_target = NFP_6000_CPPTGT_ARM;
2290 dinfo->fprintf_func (dinfo->stream, "arm[");
2291 break;
2292 case 7:
2293 cpp_target = NFP_6000_CPPTGT_CTXPB;
2294 dinfo->fprintf_func (dinfo->stream, "ct[");
2295 break;
2296 }
2297 cpp_action = _BF (tgtcmd, 1, 0);
2298 }
2299 else
2300 {
2301 /* One bit overlap between "t" and "a" fields, for sram it's "t" and
2302 for mem/cls it's "a". */
2303 cpp_action = _BF (tgtcmd, 4, 0);
2304 switch (_BF (tgtcmd, 6, 4))
2305 {
2306 case 3:
2307 cpp_target = NFP_6000_CPPTGT_VQDR;
2308 cpp_action = _BF (tgtcmd, 3, 0);
2309 dinfo->fprintf_func (dinfo->stream, "sram[");
2310 break;
2311 case 4:
2312 case 5:
2313 cpp_target = NFP_6000_CPPTGT_MU;
2314 dinfo->fprintf_func (dinfo->stream, "mem[");
2315 break;
2316 case 6:
2317 case 7:
2318 cpp_target = NFP_6000_CPPTGT_CLS;
2319 dinfo->fprintf_func (dinfo->stream, "cls[");
2320 break;
2321 }
2322 }
2323
2324 if (cpp_target < 0)
2325 {
2326 dinfo->fprintf_func (dinfo->stream, _("<invalid cmd target %d:%d:%d>[]"),
2327 cpp_target, cpp_action, token);
2328 return _NFP_ERR_CONT;
2329 }
2330
2331 mnemonic = nfp_me_find_mnemonic (cpp_target, cpp_action, token, cpp_len,
2332 nfp_me28_mnemonics,
2333 ARRAY_SIZE (nfp_me28_mnemonics));
2334
2335 if (!mnemonic)
2336 {
2337 dinfo->fprintf_func (dinfo->stream, _("<invalid cmd action %d:%d:%d>[]"),
2338 cpp_target, cpp_action, token);
2339 return _NFP_ERR_CONT;
2340 }
2341
2342 dinfo->fprintf_func (dinfo->stream, "%s, ", mnemonic);
2343
2344 if (visswap)
2345 {
2346 unsigned int tmp = srcA;
2347 srcA = srcB;
2348 srcB = tmp;
2349 }
2350
2351 switch (mode)
2352 {
2353 case 0: /* (A << 8) + B. */
2354 case 1: /* (B << 8) + A. */
2355 dinfo->fprintf_func (dinfo->stream, "$xfer_%d, ", xfer);
2356 err = err
2357 || !nfp_me_print_opnd8 (srcA, 'A' + visswap, num_ctx, 0, 0, dinfo);
2358 dinfo->fprintf_func (dinfo->stream, ", <<8, ");
2359 err = err
2360 || !nfp_me_print_opnd8 (srcB, 'B' - visswap, num_ctx, 0, 0, dinfo);
2361 dinfo->fprintf_func (dinfo->stream, ", %d", (cpp_len + 1));
2362 break;
2363 case 2: /* Accelerated 3rd party (A[ << 8]) + B. */
2364 case 3: /* Accelerated 3rd party (B[ << 8]) + A. */
2365 dinfo->fprintf_func (dinfo->stream, "0x%x, ", (indref << 6) | xfer);
2366 err = err
2367 || !nfp_me_print_opnd8 (srcA, 'A' + visswap, num_ctx, 0, 0, dinfo);
2368 if (third_party_32bit)
2369 dinfo->fprintf_func (dinfo->stream, ", ");
2370 else
2371 dinfo->fprintf_func (dinfo->stream, ", <<8, ");
2372 err = err
2373 || !nfp_me_print_opnd8 (srcB, 'B' - visswap, num_ctx, 0, 0, dinfo);
2374 dinfo->fprintf_func (dinfo->stream, ", %d", (cpp_len + 1));
2375 break;
2376 case 4: /* A + B. */
2377 dinfo->fprintf_func (dinfo->stream, "$xfer_%d, ", xfer);
2378 err = err || !nfp_me_print_opnd8 (srcA, 'A', num_ctx, 0, 0, dinfo);
2379 dinfo->fprintf_func (dinfo->stream, ", ");
2380 err = err || !nfp_me_print_opnd8 (srcB, 'B', num_ctx, 0, 0, dinfo);
2381 dinfo->fprintf_func (dinfo->stream, ", %d", (cpp_len + 1));
2382 break;
2383 case 5: /* Immediate address. */
2384 dinfo->fprintf_func (dinfo->stream, "$xfer_%d, 0x%x, %d", xfer, valBA,
2385 (cpp_len + 1));
2386 break;
2387 case 6: /* Immediate address and data. */
2388 dinfo->fprintf_func (dinfo->stream, "0x%x, 0x%x", valBA, imm);
2389 break;
2390 case 7: /* Immediate data. */
2391 dinfo->fprintf_func (dinfo->stream, "0x%x, --, %d",
2392 ((xfer << 16) | valBA), (cpp_len + 1));
2393 break;
2394 }
2395
2396 dinfo->fprintf_func (dinfo->stream, "]");
2397
2398 if (indref && (mode != 2) && (mode != 3))
2399 dinfo->fprintf_func (dinfo->stream, ", indirect_ref");
2400
2401 if (ctxswap_defer != 3)
2402 {
2403 dinfo->fprintf_func (dinfo->stream, ", ctx_swap[");
2404 if (sig)
2405 dinfo->fprintf_func (dinfo->stream, "sig%d]", sig);
2406 else
2407 dinfo->fprintf_func (dinfo->stream, "--]");
2408
2409 if (ctxswap_defer != 0)
2410 dinfo->fprintf_func (dinfo->stream, ", defer[%d]", ctxswap_defer);
2411 }
2412 else if (sig)
2413 dinfo->fprintf_func (dinfo->stream, ", sig_done[sig%d]", sig);
2414
2415 if (err)
2416 return _NFP_ERR_CONT;
2417 return 0;
2418 }
2419
2420 static int
2421 nfp_me28_print_alu_shf (uint64_t instr, int num_ctx,
2422 struct disassemble_info *dinfo)
2423 {
2424 unsigned int gpr_wrboth = _BTST (instr, 41);
2425 unsigned int src_lmext = _BTST (instr, 42);
2426 unsigned int dst_lmext = _BTST (instr, 43);
2427 unsigned int pred_cc = _BTST (instr, 44);
2428
2429 return nfp_me27_28_print_alu_shf (instr, pred_cc, dst_lmext,
2430 src_lmext, gpr_wrboth, num_ctx, dinfo);
2431 }
2432
2433 static int
2434 nfp_me28_print_alu (uint64_t instr, int num_ctx,
2435 struct disassemble_info *dinfo)
2436 {
2437 unsigned int gpr_wrboth = _BTST (instr, 41);
2438 unsigned int src_lmext = _BTST (instr, 42);
2439 unsigned int dst_lmext = _BTST (instr, 43);
2440 unsigned int pred_cc = _BTST (instr, 44);
2441
2442 return nfp_me27_28_print_alu (instr, pred_cc, dst_lmext, src_lmext,
2443 gpr_wrboth, num_ctx, dinfo);
2444 }
2445
2446 static int
2447 nfp_me28_print_immed (uint64_t instr, int num_ctx,
2448 struct disassemble_info *dinfo)
2449 {
2450 unsigned int gpr_wrboth = _BTST (instr, 41);
2451 unsigned int dst_lmext = _BTST (instr, 43);
2452 unsigned int pred_cc = _BTST (instr, 44);
2453
2454 return nfp_me27_28_print_immed (instr, pred_cc, dst_lmext, gpr_wrboth,
2455 num_ctx, dinfo);
2456 }
2457
2458 static int
2459 nfp_me28_print_ld_field (uint64_t instr, int num_ctx,
2460 struct disassemble_info *dinfo)
2461 {
2462 unsigned int gpr_wrboth = _BTST (instr, 41);
2463 unsigned int src_lmext = _BTST (instr, 42);
2464 unsigned int dst_lmext = _BTST (instr, 43);
2465 unsigned int pred_cc = _BTST (instr, 44);
2466
2467 return nfp_me27_28_print_ld_field (instr, pred_cc, dst_lmext,
2468 src_lmext, gpr_wrboth, num_ctx, dinfo);
2469 }
2470
2471 static int
2472 nfp_me28_print_ctx_arb (uint64_t instr, struct disassemble_info *dinfo)
2473 {
2474 return nfp_me27_28_print_ctx_arb (instr, dinfo);
2475 }
2476
2477 static int
2478 nfp_me28_print_local_csr (uint64_t instr, int num_ctx,
2479 struct disassemble_info *dinfo)
2480 {
2481 unsigned int src_lmext = _BTST (instr, 42);
2482
2483 return nfp_me27_28_print_local_csr (instr, src_lmext, num_ctx, dinfo);
2484 }
2485
2486 static int
2487 nfp_me28_print_branch (uint64_t instr, struct disassemble_info *dinfo)
2488 {
2489 return nfp_me27_28_print_branch (instr, nfp_me28_br_inpstates, dinfo);
2490 }
2491
2492 static int
2493 nfp_me28_print_br_byte (uint64_t instr, int num_ctx,
2494 struct disassemble_info *dinfo)
2495 {
2496 unsigned int src_lmext = _BTST (instr, 42);
2497 return nfp_me27_28_print_br_byte (instr, src_lmext, num_ctx, dinfo);
2498 }
2499
2500 static int
2501 nfp_me28_print_br_bit (uint64_t instr, int num_ctx,
2502 struct disassemble_info *dinfo)
2503 {
2504 unsigned int src_lmext = _BTST (instr, 42);
2505 return nfp_me27_28_print_br_bit (instr, src_lmext, num_ctx, dinfo);
2506 }
2507
2508 static int
2509 nfp_me28_print_br_alu (uint64_t instr, int num_ctx,
2510 struct disassemble_info *dinfo)
2511 {
2512 unsigned int src_lmext = _BTST (instr, 42);
2513 return nfp_me27_28_print_br_alu (instr, src_lmext, num_ctx, dinfo);
2514 }
2515
2516 static int
2517 nfp_me28_print_mult (uint64_t instr, int num_ctx,
2518 struct disassemble_info *dinfo)
2519 {
2520 unsigned int gpr_wrboth = _BTST (instr, 41);
2521 unsigned int src_lmext = _BTST (instr, 42);
2522 unsigned int dst_lmext = _BTST (instr, 43);
2523 unsigned int pred_cc = _BTST (instr, 44);
2524
2525 return nfp_me27_28_print_mult (instr, pred_cc, dst_lmext, src_lmext,
2526 gpr_wrboth, num_ctx, dinfo);
2527 }
2528
2529 static bool
2530 init_nfp3200_priv (nfp_priv_data * priv, struct disassemble_info *dinfo)
2531 {
2532 Elf_Internal_Shdr *sec = NULL;
2533 Elf_Nfp_MeConfig mecfg_ent;
2534 unsigned char buffer[sizeof (Elf_Nfp_MeConfig)];
2535 file_ptr roff = 0;
2536 unsigned int sec_cnt = 0;
2537 unsigned int sec_idx;
2538 size_t menum_linear = 0;
2539
2540 if (!dinfo->section)
2541 /* No section info, will use default values. */
2542 return true;
2543
2544 sec_cnt = elf_numsections (dinfo->section->owner);
2545
2546 /* Find the MECONFIG section. It's index is also in e_flags, but it has
2547 a unique SHT and we'll use that. */
2548 for (sec_idx = 0; sec_idx < sec_cnt; sec_idx++)
2549 {
2550 sec = elf_elfsections (dinfo->section->owner)[sec_idx];
2551
2552 if (sec->sh_type == SHT_NFP_MECONFIG)
2553 break;
2554 }
2555
2556 if (sec_idx == sec_cnt)
2557 {
2558 dinfo->fprintf_func (dinfo->stream, _("File has no ME-Config section."));
2559 return false;
2560 }
2561
2562 for (roff = 0; (bfd_size_type) roff < sec->sh_size;
2563 roff += sec->sh_entsize, menum_linear++)
2564 {
2565 nfp_priv_mecfg *mecfg;
2566 int isl = menum_linear >> 3;
2567 int menum = menum_linear & 7;
2568
2569 if (menum_linear >= 40)
2570 {
2571 dinfo->fprintf_func (dinfo->stream,
2572 _("File has invalid ME-Config section."));
2573 return false;
2574 }
2575
2576 mecfg = &priv->mecfgs[isl][menum][1];
2577
2578 if (!bfd_get_section_contents (dinfo->section->owner, sec->bfd_section,
2579 buffer, roff, sizeof (buffer)))
2580 return false;
2581
2582 mecfg_ent.ctx_enables = bfd_getl32 (buffer + offsetof (Elf_Nfp_MeConfig,
2583 ctx_enables));
2584 mecfg_ent.misc_control = bfd_getl32 (buffer
2585 + offsetof (Elf_Nfp_MeConfig, misc_control));
2586
2587 mecfg->ctx4_mode = _BTST (mecfg_ent.ctx_enables, 31);
2588 mecfg->addr_3rdparty32 = _BTST (mecfg_ent.misc_control, 4);
2589 mecfg->scs_cnt = _BTST (mecfg_ent.misc_control, 2);
2590 }
2591
2592 return true;
2593 }
2594
2595 static bool
2596 init_nfp6000_mecsr_sec (nfp_priv_data * priv, Elf_Internal_Shdr * sec,
2597 bool is_for_text, struct disassemble_info *dinfo)
2598 {
2599 Elf_Nfp_InitRegEntry ireg;
2600 unsigned char buffer[sizeof (Elf_Nfp_InitRegEntry)];
2601 file_ptr ireg_off = 0;
2602 size_t isl, menum;
2603
2604 if (sec->sh_entsize != sizeof (ireg))
2605 return false;
2606
2607 isl = SHI_NFP_IREG_ISLAND (sec->sh_info);
2608
2609 /* For these sections we know that the address will only be 32 bits
2610 so we only need cpp_offset_lo.
2611 Address is encoded as follows:
2612 <31:30> 0
2613 <29:24> island (already got this from sh_info)
2614 <23:17> 0
2615 <16:16> XferCsrRegSel (1 for these sections)
2616 <15:14> 0
2617 <13:10> DataMasterID (MEnum = this - 4)
2618 <9:2> register (index)
2619 <1:0> 0b0 (register byte address if appened to the previous field). */
2620 for (ireg_off = 0; (bfd_size_type) ireg_off < sec->sh_size;
2621 ireg_off += sec->sh_entsize)
2622 {
2623 uint32_t csr_off;
2624 nfp_priv_mecfg *mecfg;
2625
2626 if (!bfd_get_section_contents (dinfo->section->owner, sec->bfd_section,
2627 buffer, ireg_off, sizeof (buffer)))
2628 return false;
2629
2630 ireg.cpp_offset_lo = bfd_getl32 (buffer
2631 + offsetof (Elf_Nfp_InitRegEntry, cpp_offset_lo));
2632 ireg.mask = bfd_getl32 (buffer + offsetof (Elf_Nfp_InitRegEntry, mask));
2633 ireg.val = bfd_getl32 (buffer + offsetof (Elf_Nfp_InitRegEntry, val));
2634 ireg.w0 = bfd_getl32 (buffer + offsetof (Elf_Nfp_InitRegEntry, w0));
2635
2636 if (NFP_IREG_ENTRY_WO_NLW (ireg.w0))
2637 continue;
2638
2639 /* Only consider entries that are permanent for runtime. */
2640 if ((NFP_IREG_ENTRY_WO_VTP (ireg.w0) != NFP_IREG_VTP_CONST)
2641 && (NFP_IREG_ENTRY_WO_VTP (ireg.w0) != NFP_IREG_VTP_FORCE))
2642 continue;
2643
2644 menum = _BF (ireg.cpp_offset_lo, 13, 10) - 4;
2645 csr_off = _BF (ireg.cpp_offset_lo, 9, 0);
2646
2647 if (isl >= _NFP_ISLAND_MAX || menum >= _NFP_ME_MAX)
2648 return false;
2649
2650 mecfg = &priv->mecfgs[isl][menum][is_for_text];
2651 switch (csr_off)
2652 {
2653 case _NFP_ME27_28_CSR_CTX_ENABLES:
2654 mecfg->ctx4_mode = _BTST (ireg.val, 31);
2655 break;
2656 case _NFP_ME27_28_CSR_MISC_CONTROL:
2657 mecfg->addr_3rdparty32 = _BTST (ireg.val, 4);
2658 mecfg->scs_cnt = _BTST (ireg.val, 2);
2659 break;
2660 default:
2661 break;
2662 }
2663 }
2664
2665 return true;
2666 }
2667
2668 static bool
2669 init_nfp6000_priv (nfp_priv_data * priv, struct disassemble_info *dinfo)
2670 {
2671 int mecfg_orders[64][2];
2672 size_t isl;
2673 unsigned int sec_cnt = 0;
2674 unsigned int sec_idx;
2675 bool is_for_text;
2676
2677 memset (mecfg_orders, -1, sizeof (mecfg_orders));
2678
2679 if (!dinfo->section)
2680 /* No section info, will use default values. */
2681 return true;
2682
2683 sec_cnt = elf_numsections (dinfo->section->owner);
2684
2685 /* Go through all MECSR init sections to find ME configs. */
2686 for (sec_idx = 0; sec_idx < sec_cnt; sec_idx++)
2687 {
2688 Elf_Internal_Shdr *sec;
2689 int sec_order;
2690
2691 sec = elf_elfsections (dinfo->section->owner)[sec_idx];
2692 sec_order = (int) SHI_NFP_IREG_ORDER (sec->sh_info);
2693
2694 is_for_text = (sec->sh_flags & (SHF_NFP_INIT | SHF_NFP_INIT2)) == 0;
2695
2696 /* If we have an init2 section, that is the one that applies to the
2697 ME when executing init code. So we make it's order higher than
2698 any plain init section. */
2699 if (sec->sh_flags & SHF_NFP_INIT2)
2700 sec_order += SHI_NFP_IREG_ORDER (~0U) + 1;
2701
2702 if (sec->sh_type != SHT_NFP_INITREG)
2703 continue;
2704 if (!SHI_NFP_6000_IS_IREG_MECSR (sec->sh_info))
2705 continue;
2706
2707 isl = SHI_NFP_IREG_ISLAND (sec->sh_info);
2708 if ((sec_order < mecfg_orders[isl][is_for_text]))
2709 /* Lower order or transient, skip it. */
2710 continue;
2711
2712 mecfg_orders[isl][is_for_text] = sec_order;
2713
2714 if (!init_nfp6000_mecsr_sec (priv, sec, is_for_text, dinfo))
2715 {
2716 dinfo->fprintf_func (dinfo->stream,
2717 _("Error processing section %u "), sec_idx);
2718 return false;
2719 }
2720 }
2721
2722 return true;
2723 }
2724
2725 static int
2726 parse_disassembler_options (nfp_opts * opts, struct disassemble_info *dinfo)
2727 {
2728 const char *option;
2729
2730 if (dinfo->disassembler_options == NULL)
2731 return 0;
2732
2733 FOR_EACH_DISASSEMBLER_OPTION (option, dinfo->disassembler_options)
2734 {
2735 if (disassembler_options_cmp (option, "no-pc") == 0)
2736 opts->show_pc = 0;
2737 else if (disassembler_options_cmp (option, "ctx4") == 0)
2738 {
2739 if (!opts->ctx_mode)
2740 opts->ctx_mode = 4;
2741 }
2742 else if (disassembler_options_cmp (option, "ctx8") == 0)
2743 opts->ctx_mode = 8;
2744 else
2745 {
2746 dinfo->fprintf_func (dinfo->stream, _("Invalid NFP option: %s"), option);
2747 return _NFP_ERR_STOP;
2748 }
2749 }
2750
2751 return 0;
2752 }
2753
2754 /* Called on first disassembly attempt so that dinfo->section is valid
2755 so that we can get the bfd owner to find ME configs. */
2756
2757 static nfp_priv_data *
2758 init_nfp_priv (struct disassemble_info *dinfo)
2759 {
2760 nfp_priv_data *priv;
2761 int ret = false;
2762
2763 if (dinfo->private_data)
2764 return (nfp_priv_data *) dinfo->private_data;
2765
2766 #if 0 /* Right now only section-related info is kept in priv.
2767 So don't even calloc it if we don't need it. */
2768 if (!dinfo->section)
2769 return NULL;
2770 #endif
2771
2772 /* Alloc with no free, seems to be either this or a static global variable
2773 and this at least keeps a large struct unallocated until really needed. */
2774 priv = calloc (1, sizeof (*priv));
2775 if (!priv)
2776 return NULL;
2777
2778 switch (dinfo->mach)
2779 {
2780 case E_NFP_MACH_3200:
2781 ret = init_nfp3200_priv (priv, dinfo);
2782 break;
2783 case E_NFP_MACH_6000:
2784 ret = init_nfp6000_priv (priv, dinfo);
2785 break;
2786 }
2787
2788 if (!ret)
2789 {
2790 free (priv);
2791 return NULL;
2792 }
2793
2794 dinfo->private_data = priv;
2795 return priv;
2796 }
2797
2798 static int
2799 _print_instrs (bfd_vma addr, struct disassemble_info *dinfo, nfp_opts * opts)
2800 {
2801 nfp_priv_data *priv = init_nfp_priv (dinfo);
2802 bfd_byte buffer[8];
2803 int err;
2804 uint64_t instr = 0;
2805 size_t island, menum;
2806 int num_ctx, scs_cnt, addr_3rdparty32, pc, tmpi, tmpj;
2807 int is_text = 1;
2808
2809 err = dinfo->read_memory_func (addr, buffer, 8, dinfo);
2810 if (err)
2811 return _NFP_ERR_STOP;
2812
2813 if (!dinfo->section)
2814 {
2815 num_ctx = 8;
2816 scs_cnt = 0;
2817 addr_3rdparty32 = 0;
2818 }
2819 else
2820 {
2821 unsigned int sh_info = 0;
2822 nfp_priv_mecfg *mecfg;
2823
2824 /* We have a section, presumably all ELF sections. Try to find
2825 proper ME configs to produce better disassembly. */
2826 if (!priv)
2827 return _NFP_ERR_STOP; /* Sanity check */
2828
2829 is_text = (elf_section_flags (dinfo->section)
2830 & (SHF_NFP_INIT | SHF_NFP_INIT2)) == 0;
2831
2832 sh_info = elf_section_info (dinfo->section);
2833
2834 switch (dinfo->mach)
2835 {
2836 case E_NFP_MACH_3200:
2837 island = SHI_NFP_3200_ISLAND (sh_info);
2838 menum = SHI_NFP_3200_MENUM (sh_info);
2839 break;
2840 default:
2841 island = SHI_NFP_ISLAND (sh_info);
2842 menum = SHI_NFP_MENUM (sh_info);
2843 break;
2844 }
2845
2846 if (island >= _NFP_ISLAND_MAX || menum >= _NFP_ME_MAX)
2847 {
2848 dinfo->fprintf_func (dinfo->stream, "Invalid island or me.");
2849 return _NFP_ERR_STOP;
2850 }
2851
2852 mecfg = &priv->mecfgs[island][menum][is_text];
2853 num_ctx = (mecfg->ctx4_mode) ? 4 : 8;
2854 addr_3rdparty32 = mecfg->addr_3rdparty32;
2855 scs_cnt = mecfg->scs_cnt;
2856 }
2857
2858 if (opts->ctx_mode)
2859 num_ctx = opts->ctx_mode;
2860
2861 dinfo->bytes_per_line = 8;
2862 dinfo->bytes_per_chunk = 8;
2863
2864 instr = bfd_getl64 (buffer);
2865
2866 if (opts->show_pc)
2867 {
2868 pc = (int) (addr >> 3);
2869
2870 /* Guess max PC for formatting */
2871 tmpj = (int) (dinfo->buffer_length >> 3);
2872 if (scs_cnt == 1)
2873 {
2874 pc *= 2;
2875 tmpj *= 2;
2876 if (! !(menum & 1))
2877 {
2878 pc++;
2879 tmpj++;
2880 }
2881 }
2882
2883 for (tmpi = 1; tmpj > 9; tmpj /= 10)
2884 tmpi++;
2885
2886 tmpj = pc;
2887 for (; tmpj > 9; tmpj /= 10)
2888 tmpi--;
2889
2890 dinfo->fprintf_func (dinfo->stream, "%*c%d ", tmpi, '.', pc);
2891 }
2892
2893 switch (dinfo->mach)
2894 {
2895 case E_NFP_MACH_3200:
2896 if (NFP_ME27_INSTR_IS_CMD (instr))
2897 err = nfp_me27_print_cmd (instr, addr_3rdparty32, num_ctx, dinfo);
2898 else if (NFP_ME27_INSTR_IS_ALU_SHF (instr))
2899 err = nfp_me27_print_alu_shf (instr, num_ctx, dinfo);
2900 else if (NFP_ME27_INSTR_IS_ALU (instr))
2901 err = nfp_me27_print_alu (instr, num_ctx, dinfo);
2902 else if (NFP_ME27_INSTR_IS_IMMED (instr))
2903 err = nfp_me27_print_immed (instr, num_ctx, dinfo);
2904 else if (NFP_ME27_INSTR_IS_LD_FIELD (instr))
2905 err = nfp_me27_print_ld_field (instr, num_ctx, dinfo);
2906 else if (NFP_ME27_INSTR_IS_CTX_ARB (instr))
2907 err = nfp_me27_print_ctx_arb (instr, dinfo);
2908 else if (NFP_ME27_INSTR_IS_LOCAL_CSR (instr))
2909 err = nfp_me27_print_local_csr (instr, num_ctx, dinfo);
2910 else if (NFP_ME27_INSTR_IS_BRANCH (instr))
2911 err = nfp_me27_print_branch (instr, dinfo);
2912 else if (NFP_ME27_INSTR_IS_BR_BYTE (instr))
2913 err = nfp_me27_print_br_byte (instr, num_ctx, dinfo);
2914 else if (NFP_ME27_INSTR_IS_BR_BIT (instr))
2915 err = nfp_me27_print_br_bit (instr, num_ctx, dinfo);
2916 else if (NFP_ME27_INSTR_IS_BR_ALU (instr))
2917 err = nfp_me27_print_br_alu (instr, num_ctx, dinfo);
2918 else if (NFP_ME27_INSTR_IS_MULT (instr))
2919 err = nfp_me27_print_mult (instr, num_ctx, dinfo);
2920 else
2921 err = nfp_me_print_invalid (instr, dinfo);
2922 break;
2923
2924 case E_NFP_MACH_6000:
2925 if (NFP_ME28_INSTR_IS_CMD (instr))
2926 err = nfp_me28_print_cmd (instr, addr_3rdparty32, num_ctx, dinfo);
2927 else if (NFP_ME28_INSTR_IS_ALU_SHF (instr))
2928 err = nfp_me28_print_alu_shf (instr, num_ctx, dinfo);
2929 else if (NFP_ME28_INSTR_IS_ALU (instr))
2930 err = nfp_me28_print_alu (instr, num_ctx, dinfo);
2931 else if (NFP_ME28_INSTR_IS_IMMED (instr))
2932 err = nfp_me28_print_immed (instr, num_ctx, dinfo);
2933 else if (NFP_ME28_INSTR_IS_LD_FIELD (instr))
2934 err = nfp_me28_print_ld_field (instr, num_ctx, dinfo);
2935 else if (NFP_ME28_INSTR_IS_CTX_ARB (instr))
2936 err = nfp_me28_print_ctx_arb (instr, dinfo);
2937 else if (NFP_ME28_INSTR_IS_LOCAL_CSR (instr))
2938 err = nfp_me28_print_local_csr (instr, num_ctx, dinfo);
2939 else if (NFP_ME28_INSTR_IS_BRANCH (instr))
2940 err = nfp_me28_print_branch (instr, dinfo);
2941 else if (NFP_ME28_INSTR_IS_BR_BYTE (instr))
2942 err = nfp_me28_print_br_byte (instr, num_ctx, dinfo);
2943 else if (NFP_ME28_INSTR_IS_BR_BIT (instr))
2944 err = nfp_me28_print_br_bit (instr, num_ctx, dinfo);
2945 else if (NFP_ME28_INSTR_IS_BR_ALU (instr))
2946 err = nfp_me28_print_br_alu (instr, num_ctx, dinfo);
2947 else if (NFP_ME28_INSTR_IS_MULT (instr))
2948 err = nfp_me28_print_mult (instr, num_ctx, dinfo);
2949 else
2950 err = nfp_me_print_invalid (instr, dinfo);
2951 break;
2952 }
2953
2954 if (err < 0)
2955 return err;
2956 return 8;
2957 }
2958
2959 int
2960 print_insn_nfp (bfd_vma addr, struct disassemble_info *dinfo)
2961 {
2962 nfp_opts opts;
2963 int err;
2964
2965 opts.show_pc = 1;
2966 opts.ctx_mode = 0;
2967 err = parse_disassembler_options (&opts, dinfo);
2968 if (err < 0)
2969 goto end;
2970
2971 err = _print_instrs (addr, dinfo, &opts);
2972
2973 end:
2974 if (err != 8)
2975 dinfo->fprintf_func (dinfo->stream, "\t # ERROR");
2976 if (err == _NFP_ERR_CONT)
2977 return 8;
2978 return err;
2979 }
2980
2981 void
2982 print_nfp_disassembler_options (FILE * stream)
2983 {
2984 fprintf (stream, _("\n\
2985 The following NFP specific disassembler options are supported for use\n\
2986 with the -M switch (multiple options should be separated by commas):\n"));
2987
2988 fprintf (stream, _("\n\
2989 no-pc Don't print program counter prefix.\n\
2990 ctx4 Force disassembly using 4-context mode.\n\
2991 ctx8 Force 8-context mode, takes precedence."));
2992
2993 fprintf (stream, _("\n"));
2994 }