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