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
52typedef 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}
59nfp_priv_mecfg;
60
61typedef struct
62{
63  unsigned char show_pc;
64  unsigned char ctx_mode;
65}
66nfp_opts;
67
68/* mecfgs[island][menum][is-text] */
69typedef struct
70{
71  nfp_priv_mecfg mecfgs[_NFP_ISLAND_MAX][_NFP_ME_MAX][2];
72}
73nfp_priv_data;
74
75static 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
87static 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
123static 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
135static 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
146static 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
251const 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
287static 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
307static 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
327static 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
339static 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
352static 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
613static 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
927static int
928nfp_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
935static bool
936nfp_me_is_imm_opnd10 (unsigned int opnd)
937{
938  return _BF (opnd, 9, 8) == 0x3;
939}
940
941static bool
942nfp_me_is_imm_opnd8 (unsigned int opnd)
943{
944  return _BTST (opnd, 5);
945}
946
947static unsigned int
948nfp_me_imm_opnd10 (unsigned int opnd)
949{
950  return nfp_me_is_imm_opnd10 (opnd) ? (opnd & 0xff) : ~0U;
951}
952
953static unsigned int
954nfp_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.  */
963static bool
964nfp_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
1036static bool
1037nfp_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
1100static int
1101nfp_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
1224static int
1225nfp_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
1415static int
1416nfp_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
1485static int
1486nfp_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
1556static int
1557nfp_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
1606static int
1607nfp_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
1673static int
1674nfp_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
1722static int
1723nfp_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
1767static int
1768nfp_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
1806static int
1807nfp_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
1844static int
1845nfp_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
1907static 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
1922static const char *
1923nfp_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
1955static int
1956nfp_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
2157static int
2158nfp_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
2164static int
2165nfp_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
2171static int
2172nfp_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
2178static int
2179nfp_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
2185static int
2186nfp_me27_print_ctx_arb (uint64_t instr, struct disassemble_info *dinfo)
2187{
2188  return nfp_me27_28_print_ctx_arb (instr, dinfo);
2189}
2190
2191static int
2192nfp_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
2198static int
2199nfp_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
2204static int
2205nfp_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
2211static int
2212nfp_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
2218static int
2219nfp_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
2225static int
2226nfp_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
2234static int
2235nfp_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
2420static int
2421nfp_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
2433static int
2434nfp_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
2446static int
2447nfp_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
2458static int
2459nfp_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
2471static int
2472nfp_me28_print_ctx_arb (uint64_t instr, struct disassemble_info *dinfo)
2473{
2474  return nfp_me27_28_print_ctx_arb (instr, dinfo);
2475}
2476
2477static int
2478nfp_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
2486static int
2487nfp_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
2492static int
2493nfp_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
2500static int
2501nfp_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
2508static int
2509nfp_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
2516static int
2517nfp_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
2529static bool
2530init_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
2595static bool
2596init_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
2668static bool
2669init_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
2725static int
2726parse_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
2757static nfp_priv_data *
2758init_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
2798static 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
2959int
2960print_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
2981void
2982print_nfp_disassembler_options (FILE * stream)
2983{
2984  fprintf (stream, _("\n\
2985The following NFP specific disassembler options are supported for use\n\
2986with 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}
2995