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