Mon Nov 16 19:21:48 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_BYTES,
45               unsigned int, int, int, int, 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               unsigned long, 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
65 /* Main entry point for operand extraction.
66
67    This function is basically just a big switch statement.  Earlier versions
68    used tables to look up the function to use, but
69    - if the table contains both assembler and disassembler functions then
70      the disassembler contains much of the assembler and vice-versa,
71    - there's a lot of inlining possibilities as things grow,
72    - using a switch statement avoids the function call overhead.
73
74    This function could be moved into `print_insn_normal', but keeping it
75    separate makes clear the interface between `print_insn_normal' and each of
76    the handlers.
77 */
78
79 int
80 fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
81      CGEN_OPCODE_DESC od;
82      int opindex;
83      CGEN_EXTRACT_INFO *ex_info;
84      CGEN_INSN_BYTES insn_value;
85      CGEN_FIELDS * fields;
86      bfd_vma pc;
87 {
88   int length;
89
90   switch (opindex)
91     {
92     case FR30_OPERAND_RI :
93       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_Ri);
94       break;
95     case FR30_OPERAND_RJ :
96       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_Rj);
97       break;
98     case FR30_OPERAND_RS1 :
99       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_Rs1);
100       break;
101     case FR30_OPERAND_RS2 :
102       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_Rs2);
103       break;
104     case FR30_OPERAND_R13 :
105       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_nil);
106       break;
107     case FR30_OPERAND_R14 :
108       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_nil);
109       break;
110     case FR30_OPERAND_R15 :
111       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_nil);
112       break;
113     case FR30_OPERAND_PS :
114       length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_nil);
115       break;
116     case FR30_OPERAND_U4 :
117       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_u4);
118       break;
119     case FR30_OPERAND_M4 :
120       {
121         long value;
122         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), & value);
123         value = ((value) | ((! (15))));
124         fields->f_m4 = value;
125       }
126       break;
127     case FR30_OPERAND_U8 :
128       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), & fields->f_u8);
129       break;
130     case FR30_OPERAND_I8 :
131       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), & fields->f_i8);
132       break;
133     case FR30_OPERAND_UDISP6 :
134       {
135         long value;
136         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), & value);
137         value = ((value) << (2));
138         fields->f_udisp6 = value;
139       }
140       break;
141     case FR30_OPERAND_DISP8 :
142       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), & fields->f_disp8);
143       break;
144     case FR30_OPERAND_DISP9 :
145       {
146         long value;
147         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), & value);
148         value = ((value) << (1));
149         fields->f_disp9 = value;
150       }
151       break;
152     case FR30_OPERAND_DISP10 :
153       {
154         long value;
155         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), & value);
156         value = ((value) << (2));
157         fields->f_disp10 = value;
158       }
159       break;
160     case FR30_OPERAND_S10 :
161       {
162         long value;
163         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), & value);
164         value = ((value) << (2));
165         fields->f_s10 = value;
166       }
167       break;
168     case FR30_OPERAND_U10 :
169       {
170         long value;
171         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), & value);
172         value = ((value) << (2));
173         fields->f_u10 = value;
174       }
175       break;
176     case FR30_OPERAND_DIR8 :
177       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), & fields->f_dir8);
178       break;
179     case FR30_OPERAND_DIR9 :
180       {
181         long value;
182         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), & value);
183         value = ((value) << (1));
184         fields->f_dir9 = value;
185       }
186       break;
187     case FR30_OPERAND_DIR10 :
188       {
189         long value;
190         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), & value);
191         value = ((value) << (2));
192         fields->f_dir10 = value;
193       }
194       break;
195     case FR30_OPERAND_LABEL9 :
196       {
197         long value;
198         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), & value);
199         value = ((((value) << (1))) + (((pc) & (-2))));
200         fields->f_rel9 = value;
201       }
202       break;
203     case FR30_OPERAND_LABEL12 :
204       {
205         long value;
206         length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_SIGNED), 5, 11, CGEN_FIELDS_BITSIZE (fields), & value);
207         value = ((((value) << (1))) + (((pc) & (-2))));
208         fields->f_rel12 = value;
209       }
210       break;
211     case FR30_OPERAND_CC :
212       length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_cc);
213       break;
214
215     default :
216       /* xgettext:c-format */
217       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
218                opindex);
219       abort ();
220     }
221
222   return length;
223 }
224
225 /* Main entry point for printing operands.
226
227    This function is basically just a big switch statement.  Earlier versions
228    used tables to look up the function to use, but
229    - if the table contains both assembler and disassembler functions then
230      the disassembler contains much of the assembler and vice-versa,
231    - there's a lot of inlining possibilities as things grow,
232    - using a switch statement avoids the function call overhead.
233
234    This function could be moved into `print_insn_normal', but keeping it
235    separate makes clear the interface between `print_insn_normal' and each of
236    the handlers.
237 */
238
239 void
240 fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
241      CGEN_OPCODE_DESC od;
242      int opindex;
243      disassemble_info * info;
244      CGEN_FIELDS * fields;
245      void const * attrs;
246      bfd_vma pc;
247      int length;
248 {
249   switch (opindex)
250     {
251     case FR30_OPERAND_RI :
252       print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED));
253       break;
254     case FR30_OPERAND_RJ :
255       print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED));
256       break;
257     case FR30_OPERAND_RS1 :
258       print_keyword (od, info, & fr30_cgen_opval_h_dr, fields->f_Rs1, 0|(1<<CGEN_OPERAND_UNSIGNED));
259       break;
260     case FR30_OPERAND_RS2 :
261       print_keyword (od, info, & fr30_cgen_opval_h_dr, fields->f_Rs2, 0|(1<<CGEN_OPERAND_UNSIGNED));
262       break;
263     case FR30_OPERAND_R13 :
264       print_keyword (od, info, & fr30_cgen_opval_h_r13, fields->f_nil, 0);
265       break;
266     case FR30_OPERAND_R14 :
267       print_keyword (od, info, & fr30_cgen_opval_h_r14, fields->f_nil, 0);
268       break;
269     case FR30_OPERAND_R15 :
270       print_keyword (od, info, & fr30_cgen_opval_h_r15, fields->f_nil, 0);
271       break;
272     case FR30_OPERAND_PS :
273       print_keyword (od, info, & fr30_cgen_opval_h_ps, fields->f_nil, 0);
274       break;
275     case FR30_OPERAND_U4 :
276       print_normal (od, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
277       break;
278     case FR30_OPERAND_M4 :
279       print_normal (od, info, fields->f_m4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
280       break;
281     case FR30_OPERAND_U8 :
282       print_normal (od, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
283       break;
284     case FR30_OPERAND_I8 :
285       print_normal (od, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
286       break;
287     case FR30_OPERAND_UDISP6 :
288       print_normal (od, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
289       break;
290     case FR30_OPERAND_DISP8 :
291       print_normal (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
292       break;
293     case FR30_OPERAND_DISP9 :
294       print_normal (od, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
295       break;
296     case FR30_OPERAND_DISP10 :
297       print_normal (od, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
298       break;
299     case FR30_OPERAND_S10 :
300       print_normal (od, info, fields->f_s10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
301       break;
302     case FR30_OPERAND_U10 :
303       print_normal (od, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
304       break;
305     case FR30_OPERAND_DIR8 :
306       print_normal (od, info, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
307       break;
308     case FR30_OPERAND_DIR9 :
309       print_normal (od, info, fields->f_dir9, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
310       break;
311     case FR30_OPERAND_DIR10 :
312       print_normal (od, info, fields->f_dir10, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
313       break;
314     case FR30_OPERAND_LABEL9 :
315       print_normal (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
316       break;
317     case FR30_OPERAND_LABEL12 :
318       print_normal (od, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
319       break;
320     case FR30_OPERAND_CC :
321       print_normal (od, info, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
322       break;
323
324     default :
325       /* xgettext:c-format */
326       fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
327                opindex);
328     abort ();
329   }
330 }
331
332 cgen_extract_fn * const fr30_cgen_extract_handlers[] = 
333 {
334   0, /* default */
335   extract_insn_normal,
336 };
337
338 cgen_print_fn * const fr30_cgen_print_handlers[] = 
339 {
340   0, /* default */
341   print_insn_normal,
342 };
343
344
345 void
346 fr30_cgen_init_dis (od)
347      CGEN_OPCODE_DESC od;
348 {
349 }
350
351 \f
352 #if ! CGEN_INT_INSN_P
353
354 /* Subroutine of extract_normal.  */
355
356 static INLINE long
357 extract_1 (od, ex_info, start, length, word_length, bufp)
358      CGEN_OPCODE_DESC od;
359      CGEN_EXTRACT_INFO *info;
360      int start,length,word_length;
361      unsigned char *bufp;
362 {
363   unsigned long x,mask;
364   int shift;
365   int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
366
367   /* FIXME: Need to use ex_info to ensure bytes have been fetched.  */
368
369   switch (word_length)
370     {
371     case 8:
372       x = *bufp;
373       break;
374     case 16:
375       if (big_p)
376         x = bfd_getb16 (bufp);
377       else
378         x = bfd_getl16 (bufp);
379       break;
380     case 24:
381       /* ??? This may need reworking as these cases don't necessarily
382          want the first byte and the last two bytes handled like this.  */
383       if (big_p)
384         x = (bfd_getb8 (bufp) << 16) | bfd_getb16 (bufp + 1);
385       else
386         x = bfd_getl16 (bufp) | (bfd_getb8 (bufp + 2) << 16);
387       break;
388     case 32:
389       if (big_p)
390         x = bfd_getb32 (bufp);
391       else
392         x = bfd_getl32 (bufp);
393       break;
394     default :
395       abort ();
396     }
397
398   /* Written this way to avoid undefined behaviour.  */
399   mask = (((1L << (length - 1)) - 1) << 1) | 1;
400   if (CGEN_INSN_LSB0_P)
401     shift = start;
402   else
403     shift = (word_length - (start + length));
404   return (x >> shift) & mask;
405 }
406
407 #endif /* ! CGEN_INT_INSN_P */
408
409 /* Default extraction routine.
410
411    ATTRS is a mask of the boolean attributes.  We only need `unsigned',
412    but for generality we take a bitmask of all of them.  */
413
414 /* ??? This doesn't handle bfd_vma's.  Create another function when
415    necessary.  */
416
417 static int
418 extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, valuep)
419      CGEN_OPCODE_DESC od;
420      CGEN_EXTRACT_INFO *ex_info;
421      CGEN_INSN_BYTES insn_value;
422      unsigned int attrs;
423      int start, length, total_length;
424      long *valuep;
425 {
426   unsigned long value;
427
428   /* If LENGTH is zero, this operand doesn't contribute to the value
429      so give it a standard value of zero.  */
430   if (length == 0)
431     {
432       *valuep = 0;
433       return 1;
434     }
435
436 #if CGEN_INT_INSN_P
437
438   {
439     /* Written this way to avoid undefined behaviour.  */
440     unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
441
442     if (CGEN_INSN_LSB0_P)
443       value = insn_value >> start;
444     else
445       value = insn_value >> (total_length - (start + length));
446     value &= mask;
447     /* sign extend? */
448     if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
449         && (value & (1L << (length - 1))))
450       value |= ~mask;
451   }
452
453 #else
454
455   /* The hard case is probably too slow for the normal cases.
456      It's certainly more difficult to understand than the normal case.
457      Thus this is split into two.  Keep it that way.  The hard case is defined
458      to be when a field straddles a (loosely defined) word boundary
459      (??? which may require target specific help to determine).  */
460
461 #if 0 /*wip*/
462
463 #define HARD_CASE_P 0 /* FIXME:wip */
464
465   if (HARD_CASE_P)
466     {
467     }
468 #endif
469   else
470     {
471       unsigned char *bufp = (unsigned char *) insn_value;
472
473       if (length > 32)
474         abort ();
475
476       /* Adjust start,total_length,bufp to point to the pseudo-word that holds
477          the value.  For example in a 48 bit insn where the value to insert
478          (say an immediate value) is the last 16 bits then word_length here
479          would be 16.  To handle a 24 bit insn with an 18 bit immediate,
480          extract_1 handles 24 bits (using a combination of bfd_get8,16).  */
481
482       if (total_length > 32)
483         {
484           int needed_width = start % 8 + length;
485           int fetch_length = (needed_width <= 8 ? 8
486                               : needed_width <= 16 ? 16
487                               : 32);
488
489           if (CGEN_INSN_LSB0_P)
490             {
491               if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
492                 {
493                   abort (); /* wip */
494                 }
495               else
496                 {
497                   int offset = start & ~7;
498
499                   bufp += offset / 8;
500                   start -= offset;
501                   total_length -= offset;
502                 }
503             }
504           else
505             {
506               if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
507                 {
508                   int offset = start & ~7;
509
510                   bufp += offset / 8;
511                   start -= offset;
512                   total_length -= offset;
513                 }
514               else
515                 {
516                   abort (); /* wip */
517                 }
518             }
519         }
520
521       /* FIXME: which bytes are being extracted have been lost.  */
522       value = extract_1 (od, ex_info, start, length, total_length, bufp);
523     }
524
525 #endif /* ! CGEN_INT_INSN_P */
526
527   *valuep = value;
528
529   /* FIXME: for now */
530   return 1;
531 }
532
533 /* Default print handler.  */
534
535 static void
536 print_normal (od, dis_info, value, attrs, pc, length)
537      CGEN_OPCODE_DESC od;
538      PTR dis_info;
539      long value;
540      unsigned int attrs;
541      bfd_vma pc;
542      int length;
543 {
544   disassemble_info *info = (disassemble_info *) dis_info;
545
546 #ifdef CGEN_PRINT_NORMAL
547   CGEN_PRINT_NORMAL (od, info, value, attrs, pc, length);
548 #endif
549
550   /* Print the operand as directed by the attributes.  */
551   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
552     ; /* nothing to do */
553   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
554     (*info->fprintf_func) (info->stream, "0x%lx", value);
555   else
556     (*info->fprintf_func) (info->stream, "%ld", value);
557 }
558
559 /* Default address handler.  */
560
561 static void
562 print_address (od, dis_info, value, attrs, pc, length)
563      CGEN_OPCODE_DESC od;
564      PTR dis_info;
565      bfd_vma value;
566      unsigned int attrs;
567      bfd_vma pc;
568      int length;
569 {
570   disassemble_info *info = (disassemble_info *) dis_info;
571
572 #ifdef CGEN_PRINT_ADDRESS
573   CGEN_PRINT_ADDRESS (od, info, value, attrs, pc, length);
574 #endif
575
576   /* Print the operand as directed by the attributes.  */
577   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
578     ; /* nothing to do */
579   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
580     (*info->print_address_func) (value, info);
581   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
582     (*info->print_address_func) (value, info);
583   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
584     (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
585   else
586     (*info->fprintf_func) (info->stream, "%ld", (long) value);
587 }
588
589 /* Keyword print handler.  */
590
591 static void
592 print_keyword (od, dis_info, keyword_table, value, attrs)
593      CGEN_OPCODE_DESC od;
594      PTR dis_info;
595      CGEN_KEYWORD *keyword_table;
596      long value;
597      unsigned int attrs;
598 {
599   disassemble_info *info = (disassemble_info *) dis_info;
600   const CGEN_KEYWORD_ENTRY *ke;
601
602   ke = cgen_keyword_lookup_value (keyword_table, value);
603   if (ke != NULL)
604     (*info->fprintf_func) (info->stream, "%s", ke->name);
605   else
606     (*info->fprintf_func) (info->stream, "???");
607 }
608 \f
609 /* Default insn extractor.
610
611    INSN_VALUE is the first CGEN_BASE_INSN_SIZE bytes, translated to host order.
612    The extracted fields are stored in FIELDS.
613    EX_INFO is used to handle reading variable length insns.
614    Return the length of the insn in bits, or 0 if no match,
615    or -1 if an error occurs fetching data (memory_error_func will have
616    been called).  */
617
618 static int
619 extract_insn_normal (od, insn, ex_info, insn_value, fields, pc)
620      CGEN_OPCODE_DESC od;
621      const CGEN_INSN *insn;
622      CGEN_EXTRACT_INFO *ex_info;
623      unsigned long insn_value;
624      CGEN_FIELDS *fields;
625      bfd_vma pc;
626 {
627   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
628   const unsigned char *syn;
629
630   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
631
632   CGEN_INIT_EXTRACT (od);
633
634   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
635     {
636       int length;
637
638       if (CGEN_SYNTAX_CHAR_P (*syn))
639         continue;
640
641       length = fr30_cgen_extract_operand (od, CGEN_SYNTAX_FIELD (*syn),
642                                             ex_info, insn_value, fields, pc);
643       if (length <= 0)
644         return length;
645     }
646
647   /* We recognized and successfully extracted this insn.  */
648   return CGEN_INSN_BITSIZE (insn);
649 }
650
651 /* Default insn printer.
652
653    DIS_INFO is defined as `PTR' so the disassembler needn't know anything
654    about disassemble_info.  */
655
656 static void
657 print_insn_normal (od, dis_info, insn, fields, pc, length)
658      CGEN_OPCODE_DESC od;
659      PTR dis_info;
660      const CGEN_INSN *insn;
661      CGEN_FIELDS *fields;
662      bfd_vma pc;
663      int length;
664 {
665   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
666   disassemble_info *info = (disassemble_info *) dis_info;
667   const unsigned char *syn;
668
669   CGEN_INIT_PRINT (od);
670
671   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
672     {
673       if (CGEN_SYNTAX_MNEMONIC_P (*syn))
674         {
675           (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
676           continue;
677         }
678       if (CGEN_SYNTAX_CHAR_P (*syn))
679         {
680           (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
681           continue;
682         }
683
684       /* We have an operand.  */
685       fr30_cgen_print_operand (od, CGEN_SYNTAX_FIELD (*syn), info,
686                                  fields, CGEN_INSN_ATTRS (insn), pc, length);
687     }
688 }
689 \f
690 /* Utility to print an insn.
691    BUF is the base part of the insn, target byte order, BUFLEN bytes long.
692    The result is the size of the insn in bytes or zero for an unknown insn
693    or -1 if an error occurs fetching data (memory_error_func will have
694    been called).  */
695
696 static int
697 print_insn (od, pc, info, buf, buflen)
698      CGEN_OPCODE_DESC od;
699      bfd_vma pc;
700      disassemble_info *info;
701      char *buf;
702      int buflen;
703 {
704   unsigned long insn_value;
705   const CGEN_INSN_LIST *insn_list;
706   CGEN_EXTRACT_INFO ex_info;
707
708   ex_info.dis_info = info;
709   ex_info.valid = (1 << CGEN_BASE_INSN_SIZE) - 1;
710   ex_info.bytes = buf;
711
712   switch (buflen)
713     {
714     case 1:
715       insn_value = buf[0];
716       break;
717     case 2:
718       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
719       break;
720     case 4:
721       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
722       break;
723     default:
724       abort ();
725     }
726
727   /* The instructions are stored in hash lists.
728      Pick the first one and keep trying until we find the right one.  */
729
730   insn_list = CGEN_DIS_LOOKUP_INSN (od, buf, insn_value);
731   while (insn_list != NULL)
732     {
733       const CGEN_INSN *insn = insn_list->insn;
734       CGEN_FIELDS fields;
735       int length;
736
737 #if 0 /* not needed as insn shouldn't be in hash lists if not supported */
738       /* Supported by this cpu?  */
739       if (! fr30_cgen_insn_supported (od, insn))
740         continue;
741 #endif
742
743       /* Basic bit mask must be correct.  */
744       /* ??? May wish to allow target to defer this check until the extract
745          handler.  */
746       if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
747         {
748           /* Printing is handled in two passes.  The first pass parses the
749              machine insn and extracts the fields.  The second pass prints
750              them.  */
751
752           length = (*CGEN_EXTRACT_FN (insn)) (od, insn, &ex_info, insn_value,
753                                               &fields, pc);
754           /* length < 0 -> error */
755           if (length < 0)
756             return length;
757           if (length > 0)
758             {
759               (*CGEN_PRINT_FN (insn)) (od, info, insn, &fields, pc, length);
760               /* length is in bits, result is in bytes */
761               return length / 8;
762             }
763         }
764
765       insn_list = CGEN_DIS_NEXT_INSN (insn_list);
766     }
767
768   return 0;
769 }
770
771 /* Default value for CGEN_PRINT_INSN.
772    The result is the size of the insn in bytes or zero for an unknown insn
773    or -1 if an error occured fetching bytes.  */
774
775 #ifndef CGEN_PRINT_INSN
776 #define CGEN_PRINT_INSN default_print_insn
777 #endif
778
779 static int
780 default_print_insn (od, pc, info)
781      CGEN_OPCODE_DESC od;
782      bfd_vma pc;
783      disassemble_info *info;
784 {
785   char buf[CGEN_MAX_INSN_SIZE];
786   int status;
787
788   /* Read the base part of the insn.  */
789
790   status = (*info->read_memory_func) (pc, buf, CGEN_BASE_INSN_SIZE, info);
791   if (status != 0)
792     {
793       (*info->memory_error_func) (status, pc, info);
794       return -1;
795     }
796
797   return print_insn (od, pc, info, buf, CGEN_BASE_INSN_SIZE);
798 }
799
800 /* Main entry point.
801    Print one instruction from PC on INFO->STREAM.
802    Return the size of the instruction (in bytes).  */
803
804 int
805 print_insn_fr30 (pc, info)
806      bfd_vma pc;
807      disassemble_info *info;
808 {
809   int length;
810   static CGEN_OPCODE_DESC od = 0;
811   int mach = info->mach;
812   int big_p = info->endian == BFD_ENDIAN_BIG;
813
814   /* If we haven't initialized yet, initialize the opcode table.  */
815   if (! od)
816     {
817       od = fr30_cgen_opcode_open (mach,
818                                     big_p ?
819                                     CGEN_ENDIAN_BIG
820                                     : CGEN_ENDIAN_LITTLE);
821       fr30_cgen_init_dis (od);
822     }
823   /* If we've switched cpu's, re-initialize.  */
824   /* ??? Perhaps we should use BFD_ENDIAN.  */
825   else if (mach != CGEN_OPCODE_MACH (od)
826            || (CGEN_OPCODE_ENDIAN (od)
827                != (big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE)))
828     {
829       cgen_set_cpu (od, mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
830     }
831
832   /* We try to have as much common code as possible.
833      But at this point some targets need to take over.  */
834   /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
835      but if not possible try to move this hook elsewhere rather than
836      have two hooks.  */
837   length = CGEN_PRINT_INSN (od, pc, info);
838   if (length > 0)
839     return length;
840   if (length < 0)
841     return -1;
842
843   (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
844   return CGEN_DEFAULT_INSN_SIZE;
845 }