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