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