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