Thu Nov 26 11:26:32 1998 Dave Brolley <brolley@cygnus.com>
[platform/upstream/binutils.git] / opcodes / fr30-dis.c
1 /* Disassembler interface for targets using CGEN. -*- C -*-
2    CGEN: Cpu tools GENerator
3
4 THIS FILE IS USED TO GENERATE fr30-dis.c.
5
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
7
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10 This program 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 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
24 #include "sysdep.h"
25 #include <stdio.h>
26 #include "ansidecl.h"
27 #include "dis-asm.h"
28 #include "bfd.h"
29 #include "symcat.h"
30 #include "fr30-opc.h"
31 #include "opintl.h"
32
33 #undef INLINE
34 #ifdef __GNUC__
35 #define INLINE __inline__
36 #else
37 #define INLINE
38 #endif
39
40 /* Default text to print if an instruction isn't recognized.  */
41 #define UNKNOWN_INSN_MSG _("*unknown*")
42
43 static int extract_normal
44      PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
45               unsigned int, int, int, int, bfd_vma, long *));
46 static void print_normal
47      PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int));
48 static void print_address
49      PARAMS ((CGEN_OPCODE_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
50 static void print_keyword
51      PARAMS ((CGEN_OPCODE_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
52 static int extract_insn_normal
53      PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
54               CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
55 static void print_insn_normal
56      PARAMS ((CGEN_OPCODE_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
57               bfd_vma, int));
58 static int print_insn PARAMS ((CGEN_OPCODE_DESC, bfd_vma,
59                                disassemble_info *, char *, int));
60 static int default_print_insn
61      PARAMS ((CGEN_OPCODE_DESC, bfd_vma, disassemble_info *));
62 \f
63 /* -- disassembler routines inserted here */
64 /* -- dis.c */
65
66 static void
67 print_register_list (dis_info, value, offset)
68      PTR dis_info;
69      long value;
70      long offset;
71 {
72   disassemble_info *info = dis_info;
73   int mask  = 1;
74   int index;
75
76   if (value & mask)
77     (*info->fprintf_func) (info->stream, "r%i", index + offset);
78
79   for (index = 1; index <= 7; ++index)
80     {
81       mask <<= 1;
82       if (value & mask)
83         (*info->fprintf_func) (info->stream, ",r%i", index + offset);
84     }
85 }
86
87 static void
88 print_hi_register_list (od, dis_info, value, attrs, pc, length)
89      CGEN_OPCODE_DESC od;
90      PTR dis_info;
91      long value;
92      unsigned int attrs;
93      bfd_vma pc;
94      int length;
95 {
96   print_register_list (dis_info, value, 8);
97 }
98
99 static void
100 print_low_register_list (od, dis_info, value, attrs, pc, length)
101      CGEN_OPCODE_DESC od;
102      PTR dis_info;
103      long value;
104      unsigned int attrs;
105      bfd_vma pc;
106      int length;
107 {
108   print_register_list (dis_info, value, 0);
109 }
110
111 static void
112 print_label9 (od, dis_info, value, attrs, pc, length)
113      CGEN_OPCODE_DESC od;
114      PTR dis_info;
115      long value;
116      unsigned int attrs;
117      bfd_vma pc;
118      int length;
119 {
120   disassemble_info *info = (disassemble_info *) dis_info;
121   (*info->fprintf_func) (info->stream, "0x%lx", value);
122 }
123
124 /* -- */
125
126 /* Main entry point for operand extraction.
127
128    This function is basically just a big switch statement.  Earlier versions
129    used tables to look up the function to use, but
130    - if the table contains both assembler and disassembler functions then
131      the disassembler contains much of the assembler and vice-versa,
132    - there's a lot of inlining possibilities as things grow,
133    - using a switch statement avoids the function call overhead.
134
135    This function could be moved into `print_insn_normal', but keeping it
136    separate makes clear the interface between `print_insn_normal' and each of
137    the handlers.
138 */
139
140 int
141 fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
142      CGEN_OPCODE_DESC od;
143      int opindex;
144      CGEN_EXTRACT_INFO *ex_info;
145      CGEN_INSN_INT insn_value;
146      CGEN_FIELDS * fields;
147      bfd_vma pc;
148 {
149   int length;
150
151   switch (opindex)
152     {
153     case FR30_OPERAND_RI :
154       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Ri);
155       break;
156     case FR30_OPERAND_RJ :
157       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rj);
158       break;
159     case FR30_OPERAND_RIC :
160       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Ric);
161       break;
162     case FR30_OPERAND_RJC :
163       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rjc);
164       break;
165     case FR30_OPERAND_CRI :
166       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_CRi);
167       break;
168     case FR30_OPERAND_CRJ :
169       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_CRj);
170       break;
171     case FR30_OPERAND_RS1 :
172       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs1);
173       break;
174     case FR30_OPERAND_RS2 :
175       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs2);
176       break;
177     case FR30_OPERAND_R13 :
178       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
179       break;
180     case FR30_OPERAND_R14 :
181       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
182       break;
183     case FR30_OPERAND_R15 :
184       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
185       break;
186     case FR30_OPERAND_PS :
187       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
188       break;
189     case FR30_OPERAND_U4 :
190       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u4);
191       break;
192     case FR30_OPERAND_U4C :
193       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u4c);
194       break;
195     case FR30_OPERAND_M4 :
196       {
197         long value;
198         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
199         value = ((value) | ((! (15))));
200         fields->f_m4 = value;
201       }
202       break;
203     case FR30_OPERAND_U8 :
204       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u8);
205       break;
206     case FR30_OPERAND_I8 :
207       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i8);
208       break;
209     case FR30_OPERAND_UDISP6 :
210       {
211         long value;
212         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
213         value = ((value) << (2));
214         fields->f_udisp6 = value;
215       }
216       break;
217     case FR30_OPERAND_DISP8 :
218       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_disp8);
219       break;
220     case FR30_OPERAND_DISP9 :
221       {
222         long value;
223         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
224         value = ((value) << (1));
225         fields->f_disp9 = value;
226       }
227       break;
228     case FR30_OPERAND_DISP10 :
229       {
230         long value;
231         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
232         value = ((value) << (2));
233         fields->f_disp10 = value;
234       }
235       break;
236     case FR30_OPERAND_S10 :
237       {
238         long value;
239         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
240         value = ((value) << (2));
241         fields->f_s10 = value;
242       }
243       break;
244     case FR30_OPERAND_U10 :
245       {
246         long value;
247         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
248         value = ((value) << (2));
249         fields->f_u10 = value;
250       }
251       break;
252     case FR30_OPERAND_I32 :
253       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 32, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i32);
254       break;
255     case FR30_OPERAND_DIR8 :
256       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_dir8);
257       break;
258     case FR30_OPERAND_DIR9 :
259       {
260         long value;
261         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
262         value = ((value) << (1));
263         fields->f_dir9 = value;
264       }
265       break;
266     case FR30_OPERAND_DIR10 :
267       {
268         long value;
269         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
270         value = ((value) << (2));
271         fields->f_dir10 = value;
272       }
273       break;
274     case FR30_OPERAND_LABEL9 :
275       {
276         long value;
277         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
278         value = ((((value) << (1))) + (((pc) + (2))));
279         fields->f_rel9 = value;
280       }
281       break;
282     case FR30_OPERAND_LABEL12 :
283       {
284         long value;
285         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 5, 11, CGEN_FIELDS_BITSIZE (fields), pc, & value);
286         value = ((((value) << (1))) + (((pc) & (-2))));
287         fields->f_rel12 = value;
288       }
289       break;
290     case FR30_OPERAND_REGLIST_LOW :
291       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_reglist_low);
292       break;
293     case FR30_OPERAND_REGLIST_HI :
294       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_reglist_hi);
295       break;
296     case FR30_OPERAND_CC :
297       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_cc);
298       break;
299     case FR30_OPERAND_CCC :
300       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_ccc);
301       break;
302
303     default :
304       /* xgettext:c-format */
305       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
306                opindex);
307       abort ();
308     }
309
310   return length;
311 }
312
313 /* Main entry point for printing operands.
314
315    This function is basically just a big switch statement.  Earlier versions
316    used tables to look up the function to use, but
317    - if the table contains both assembler and disassembler functions then
318      the disassembler contains much of the assembler and vice-versa,
319    - there's a lot of inlining possibilities as things grow,
320    - using a switch statement avoids the function call overhead.
321
322    This function could be moved into `print_insn_normal', but keeping it
323    separate makes clear the interface between `print_insn_normal' and each of
324    the handlers.
325 */
326
327 void
328 fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
329      CGEN_OPCODE_DESC od;
330      int opindex;
331      disassemble_info * info;
332      CGEN_FIELDS * fields;
333      void const * attrs;
334      bfd_vma pc;
335      int length;
336 {
337   switch (opindex)
338     {
339     case FR30_OPERAND_RI :
340       print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED));
341       break;
342     case FR30_OPERAND_RJ :
343       print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED));
344       break;
345     case FR30_OPERAND_RIC :
346       print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Ric, 0|(1<<CGEN_OPERAND_UNSIGNED));
347       break;
348     case FR30_OPERAND_RJC :
349       print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rjc, 0|(1<<CGEN_OPERAND_UNSIGNED));
350       break;
351     case FR30_OPERAND_CRI :
352       print_keyword (od, info, & fr30_cgen_opval_h_cr, fields->f_CRi, 0|(1<<CGEN_OPERAND_UNSIGNED));
353       break;
354     case FR30_OPERAND_CRJ :
355       print_keyword (od, info, & fr30_cgen_opval_h_cr, fields->f_CRj, 0|(1<<CGEN_OPERAND_UNSIGNED));
356       break;
357     case FR30_OPERAND_RS1 :
358       print_keyword (od, info, & fr30_cgen_opval_h_dr, fields->f_Rs1, 0|(1<<CGEN_OPERAND_UNSIGNED));
359       break;
360     case FR30_OPERAND_RS2 :
361       print_keyword (od, info, & fr30_cgen_opval_h_dr, fields->f_Rs2, 0|(1<<CGEN_OPERAND_UNSIGNED));
362       break;
363     case FR30_OPERAND_R13 :
364       print_keyword (od, info, & fr30_cgen_opval_h_r13, fields->f_nil, 0);
365       break;
366     case FR30_OPERAND_R14 :
367       print_keyword (od, info, & fr30_cgen_opval_h_r14, fields->f_nil, 0);
368       break;
369     case FR30_OPERAND_R15 :
370       print_keyword (od, info, & fr30_cgen_opval_h_r15, fields->f_nil, 0);
371       break;
372     case FR30_OPERAND_PS :
373       print_keyword (od, info, & fr30_cgen_opval_h_ps, fields->f_nil, 0);
374       break;
375     case FR30_OPERAND_U4 :
376       print_normal (od, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
377       break;
378     case FR30_OPERAND_U4C :
379       print_normal (od, info, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
380       break;
381     case FR30_OPERAND_M4 :
382       print_normal (od, info, fields->f_m4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
383       break;
384     case FR30_OPERAND_U8 :
385       print_normal (od, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
386       break;
387     case FR30_OPERAND_I8 :
388       print_normal (od, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
389       break;
390     case FR30_OPERAND_UDISP6 :
391       print_normal (od, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
392       break;
393     case FR30_OPERAND_DISP8 :
394       print_normal (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
395       break;
396     case FR30_OPERAND_DISP9 :
397       print_normal (od, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
398       break;
399     case FR30_OPERAND_DISP10 :
400       print_normal (od, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
401       break;
402     case FR30_OPERAND_S10 :
403       print_normal (od, info, fields->f_s10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
404       break;
405     case FR30_OPERAND_U10 :
406       print_normal (od, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
407       break;
408     case FR30_OPERAND_I32 :
409       print_normal (od, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
410       break;
411     case FR30_OPERAND_DIR8 :
412       print_normal (od, info, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
413       break;
414     case FR30_OPERAND_DIR9 :
415       print_normal (od, info, fields->f_dir9, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
416       break;
417     case FR30_OPERAND_DIR10 :
418       print_normal (od, info, fields->f_dir10, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
419       break;
420     case FR30_OPERAND_LABEL9 :
421       print_label9 (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), pc, length);
422       break;
423     case FR30_OPERAND_LABEL12 :
424       print_normal (od, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), pc, length);
425       break;
426     case FR30_OPERAND_REGLIST_LOW :
427       print_low_register_list (od, info, fields->f_reglist_low, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
428       break;
429     case FR30_OPERAND_REGLIST_HI :
430       print_hi_register_list (od, info, fields->f_reglist_hi, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
431       break;
432     case FR30_OPERAND_CC :
433       print_normal (od, info, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
434       break;
435     case FR30_OPERAND_CCC :
436       print_normal (od, info, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
437       break;
438
439     default :
440       /* xgettext:c-format */
441       fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
442                opindex);
443     abort ();
444   }
445 }
446
447 cgen_extract_fn * const fr30_cgen_extract_handlers[] = 
448 {
449   0, /* default */
450   extract_insn_normal,
451 };
452
453 cgen_print_fn * const fr30_cgen_print_handlers[] = 
454 {
455   0, /* default */
456   print_insn_normal,
457 };
458
459
460 void
461 fr30_cgen_init_dis (od)
462      CGEN_OPCODE_DESC od;
463 {
464 }
465
466 \f
467 #if ! CGEN_INT_INSN_P
468
469 /* Subroutine of extract_normal.
470    Ensure sufficient bytes are cached in EX_INFO.
471    Returns 1 for success, 0 for failure.  */
472
473 static INLINE int
474 fill_cache (od, ex_info, offset, bytes, pc)
475      CGEN_OPCODE_DESC od;
476      CGEN_EXTRACT_INFO *ex_info;
477      int offset, bytes;
478      bfd_vma pc;
479 {
480   /* It's doubtful that the middle part has already been fetched so
481      we don't optimize that case.  kiss.  */
482   int mask;
483   disassemble_info *info = (disassemble_info *) ex_info->dis_info;
484
485   /* First do a quick check.  */
486   mask = (1 << bytes) - 1;
487   if (((ex_info->valid >> offset) & mask) == mask)
488     return 1;
489
490   /* Search for the first byte we need to read.  */
491   for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
492     if (! (mask & ex_info->valid))
493       break;
494
495   if (bytes)
496     {
497       int status;
498
499       pc += offset;
500       status = (*info->read_memory_func)
501         (pc, ex_info->insn_bytes + offset, bytes, info);
502
503       if (status != 0)
504         {
505           (*info->memory_error_func) (status, pc, info);
506           return 0;
507         }
508
509       ex_info->valid |= ((1 << bytes) - 1) << offset;
510     }
511
512   return 1;
513 }
514
515 /* Subroutine of extract_normal.  */
516
517 static INLINE long
518 extract_1 (od, ex_info, start, length, word_length, bufp, pc)
519      CGEN_OPCODE_DESC od;
520      CGEN_EXTRACT_INFO *ex_info;
521      int start,length,word_length;
522      unsigned char *bufp;
523      bfd_vma pc;
524 {
525   unsigned long x,mask;
526   int shift;
527   int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
528
529   switch (word_length)
530     {
531     case 8:
532       x = *bufp;
533       break;
534     case 16:
535       if (big_p)
536         x = bfd_getb16 (bufp);
537       else
538         x = bfd_getl16 (bufp);
539       break;
540     case 24:
541       /* ??? This may need reworking as these cases don't necessarily
542          want the first byte and the last two bytes handled like this.  */
543       if (big_p)
544         x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
545       else
546         x = bfd_getl16 (bufp) | (bufp[2] << 16);
547       break;
548     case 32:
549       if (big_p)
550         x = bfd_getb32 (bufp);
551       else
552         x = bfd_getl32 (bufp);
553       break;
554     default :
555       abort ();
556     }
557
558   /* Written this way to avoid undefined behaviour.  */
559   mask = (((1L << (length - 1)) - 1) << 1) | 1;
560   if (CGEN_INSN_LSB0_P)
561     shift = start;
562   else
563     shift = (word_length - (start + length));
564   return (x >> shift) & mask;
565 }
566
567 #endif /* ! CGEN_INT_INSN_P */
568
569 /* Default extraction routine.
570
571    INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order,
572    or sometimes less for cases like the m32r where the base insn size is 32
573    but some insns are 16 bits.
574    ATTRS is a mask of the boolean attributes.  We only need `unsigned',
575    but for generality we take a bitmask of all of them.
576    TOTAL_LENGTH is the length of the insn in bits.
577
578    Returns 1 for success, 0 for failure.  */
579
580 /* ??? This doesn't handle bfd_vma's.  Create another function when
581    necessary.  */
582
583 static int
584 extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc, valuep)
585      CGEN_OPCODE_DESC od;
586      CGEN_EXTRACT_INFO *ex_info;
587      CGEN_INSN_INT insn_value;
588      unsigned int attrs;
589      int start, length, total_length;
590      bfd_vma pc;
591      long *valuep;
592 {
593   unsigned long value;
594
595   /* If LENGTH is zero, this operand doesn't contribute to the value
596      so give it a standard value of zero.  */
597   if (length == 0)
598     {
599       *valuep = 0;
600       return 1;
601     }
602
603   if (CGEN_INT_INSN_P
604       || (CGEN_INSN_LSB0_P
605           ? ((total_length - start) <= CGEN_BASE_INSN_BITSIZE)
606           : ((start + length) <= CGEN_BASE_INSN_BITSIZE)))
607     {
608       /* Written this way to avoid undefined behaviour.  */
609       unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
610
611       if (CGEN_INSN_LSB0_P)
612         value = insn_value >> start;
613       else
614         value = insn_value >> (total_length - (start + length));
615       value &= mask;
616       /* sign extend? */
617       if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
618           && (value & (1L << (length - 1))))
619         value |= ~mask;
620     }
621
622 #if ! CGEN_INT_INSN_P
623
624   /* The hard case is probably too slow for the normal cases.
625      It's certainly more difficult to understand than the normal case.
626      Thus this is split into two.  The hard case is defined
627      to be when a field straddles a (loosely defined) word boundary
628      (??? which may require target specific help to determine).  */
629
630 #define HARD_CASE_P 0 /* FIXME:wip */
631
632   else if (HARD_CASE_P)
633     {
634     }
635
636   else
637     {
638       unsigned char *bufp = ex_info->insn_bytes;
639       int offset = 0;
640
641       if (length > 32)
642         abort ();
643
644       /* Adjust start,total_length,bufp to point to the pseudo-word that holds
645          the value.  For example in a 48 bit insn where the value to insert
646          (say an immediate value) is the last 16 bits then fetch_length here
647          would be 16.  To handle a 24 bit insn with an 18 bit immediate,
648          extract_1 handles 24 bits.  */
649
650       if (total_length > 32)
651         {
652           int needed_width = start % 8 + length;
653           int fetch_length = (needed_width <= 8 ? 8
654                               : needed_width <= 16 ? 16
655                               : 32);
656
657           if (CGEN_INSN_LSB0_P)
658             {
659               if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
660                 {
661                   abort (); /* wip */
662                 }
663               else
664                 {
665                   offset = start & ~7;
666
667                   bufp += offset / 8;
668                   start -= offset;
669                   total_length = fetch_length;
670                 }
671             }
672           else
673             {
674               if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
675                 {
676                   offset = start & ~7;
677
678                   bufp += offset / 8;
679                   start -= offset;
680                   total_length = fetch_length;
681                 }
682               else
683                 {
684                   abort (); /* wip */
685                 }
686             }
687         }
688
689       if (fill_cache (od, ex_info, offset / 8, total_length / 8, pc) == 0)
690         return 0;
691
692       value = extract_1 (od, ex_info, start, length, total_length, bufp, pc);
693     }
694
695 #endif /* ! CGEN_INT_INSN_P */
696
697   *valuep = value;
698
699   return 1;
700 }
701
702 /* Default print handler.  */
703
704 static void
705 print_normal (od, dis_info, value, attrs, pc, length)
706      CGEN_OPCODE_DESC od;
707      PTR dis_info;
708      long value;
709      unsigned int attrs;
710      bfd_vma pc;
711      int length;
712 {
713   disassemble_info *info = (disassemble_info *) dis_info;
714
715 #ifdef CGEN_PRINT_NORMAL
716   CGEN_PRINT_NORMAL (od, info, value, attrs, pc, length);
717 #endif
718
719   /* Print the operand as directed by the attributes.  */
720   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
721     ; /* nothing to do */
722   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
723     (*info->fprintf_func) (info->stream, "0x%lx", value);
724   else
725     (*info->fprintf_func) (info->stream, "%ld", value);
726 }
727
728 /* Default address handler.  */
729
730 static void
731 print_address (od, dis_info, value, attrs, pc, length)
732      CGEN_OPCODE_DESC od;
733      PTR dis_info;
734      bfd_vma value;
735      unsigned int attrs;
736      bfd_vma pc;
737      int length;
738 {
739   disassemble_info *info = (disassemble_info *) dis_info;
740
741 #ifdef CGEN_PRINT_ADDRESS
742   CGEN_PRINT_ADDRESS (od, info, value, attrs, pc, length);
743 #endif
744
745   /* Print the operand as directed by the attributes.  */
746   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
747     ; /* nothing to do */
748   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
749     (*info->print_address_func) (value, info);
750   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
751     (*info->print_address_func) (value, info);
752   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
753     (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
754   else
755     (*info->fprintf_func) (info->stream, "%ld", (long) value);
756 }
757
758 /* Keyword print handler.  */
759
760 static void
761 print_keyword (od, dis_info, keyword_table, value, attrs)
762      CGEN_OPCODE_DESC od;
763      PTR dis_info;
764      CGEN_KEYWORD *keyword_table;
765      long value;
766      unsigned int attrs;
767 {
768   disassemble_info *info = (disassemble_info *) dis_info;
769   const CGEN_KEYWORD_ENTRY *ke;
770
771   ke = cgen_keyword_lookup_value (keyword_table, value);
772   if (ke != NULL)
773     (*info->fprintf_func) (info->stream, "%s", ke->name);
774   else
775     (*info->fprintf_func) (info->stream, "???");
776 }
777 \f
778 /* Default insn extractor.
779
780    INSN_VALUE is the first CGEN_BASE_INSN_SIZE bytes, translated to host order.
781    The extracted fields are stored in FIELDS.
782    EX_INFO is used to handle reading variable length insns.
783    Return the length of the insn in bits, or 0 if no match,
784    or -1 if an error occurs fetching data (memory_error_func will have
785    been called).  */
786
787 static int
788 extract_insn_normal (od, insn, ex_info, insn_value, fields, pc)
789      CGEN_OPCODE_DESC od;
790      const CGEN_INSN *insn;
791      CGEN_EXTRACT_INFO *ex_info;
792      CGEN_INSN_INT insn_value;
793      CGEN_FIELDS *fields;
794      bfd_vma pc;
795 {
796   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
797   const unsigned char *syn;
798
799   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
800
801   CGEN_INIT_EXTRACT (od);
802
803   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
804     {
805       int length;
806
807       if (CGEN_SYNTAX_CHAR_P (*syn))
808         continue;
809
810       length = fr30_cgen_extract_operand (od, CGEN_SYNTAX_FIELD (*syn),
811                                             ex_info, insn_value, fields, pc);
812       if (length <= 0)
813         return length;
814     }
815
816   /* We recognized and successfully extracted this insn.  */
817   return CGEN_INSN_BITSIZE (insn);
818 }
819
820 /* Default insn printer.
821
822    DIS_INFO is defined as `PTR' so the disassembler needn't know anything
823    about disassemble_info.  */
824
825 static void
826 print_insn_normal (od, dis_info, insn, fields, pc, length)
827      CGEN_OPCODE_DESC od;
828      PTR dis_info;
829      const CGEN_INSN *insn;
830      CGEN_FIELDS *fields;
831      bfd_vma pc;
832      int length;
833 {
834   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
835   disassemble_info *info = (disassemble_info *) dis_info;
836   const unsigned char *syn;
837
838   CGEN_INIT_PRINT (od);
839
840   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
841     {
842       if (CGEN_SYNTAX_MNEMONIC_P (*syn))
843         {
844           (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
845           continue;
846         }
847       if (CGEN_SYNTAX_CHAR_P (*syn))
848         {
849           (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
850           continue;
851         }
852
853       /* We have an operand.  */
854       fr30_cgen_print_operand (od, CGEN_SYNTAX_FIELD (*syn), info,
855                                  fields, CGEN_INSN_ATTRS (insn), pc, length);
856     }
857 }
858 \f
859 /* Utility to print an insn.
860    BUF is the base part of the insn, target byte order, BUFLEN bytes long.
861    The result is the size of the insn in bytes or zero for an unknown insn
862    or -1 if an error occurs fetching data (memory_error_func will have
863    been called).  */
864
865 static int
866 print_insn (od, pc, info, buf, buflen)
867      CGEN_OPCODE_DESC od;
868      bfd_vma pc;
869      disassemble_info *info;
870      char *buf;
871      int buflen;
872 {
873   unsigned long insn_value;
874   const CGEN_INSN_LIST *insn_list;
875   CGEN_EXTRACT_INFO ex_info;
876
877   ex_info.dis_info = info;
878   ex_info.valid = (1 << CGEN_BASE_INSN_SIZE) - 1;
879   ex_info.insn_bytes = buf;
880
881   switch (buflen)
882     {
883     case 1:
884       insn_value = buf[0];
885       break;
886     case 2:
887       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
888       break;
889     case 4:
890       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
891       break;
892     default:
893       abort ();
894     }
895
896   /* The instructions are stored in hash lists.
897      Pick the first one and keep trying until we find the right one.  */
898
899   insn_list = CGEN_DIS_LOOKUP_INSN (od, buf, insn_value);
900   while (insn_list != NULL)
901     {
902       const CGEN_INSN *insn = insn_list->insn;
903       CGEN_FIELDS fields;
904       int length;
905
906 #if 0 /* not needed as insn shouldn't be in hash lists if not supported */
907       /* Supported by this cpu?  */
908       if (! fr30_cgen_insn_supported (od, insn))
909         continue;
910 #endif
911
912       /* Basic bit mask must be correct.  */
913       /* ??? May wish to allow target to defer this check until the extract
914          handler.  */
915       if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
916         {
917           /* Printing is handled in two passes.  The first pass parses the
918              machine insn and extracts the fields.  The second pass prints
919              them.  */
920
921           length = (*CGEN_EXTRACT_FN (insn)) (od, insn, &ex_info, insn_value,
922                                               &fields, pc);
923           /* length < 0 -> error */
924           if (length < 0)
925             return length;
926           if (length > 0)
927             {
928               (*CGEN_PRINT_FN (insn)) (od, info, insn, &fields, pc, length);
929               /* length is in bits, result is in bytes */
930               return length / 8;
931             }
932         }
933
934       insn_list = CGEN_DIS_NEXT_INSN (insn_list);
935     }
936
937   return 0;
938 }
939
940 /* Default value for CGEN_PRINT_INSN.
941    The result is the size of the insn in bytes or zero for an unknown insn
942    or -1 if an error occured fetching bytes.  */
943
944 #ifndef CGEN_PRINT_INSN
945 #define CGEN_PRINT_INSN default_print_insn
946 #endif
947
948 static int
949 default_print_insn (od, pc, info)
950      CGEN_OPCODE_DESC od;
951      bfd_vma pc;
952      disassemble_info *info;
953 {
954   char buf[CGEN_MAX_INSN_SIZE];
955   int status;
956
957   /* Read the base part of the insn.  */
958
959   status = (*info->read_memory_func) (pc, buf, CGEN_BASE_INSN_SIZE, info);
960   if (status != 0)
961     {
962       (*info->memory_error_func) (status, pc, info);
963       return -1;
964     }
965
966   return print_insn (od, pc, info, buf, CGEN_BASE_INSN_SIZE);
967 }
968
969 /* Main entry point.
970    Print one instruction from PC on INFO->STREAM.
971    Return the size of the instruction (in bytes).  */
972
973 int
974 print_insn_fr30 (pc, info)
975      bfd_vma pc;
976      disassemble_info *info;
977 {
978   int length;
979   static CGEN_OPCODE_DESC od = 0;
980   int mach = info->mach;
981   int big_p = info->endian == BFD_ENDIAN_BIG;
982
983   /* If we haven't initialized yet, initialize the opcode table.  */
984   if (! od)
985     {
986       od = fr30_cgen_opcode_open (mach,
987                                     big_p ?
988                                     CGEN_ENDIAN_BIG
989                                     : CGEN_ENDIAN_LITTLE);
990       fr30_cgen_init_dis (od);
991     }
992   /* If we've switched cpu's, re-initialize.  */
993   /* ??? Perhaps we should use BFD_ENDIAN.  */
994   else if (mach != CGEN_OPCODE_MACH (od)
995            || (CGEN_OPCODE_ENDIAN (od)
996                != (big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE)))
997     {
998       cgen_set_cpu (od, mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
999     }
1000
1001   /* We try to have as much common code as possible.
1002      But at this point some targets need to take over.  */
1003   /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
1004      but if not possible try to move this hook elsewhere rather than
1005      have two hooks.  */
1006   length = CGEN_PRINT_INSN (od, pc, info);
1007   if (length > 0)
1008     return length;
1009   if (length < 0)
1010     return -1;
1011
1012   (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1013   return CGEN_DEFAULT_INSN_SIZE;
1014 }