1/* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2/* Instruction opcode table for ip2k.
3
4THIS FILE IS MACHINE GENERATED WITH CGEN.
5
6Copyright (C) 1996-2020 Free Software Foundation, Inc.
7
8This file is part of the GNU Binutils and/or GDB, the GNU debugger.
9
10   This file is free software; you can redistribute it and/or modify
11   it under the terms of the GNU General Public License as published by
12   the Free Software Foundation; either version 3, or (at your option)
13   any later version.
14
15   It is distributed in the hope that it will be useful, but WITHOUT
16   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
18   License for more details.
19
20   You should have received a copy of the GNU General Public License along
21   with this program; if not, write to the Free Software Foundation, Inc.,
22   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
23
24*/
25
26#include "sysdep.h"
27#include "ansidecl.h"
28#include "bfd.h"
29#include "symcat.h"
30#include "ip2k-desc.h"
31#include "ip2k-opc.h"
32#include "libiberty.h"
33
34/* -- opc.c */
35
36#include "safe-ctype.h"
37
38/* A better hash function for instruction mnemonics.  */
39unsigned int
40ip2k_asm_hash (const char* insn)
41{
42  unsigned int hash;
43  const char* m = insn;
44
45  for (hash = 0; *m && ! ISSPACE (*m); m++)
46    hash = (hash * 23) ^ (0x1F & TOLOWER (*m));
47
48  /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */
49
50  return hash % CGEN_ASM_HASH_SIZE;
51}
52
53
54/* Special check to ensure that instruction exists for given machine.  */
55
56int
57ip2k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
58{
59  int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
60
61  /* No mach attribute?  Assume it's supported for all machs.  */
62  if (machs == 0)
63    return 1;
64
65  return (machs & cd->machs) != 0;
66}
67
68
69/* -- asm.c */
70/* The hash functions are recorded here to help keep assembler code out of
71   the disassembler and vice versa.  */
72
73static int asm_hash_insn_p        (const CGEN_INSN *);
74static unsigned int asm_hash_insn (const char *);
75static int dis_hash_insn_p        (const CGEN_INSN *);
76static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT);
77
78/* Instruction formats.  */
79
80#define F(f) & ip2k_cgen_ifld_table[IP2K_##f]
81static const CGEN_IFMT ifmt_empty ATTRIBUTE_UNUSED = {
82  0, 0, 0x0, { { 0 } }
83};
84
85static const CGEN_IFMT ifmt_jmp ATTRIBUTE_UNUSED = {
86  16, 16, 0xe000, { { F (F_OP3) }, { F (F_ADDR16CJP) }, { 0 } }
87};
88
89static const CGEN_IFMT ifmt_sb ATTRIBUTE_UNUSED = {
90  16, 16, 0xf000, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
91};
92
93static const CGEN_IFMT ifmt_xorw_l ATTRIBUTE_UNUSED = {
94  16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } }
95};
96
97static const CGEN_IFMT ifmt_loadl_a ATTRIBUTE_UNUSED = {
98  16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } }
99};
100
101static const CGEN_IFMT ifmt_loadh_a ATTRIBUTE_UNUSED = {
102  16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } }
103};
104
105static const CGEN_IFMT ifmt_addcfr_w ATTRIBUTE_UNUSED = {
106  16, 16, 0xfe00, { { F (F_OP6) }, { F (F_DIR) }, { F (F_REG) }, { 0 } }
107};
108
109static const CGEN_IFMT ifmt_speed ATTRIBUTE_UNUSED = {
110  16, 16, 0xff00, { { F (F_OP8) }, { F (F_IMM8) }, { 0 } }
111};
112
113static const CGEN_IFMT ifmt_ireadi ATTRIBUTE_UNUSED = {
114  16, 16, 0xffff, { { F (F_OP6) }, { F (F_OP6_10LOW) }, { 0 } }
115};
116
117static const CGEN_IFMT ifmt_page ATTRIBUTE_UNUSED = {
118  16, 16, 0xfff8, { { F (F_OP6) }, { F (F_OP6_7LOW) }, { F (F_PAGE3) }, { 0 } }
119};
120
121static const CGEN_IFMT ifmt_reti ATTRIBUTE_UNUSED = {
122  16, 16, 0xfff8, { { F (F_OP6) }, { F (F_OP6_7LOW) }, { F (F_RETI3) }, { 0 } }
123};
124
125#undef F
126
127#define A(a) (1 << CGEN_INSN_##a)
128#define OPERAND(op) IP2K_OPERAND_##op
129#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
130#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
131
132/* The instruction table.  */
133
134static const CGEN_OPCODE ip2k_cgen_insn_opcode_table[MAX_INSNS] =
135{
136  /* Special null first entry.
137     A `num' value of zero is thus invalid.
138     Also, the special `invalid' insn resides here.  */
139  { { 0, 0, 0, 0 }, {{0}}, 0, {0}},
140/* jmp $addr16cjp */
141  {
142    { 0, 0, 0, 0 },
143    { { MNEM, ' ', OP (ADDR16CJP), 0 } },
144    & ifmt_jmp, { 0xe000 }
145  },
146/* call $addr16cjp */
147  {
148    { 0, 0, 0, 0 },
149    { { MNEM, ' ', OP (ADDR16CJP), 0 } },
150    & ifmt_jmp, { 0xc000 }
151  },
152/* sb $fr,$bitno */
153  {
154    { 0, 0, 0, 0 },
155    { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
156    & ifmt_sb, { 0xb000 }
157  },
158/* snb $fr,$bitno */
159  {
160    { 0, 0, 0, 0 },
161    { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
162    & ifmt_sb, { 0xa000 }
163  },
164/* setb $fr,$bitno */
165  {
166    { 0, 0, 0, 0 },
167    { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
168    & ifmt_sb, { 0x9000 }
169  },
170/* clrb $fr,$bitno */
171  {
172    { 0, 0, 0, 0 },
173    { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } },
174    & ifmt_sb, { 0x8000 }
175  },
176/* xor W,#$lit8 */
177  {
178    { 0, 0, 0, 0 },
179    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
180    & ifmt_xorw_l, { 0x7f00 }
181  },
182/* and W,#$lit8 */
183  {
184    { 0, 0, 0, 0 },
185    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
186    & ifmt_xorw_l, { 0x7e00 }
187  },
188/* or W,#$lit8 */
189  {
190    { 0, 0, 0, 0 },
191    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
192    & ifmt_xorw_l, { 0x7d00 }
193  },
194/* add W,#$lit8 */
195  {
196    { 0, 0, 0, 0 },
197    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
198    & ifmt_xorw_l, { 0x7b00 }
199  },
200/* sub W,#$lit8 */
201  {
202    { 0, 0, 0, 0 },
203    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
204    & ifmt_xorw_l, { 0x7a00 }
205  },
206/* cmp W,#$lit8 */
207  {
208    { 0, 0, 0, 0 },
209    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
210    & ifmt_xorw_l, { 0x7900 }
211  },
212/* retw #$lit8 */
213  {
214    { 0, 0, 0, 0 },
215    { { MNEM, ' ', '#', OP (LIT8), 0 } },
216    & ifmt_xorw_l, { 0x7800 }
217  },
218/* cse W,#$lit8 */
219  {
220    { 0, 0, 0, 0 },
221    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
222    & ifmt_xorw_l, { 0x7700 }
223  },
224/* csne W,#$lit8 */
225  {
226    { 0, 0, 0, 0 },
227    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
228    & ifmt_xorw_l, { 0x7600 }
229  },
230/* push #$lit8 */
231  {
232    { 0, 0, 0, 0 },
233    { { MNEM, ' ', '#', OP (LIT8), 0 } },
234    & ifmt_xorw_l, { 0x7400 }
235  },
236/* muls W,#$lit8 */
237  {
238    { 0, 0, 0, 0 },
239    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
240    & ifmt_xorw_l, { 0x7300 }
241  },
242/* mulu W,#$lit8 */
243  {
244    { 0, 0, 0, 0 },
245    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
246    & ifmt_xorw_l, { 0x7200 }
247  },
248/* loadl #$lit8 */
249  {
250    { 0, 0, 0, 0 },
251    { { MNEM, ' ', '#', OP (LIT8), 0 } },
252    & ifmt_xorw_l, { 0x7100 }
253  },
254/* loadh #$lit8 */
255  {
256    { 0, 0, 0, 0 },
257    { { MNEM, ' ', '#', OP (LIT8), 0 } },
258    & ifmt_xorw_l, { 0x7000 }
259  },
260/* loadl $addr16l */
261  {
262    { 0, 0, 0, 0 },
263    { { MNEM, ' ', OP (ADDR16L), 0 } },
264    & ifmt_loadl_a, { 0x7100 }
265  },
266/* loadh $addr16h */
267  {
268    { 0, 0, 0, 0 },
269    { { MNEM, ' ', OP (ADDR16H), 0 } },
270    & ifmt_loadh_a, { 0x7000 }
271  },
272/* addc $fr,W */
273  {
274    { 0, 0, 0, 0 },
275    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
276    & ifmt_addcfr_w, { 0x5e00 }
277  },
278/* addc W,$fr */
279  {
280    { 0, 0, 0, 0 },
281    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
282    & ifmt_addcfr_w, { 0x5c00 }
283  },
284/* incsnz $fr */
285  {
286    { 0, 0, 0, 0 },
287    { { MNEM, ' ', OP (FR), 0 } },
288    & ifmt_addcfr_w, { 0x5a00 }
289  },
290/* incsnz W,$fr */
291  {
292    { 0, 0, 0, 0 },
293    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
294    & ifmt_addcfr_w, { 0x5800 }
295  },
296/* muls W,$fr */
297  {
298    { 0, 0, 0, 0 },
299    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
300    & ifmt_addcfr_w, { 0x5400 }
301  },
302/* mulu W,$fr */
303  {
304    { 0, 0, 0, 0 },
305    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
306    & ifmt_addcfr_w, { 0x5000 }
307  },
308/* decsnz $fr */
309  {
310    { 0, 0, 0, 0 },
311    { { MNEM, ' ', OP (FR), 0 } },
312    & ifmt_addcfr_w, { 0x4e00 }
313  },
314/* decsnz W,$fr */
315  {
316    { 0, 0, 0, 0 },
317    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
318    & ifmt_addcfr_w, { 0x4c00 }
319  },
320/* subc W,$fr */
321  {
322    { 0, 0, 0, 0 },
323    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
324    & ifmt_addcfr_w, { 0x4800 }
325  },
326/* subc $fr,W */
327  {
328    { 0, 0, 0, 0 },
329    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
330    & ifmt_addcfr_w, { 0x4a00 }
331  },
332/* pop $fr */
333  {
334    { 0, 0, 0, 0 },
335    { { MNEM, ' ', OP (FR), 0 } },
336    & ifmt_addcfr_w, { 0x4600 }
337  },
338/* push $fr */
339  {
340    { 0, 0, 0, 0 },
341    { { MNEM, ' ', OP (FR), 0 } },
342    & ifmt_addcfr_w, { 0x4400 }
343  },
344/* cse W,$fr */
345  {
346    { 0, 0, 0, 0 },
347    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
348    & ifmt_addcfr_w, { 0x4200 }
349  },
350/* csne W,$fr */
351  {
352    { 0, 0, 0, 0 },
353    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
354    & ifmt_addcfr_w, { 0x4000 }
355  },
356/* incsz $fr */
357  {
358    { 0, 0, 0, 0 },
359    { { MNEM, ' ', OP (FR), 0 } },
360    & ifmt_addcfr_w, { 0x3e00 }
361  },
362/* incsz W,$fr */
363  {
364    { 0, 0, 0, 0 },
365    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
366    & ifmt_addcfr_w, { 0x3c00 }
367  },
368/* swap $fr */
369  {
370    { 0, 0, 0, 0 },
371    { { MNEM, ' ', OP (FR), 0 } },
372    & ifmt_addcfr_w, { 0x3a00 }
373  },
374/* swap W,$fr */
375  {
376    { 0, 0, 0, 0 },
377    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
378    & ifmt_addcfr_w, { 0x3800 }
379  },
380/* rl $fr */
381  {
382    { 0, 0, 0, 0 },
383    { { MNEM, ' ', OP (FR), 0 } },
384    & ifmt_addcfr_w, { 0x3600 }
385  },
386/* rl W,$fr */
387  {
388    { 0, 0, 0, 0 },
389    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
390    & ifmt_addcfr_w, { 0x3400 }
391  },
392/* rr $fr */
393  {
394    { 0, 0, 0, 0 },
395    { { MNEM, ' ', OP (FR), 0 } },
396    & ifmt_addcfr_w, { 0x3200 }
397  },
398/* rr W,$fr */
399  {
400    { 0, 0, 0, 0 },
401    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
402    & ifmt_addcfr_w, { 0x3000 }
403  },
404/* decsz $fr */
405  {
406    { 0, 0, 0, 0 },
407    { { MNEM, ' ', OP (FR), 0 } },
408    & ifmt_addcfr_w, { 0x2e00 }
409  },
410/* decsz W,$fr */
411  {
412    { 0, 0, 0, 0 },
413    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
414    & ifmt_addcfr_w, { 0x2c00 }
415  },
416/* inc $fr */
417  {
418    { 0, 0, 0, 0 },
419    { { MNEM, ' ', OP (FR), 0 } },
420    & ifmt_addcfr_w, { 0x2a00 }
421  },
422/* inc W,$fr */
423  {
424    { 0, 0, 0, 0 },
425    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
426    & ifmt_addcfr_w, { 0x2800 }
427  },
428/* not $fr */
429  {
430    { 0, 0, 0, 0 },
431    { { MNEM, ' ', OP (FR), 0 } },
432    & ifmt_addcfr_w, { 0x2600 }
433  },
434/* not W,$fr */
435  {
436    { 0, 0, 0, 0 },
437    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
438    & ifmt_addcfr_w, { 0x2400 }
439  },
440/* test $fr */
441  {
442    { 0, 0, 0, 0 },
443    { { MNEM, ' ', OP (FR), 0 } },
444    & ifmt_addcfr_w, { 0x2200 }
445  },
446/* mov W,#$lit8 */
447  {
448    { 0, 0, 0, 0 },
449    { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } },
450    & ifmt_xorw_l, { 0x7c00 }
451  },
452/* mov $fr,W */
453  {
454    { 0, 0, 0, 0 },
455    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
456    & ifmt_addcfr_w, { 0x200 }
457  },
458/* mov W,$fr */
459  {
460    { 0, 0, 0, 0 },
461    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
462    & ifmt_addcfr_w, { 0x2000 }
463  },
464/* add $fr,W */
465  {
466    { 0, 0, 0, 0 },
467    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
468    & ifmt_addcfr_w, { 0x1e00 }
469  },
470/* add W,$fr */
471  {
472    { 0, 0, 0, 0 },
473    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
474    & ifmt_addcfr_w, { 0x1c00 }
475  },
476/* xor $fr,W */
477  {
478    { 0, 0, 0, 0 },
479    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
480    & ifmt_addcfr_w, { 0x1a00 }
481  },
482/* xor W,$fr */
483  {
484    { 0, 0, 0, 0 },
485    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
486    & ifmt_addcfr_w, { 0x1800 }
487  },
488/* and $fr,W */
489  {
490    { 0, 0, 0, 0 },
491    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
492    & ifmt_addcfr_w, { 0x1600 }
493  },
494/* and W,$fr */
495  {
496    { 0, 0, 0, 0 },
497    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
498    & ifmt_addcfr_w, { 0x1400 }
499  },
500/* or $fr,W */
501  {
502    { 0, 0, 0, 0 },
503    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
504    & ifmt_addcfr_w, { 0x1200 }
505  },
506/* or W,$fr */
507  {
508    { 0, 0, 0, 0 },
509    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
510    & ifmt_addcfr_w, { 0x1000 }
511  },
512/* dec $fr */
513  {
514    { 0, 0, 0, 0 },
515    { { MNEM, ' ', OP (FR), 0 } },
516    & ifmt_addcfr_w, { 0xe00 }
517  },
518/* dec W,$fr */
519  {
520    { 0, 0, 0, 0 },
521    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
522    & ifmt_addcfr_w, { 0xc00 }
523  },
524/* sub $fr,W */
525  {
526    { 0, 0, 0, 0 },
527    { { MNEM, ' ', OP (FR), ',', 'W', 0 } },
528    & ifmt_addcfr_w, { 0xa00 }
529  },
530/* sub W,$fr */
531  {
532    { 0, 0, 0, 0 },
533    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
534    & ifmt_addcfr_w, { 0x800 }
535  },
536/* clr $fr */
537  {
538    { 0, 0, 0, 0 },
539    { { MNEM, ' ', OP (FR), 0 } },
540    & ifmt_addcfr_w, { 0x600 }
541  },
542/* cmp W,$fr */
543  {
544    { 0, 0, 0, 0 },
545    { { MNEM, ' ', 'W', ',', OP (FR), 0 } },
546    & ifmt_addcfr_w, { 0x400 }
547  },
548/* speed #$lit8 */
549  {
550    { 0, 0, 0, 0 },
551    { { MNEM, ' ', '#', OP (LIT8), 0 } },
552    & ifmt_speed, { 0x100 }
553  },
554/* ireadi */
555  {
556    { 0, 0, 0, 0 },
557    { { MNEM, 0 } },
558    & ifmt_ireadi, { 0x1d }
559  },
560/* iwritei */
561  {
562    { 0, 0, 0, 0 },
563    { { MNEM, 0 } },
564    & ifmt_ireadi, { 0x1c }
565  },
566/* fread */
567  {
568    { 0, 0, 0, 0 },
569    { { MNEM, 0 } },
570    & ifmt_ireadi, { 0x1b }
571  },
572/* fwrite */
573  {
574    { 0, 0, 0, 0 },
575    { { MNEM, 0 } },
576    & ifmt_ireadi, { 0x1a }
577  },
578/* iread */
579  {
580    { 0, 0, 0, 0 },
581    { { MNEM, 0 } },
582    & ifmt_ireadi, { 0x19 }
583  },
584/* iwrite */
585  {
586    { 0, 0, 0, 0 },
587    { { MNEM, 0 } },
588    & ifmt_ireadi, { 0x18 }
589  },
590/* page $addr16p */
591  {
592    { 0, 0, 0, 0 },
593    { { MNEM, ' ', OP (ADDR16P), 0 } },
594    & ifmt_page, { 0x10 }
595  },
596/* system */
597  {
598    { 0, 0, 0, 0 },
599    { { MNEM, 0 } },
600    & ifmt_ireadi, { 0xff }
601  },
602/* reti #$reti3 */
603  {
604    { 0, 0, 0, 0 },
605    { { MNEM, ' ', '#', OP (RETI3), 0 } },
606    & ifmt_reti, { 0x8 }
607  },
608/* ret */
609  {
610    { 0, 0, 0, 0 },
611    { { MNEM, 0 } },
612    & ifmt_ireadi, { 0x7 }
613  },
614/* int */
615  {
616    { 0, 0, 0, 0 },
617    { { MNEM, 0 } },
618    & ifmt_ireadi, { 0x6 }
619  },
620/* breakx */
621  {
622    { 0, 0, 0, 0 },
623    { { MNEM, 0 } },
624    & ifmt_ireadi, { 0x5 }
625  },
626/* cwdt */
627  {
628    { 0, 0, 0, 0 },
629    { { MNEM, 0 } },
630    & ifmt_ireadi, { 0x4 }
631  },
632/* ferase */
633  {
634    { 0, 0, 0, 0 },
635    { { MNEM, 0 } },
636    & ifmt_ireadi, { 0x3 }
637  },
638/* retnp */
639  {
640    { 0, 0, 0, 0 },
641    { { MNEM, 0 } },
642    & ifmt_ireadi, { 0x2 }
643  },
644/* break */
645  {
646    { 0, 0, 0, 0 },
647    { { MNEM, 0 } },
648    & ifmt_ireadi, { 0x1 }
649  },
650/* nop */
651  {
652    { 0, 0, 0, 0 },
653    { { MNEM, 0 } },
654    & ifmt_ireadi, { 0x0 }
655  },
656};
657
658#undef A
659#undef OPERAND
660#undef MNEM
661#undef OP
662
663/* Formats for ALIAS macro-insns.  */
664
665#define F(f) & ip2k_cgen_ifld_table[IP2K_##f]
666static const CGEN_IFMT ifmt_sc ATTRIBUTE_UNUSED = {
667  16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
668};
669
670static const CGEN_IFMT ifmt_snc ATTRIBUTE_UNUSED = {
671  16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
672};
673
674static const CGEN_IFMT ifmt_sz ATTRIBUTE_UNUSED = {
675  16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
676};
677
678static const CGEN_IFMT ifmt_snz ATTRIBUTE_UNUSED = {
679  16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
680};
681
682static const CGEN_IFMT ifmt_skip ATTRIBUTE_UNUSED = {
683  16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
684};
685
686static const CGEN_IFMT ifmt_skipb ATTRIBUTE_UNUSED = {
687  16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } }
688};
689
690#undef F
691
692/* Each non-simple macro entry points to an array of expansion possibilities.  */
693
694#define A(a) (1 << CGEN_INSN_##a)
695#define OPERAND(op) IP2K_OPERAND_##op
696#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
697#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
698
699/* The macro instruction table.  */
700
701static const CGEN_IBASE ip2k_cgen_macro_insn_table[] =
702{
703/* sc */
704  {
705    -1, "sc", "sc", 16,
706    { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
707  },
708/* snc */
709  {
710    -1, "snc", "snc", 16,
711    { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
712  },
713/* sz */
714  {
715    -1, "sz", "sz", 16,
716    { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
717  },
718/* snz */
719  {
720    -1, "snz", "snz", 16,
721    { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
722  },
723/* skip */
724  {
725    -1, "skip", "skip", 16,
726    { 0|A(SKIPA)|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
727  },
728/* skip */
729  {
730    -1, "skipb", "skip", 16,
731    { 0|A(SKIPA)|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
732  },
733};
734
735/* The macro instruction opcode table.  */
736
737static const CGEN_OPCODE ip2k_cgen_macro_insn_opcode_table[] =
738{
739/* sc */
740  {
741    { 0, 0, 0, 0 },
742    { { MNEM, 0 } },
743    & ifmt_sc, { 0xb00b }
744  },
745/* snc */
746  {
747    { 0, 0, 0, 0 },
748    { { MNEM, 0 } },
749    & ifmt_snc, { 0xa00b }
750  },
751/* sz */
752  {
753    { 0, 0, 0, 0 },
754    { { MNEM, 0 } },
755    & ifmt_sz, { 0xb40b }
756  },
757/* snz */
758  {
759    { 0, 0, 0, 0 },
760    { { MNEM, 0 } },
761    & ifmt_snz, { 0xa40b }
762  },
763/* skip */
764  {
765    { 0, 0, 0, 0 },
766    { { MNEM, 0 } },
767    & ifmt_skip, { 0xa009 }
768  },
769/* skip */
770  {
771    { 0, 0, 0, 0 },
772    { { MNEM, 0 } },
773    & ifmt_skipb, { 0xb009 }
774  },
775};
776
777#undef A
778#undef OPERAND
779#undef MNEM
780#undef OP
781
782#ifndef CGEN_ASM_HASH_P
783#define CGEN_ASM_HASH_P(insn) 1
784#endif
785
786#ifndef CGEN_DIS_HASH_P
787#define CGEN_DIS_HASH_P(insn) 1
788#endif
789
790/* Return non-zero if INSN is to be added to the hash table.
791   Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file.  */
792
793static int
794asm_hash_insn_p (const CGEN_INSN *insn ATTRIBUTE_UNUSED)
795{
796  return CGEN_ASM_HASH_P (insn);
797}
798
799static int
800dis_hash_insn_p (const CGEN_INSN *insn)
801{
802  /* If building the hash table and the NO-DIS attribute is present,
803     ignore.  */
804  if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS))
805    return 0;
806  return CGEN_DIS_HASH_P (insn);
807}
808
809#ifndef CGEN_ASM_HASH
810#define CGEN_ASM_HASH_SIZE 127
811#ifdef CGEN_MNEMONIC_OPERANDS
812#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE)
813#else
814#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/
815#endif
816#endif
817
818/* It doesn't make much sense to provide a default here,
819   but while this is under development we do.
820   BUFFER is a pointer to the bytes of the insn, target order.
821   VALUE is the first base_insn_bitsize bits as an int in host order.  */
822
823#ifndef CGEN_DIS_HASH
824#define CGEN_DIS_HASH_SIZE 256
825#define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf))
826#endif
827
828/* The result is the hash value of the insn.
829   Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file.  */
830
831static unsigned int
832asm_hash_insn (const char *mnem)
833{
834  return CGEN_ASM_HASH (mnem);
835}
836
837/* BUF is a pointer to the bytes of the insn, target order.
838   VALUE is the first base_insn_bitsize bits as an int in host order.  */
839
840static unsigned int
841dis_hash_insn (const char *buf ATTRIBUTE_UNUSED,
842		     CGEN_INSN_INT value ATTRIBUTE_UNUSED)
843{
844  return CGEN_DIS_HASH (buf, value);
845}
846
847/* Set the recorded length of the insn in the CGEN_FIELDS struct.  */
848
849static void
850set_fields_bitsize (CGEN_FIELDS *fields, int size)
851{
852  CGEN_FIELDS_BITSIZE (fields) = size;
853}
854
855/* Function to call before using the operand instance table.
856   This plugs the opcode entries and macro instructions into the cpu table.  */
857
858void
859ip2k_cgen_init_opcode_table (CGEN_CPU_DESC cd)
860{
861  int i;
862  int num_macros = (sizeof (ip2k_cgen_macro_insn_table) /
863		    sizeof (ip2k_cgen_macro_insn_table[0]));
864  const CGEN_IBASE *ib = & ip2k_cgen_macro_insn_table[0];
865  const CGEN_OPCODE *oc = & ip2k_cgen_macro_insn_opcode_table[0];
866  CGEN_INSN *insns = xmalloc (num_macros * sizeof (CGEN_INSN));
867
868  /* This test has been added to avoid a warning generated
869     if memset is called with a third argument of value zero.  */
870  if (num_macros >= 1)
871    memset (insns, 0, num_macros * sizeof (CGEN_INSN));
872  for (i = 0; i < num_macros; ++i)
873    {
874      insns[i].base = &ib[i];
875      insns[i].opcode = &oc[i];
876      ip2k_cgen_build_insn_regex (& insns[i]);
877    }
878  cd->macro_insn_table.init_entries = insns;
879  cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
880  cd->macro_insn_table.num_init_entries = num_macros;
881
882  oc = & ip2k_cgen_insn_opcode_table[0];
883  insns = (CGEN_INSN *) cd->insn_table.init_entries;
884  for (i = 0; i < MAX_INSNS; ++i)
885    {
886      insns[i].opcode = &oc[i];
887      ip2k_cgen_build_insn_regex (& insns[i]);
888    }
889
890  cd->sizeof_fields = sizeof (CGEN_FIELDS);
891  cd->set_fields_bitsize = set_fields_bitsize;
892
893  cd->asm_hash_p = asm_hash_insn_p;
894  cd->asm_hash = asm_hash_insn;
895  cd->asm_hash_size = CGEN_ASM_HASH_SIZE;
896
897  cd->dis_hash_p = dis_hash_insn_p;
898  cd->dis_hash = dis_hash_insn;
899  cd->dis_hash_size = CGEN_DIS_HASH_SIZE;
900}
901