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