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