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