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