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