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