106324dcfSchristos /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2ed0d50c3Schristos /* Disassembler interface for targets using CGEN. -*- C -*-
3ed0d50c3Schristos    CGEN: Cpu tools GENerator
4ed0d50c3Schristos 
5ed0d50c3Schristos    THIS FILE IS MACHINE GENERATED WITH CGEN.
6ed0d50c3Schristos    - the resultant file is machine generated, cgen-dis.in isn't
7ed0d50c3Schristos 
8*b88e3e88Schristos    Copyright (C) 1996-2020 Free Software Foundation, Inc.
9ed0d50c3Schristos 
10ed0d50c3Schristos    This file is part of libopcodes.
11ed0d50c3Schristos 
12ed0d50c3Schristos    This library is free software; you can redistribute it and/or modify
13ed0d50c3Schristos    it under the terms of the GNU General Public License as published by
14ed0d50c3Schristos    the Free Software Foundation; either version 3, or (at your option)
15ed0d50c3Schristos    any later version.
16ed0d50c3Schristos 
17ed0d50c3Schristos    It is distributed in the hope that it will be useful, but WITHOUT
18ed0d50c3Schristos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19ed0d50c3Schristos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20ed0d50c3Schristos    License for more details.
21ed0d50c3Schristos 
22ed0d50c3Schristos    You should have received a copy of the GNU General Public License
23ed0d50c3Schristos    along with this program; if not, write to the Free Software Foundation, Inc.,
24ed0d50c3Schristos    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
25ed0d50c3Schristos 
26ed0d50c3Schristos /* ??? Eventually more and more of this stuff can go to cpu-independent files.
27ed0d50c3Schristos    Keep that in mind.  */
28ed0d50c3Schristos 
29ed0d50c3Schristos #include "sysdep.h"
30ed0d50c3Schristos #include <stdio.h>
31ed0d50c3Schristos #include "ansidecl.h"
3206324dcfSchristos #include "disassemble.h"
33ed0d50c3Schristos #include "bfd.h"
34ed0d50c3Schristos #include "symcat.h"
35ed0d50c3Schristos #include "libiberty.h"
36ed0d50c3Schristos #include "fr30-desc.h"
37ed0d50c3Schristos #include "fr30-opc.h"
38ed0d50c3Schristos #include "opintl.h"
39ed0d50c3Schristos 
40ed0d50c3Schristos /* Default text to print if an instruction isn't recognized.  */
41ed0d50c3Schristos #define UNKNOWN_INSN_MSG _("*unknown*")
42ed0d50c3Schristos 
43ed0d50c3Schristos static void print_normal
44ed0d50c3Schristos   (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
45ed0d50c3Schristos static void print_address
46ed0d50c3Schristos   (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
47ed0d50c3Schristos static void print_keyword
48ed0d50c3Schristos   (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
49ed0d50c3Schristos static void print_insn_normal
50ed0d50c3Schristos   (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
51ed0d50c3Schristos static int print_insn
52ed0d50c3Schristos   (CGEN_CPU_DESC, bfd_vma,  disassemble_info *, bfd_byte *, unsigned);
53ed0d50c3Schristos static int default_print_insn
54ed0d50c3Schristos   (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
55ed0d50c3Schristos static int read_insn
56ed0d50c3Schristos   (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
57ed0d50c3Schristos    unsigned long *);
58ed0d50c3Schristos 
59ed0d50c3Schristos /* -- disassembler routines inserted here.  */
60ed0d50c3Schristos 
61ed0d50c3Schristos /* -- dis.c */
62ed0d50c3Schristos static void
print_register_list(void * dis_info,long value,long offset,int load_store)63ed0d50c3Schristos print_register_list (void * dis_info,
64ed0d50c3Schristos 		     long value,
65ed0d50c3Schristos 		     long offset,
66ed0d50c3Schristos 		     int load_store) /* 0 == load, 1 == store.  */
67ed0d50c3Schristos {
68ed0d50c3Schristos   disassemble_info *info = dis_info;
69ed0d50c3Schristos   int mask;
70ed0d50c3Schristos   int reg_index = 0;
71ed0d50c3Schristos   char * comma = "";
72ed0d50c3Schristos 
73ed0d50c3Schristos   if (load_store)
74ed0d50c3Schristos     mask = 0x80;
75ed0d50c3Schristos   else
76ed0d50c3Schristos     mask = 1;
77ed0d50c3Schristos 
78ed0d50c3Schristos   if (value & mask)
79ed0d50c3Schristos     {
80ed0d50c3Schristos       (*info->fprintf_func) (info->stream, "r%li", reg_index + offset);
81ed0d50c3Schristos       comma = ",";
82ed0d50c3Schristos     }
83ed0d50c3Schristos 
84ed0d50c3Schristos   for (reg_index = 1; reg_index <= 7; ++reg_index)
85ed0d50c3Schristos     {
86ed0d50c3Schristos       if (load_store)
87ed0d50c3Schristos 	mask >>= 1;
88ed0d50c3Schristos       else
89ed0d50c3Schristos 	mask <<= 1;
90ed0d50c3Schristos 
91ed0d50c3Schristos       if (value & mask)
92ed0d50c3Schristos 	{
93ed0d50c3Schristos 	  (*info->fprintf_func) (info->stream, "%sr%li", comma, reg_index + offset);
94ed0d50c3Schristos 	  comma = ",";
95ed0d50c3Schristos 	}
96ed0d50c3Schristos     }
97ed0d50c3Schristos }
98ed0d50c3Schristos 
99ed0d50c3Schristos static void
print_hi_register_list_ld(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,long value,unsigned int attrs ATTRIBUTE_UNUSED,bfd_vma pc ATTRIBUTE_UNUSED,int length ATTRIBUTE_UNUSED)100ed0d50c3Schristos print_hi_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
101ed0d50c3Schristos 			   void * dis_info,
102ed0d50c3Schristos 			   long value,
103ed0d50c3Schristos 			   unsigned int attrs ATTRIBUTE_UNUSED,
104ed0d50c3Schristos 			   bfd_vma pc ATTRIBUTE_UNUSED,
105ed0d50c3Schristos 			   int length ATTRIBUTE_UNUSED)
106ed0d50c3Schristos {
107ed0d50c3Schristos   print_register_list (dis_info, value, 8, 0 /* Load.  */);
108ed0d50c3Schristos }
109ed0d50c3Schristos 
110ed0d50c3Schristos static void
print_low_register_list_ld(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,long value,unsigned int attrs ATTRIBUTE_UNUSED,bfd_vma pc ATTRIBUTE_UNUSED,int length ATTRIBUTE_UNUSED)111ed0d50c3Schristos print_low_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
112ed0d50c3Schristos 			    void * dis_info,
113ed0d50c3Schristos 			    long value,
114ed0d50c3Schristos 			    unsigned int attrs ATTRIBUTE_UNUSED,
115ed0d50c3Schristos 			    bfd_vma pc ATTRIBUTE_UNUSED,
116ed0d50c3Schristos 			    int length ATTRIBUTE_UNUSED)
117ed0d50c3Schristos {
118ed0d50c3Schristos   print_register_list (dis_info, value, 0, 0 /* Load.  */);
119ed0d50c3Schristos }
120ed0d50c3Schristos 
121ed0d50c3Schristos static void
print_hi_register_list_st(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,long value,unsigned int attrs ATTRIBUTE_UNUSED,bfd_vma pc ATTRIBUTE_UNUSED,int length ATTRIBUTE_UNUSED)122ed0d50c3Schristos print_hi_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
123ed0d50c3Schristos 			   void * dis_info,
124ed0d50c3Schristos 			   long value,
125ed0d50c3Schristos 			   unsigned int attrs ATTRIBUTE_UNUSED,
126ed0d50c3Schristos 			   bfd_vma pc ATTRIBUTE_UNUSED,
127ed0d50c3Schristos 			   int length ATTRIBUTE_UNUSED)
128ed0d50c3Schristos {
129ed0d50c3Schristos   print_register_list (dis_info, value, 8, 1 /* Store.  */);
130ed0d50c3Schristos }
131ed0d50c3Schristos 
132ed0d50c3Schristos static void
print_low_register_list_st(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,long value,unsigned int attrs ATTRIBUTE_UNUSED,bfd_vma pc ATTRIBUTE_UNUSED,int length ATTRIBUTE_UNUSED)133ed0d50c3Schristos print_low_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
134ed0d50c3Schristos 			    void * dis_info,
135ed0d50c3Schristos 			    long value,
136ed0d50c3Schristos 			    unsigned int attrs ATTRIBUTE_UNUSED,
137ed0d50c3Schristos 			    bfd_vma pc ATTRIBUTE_UNUSED,
138ed0d50c3Schristos 			    int length ATTRIBUTE_UNUSED)
139ed0d50c3Schristos {
140ed0d50c3Schristos   print_register_list (dis_info, value, 0, 1 /* Store.  */);
141ed0d50c3Schristos }
142ed0d50c3Schristos 
143ed0d50c3Schristos static void
print_m4(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,long value,unsigned int attrs ATTRIBUTE_UNUSED,bfd_vma pc ATTRIBUTE_UNUSED,int length ATTRIBUTE_UNUSED)144ed0d50c3Schristos print_m4 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
145ed0d50c3Schristos 	  void * dis_info,
146ed0d50c3Schristos 	  long value,
147ed0d50c3Schristos 	  unsigned int attrs ATTRIBUTE_UNUSED,
148ed0d50c3Schristos 	  bfd_vma pc ATTRIBUTE_UNUSED,
149ed0d50c3Schristos 	  int length ATTRIBUTE_UNUSED)
150ed0d50c3Schristos {
151ed0d50c3Schristos   disassemble_info *info = (disassemble_info *) dis_info;
152ed0d50c3Schristos 
153ed0d50c3Schristos   (*info->fprintf_func) (info->stream, "%ld", value);
154ed0d50c3Schristos }
155ed0d50c3Schristos /* -- */
156ed0d50c3Schristos 
157ed0d50c3Schristos void fr30_cgen_print_operand
158ed0d50c3Schristos   (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int);
159ed0d50c3Schristos 
160ed0d50c3Schristos /* Main entry point for printing operands.
161ed0d50c3Schristos    XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
162ed0d50c3Schristos    of dis-asm.h on cgen.h.
163ed0d50c3Schristos 
164ed0d50c3Schristos    This function is basically just a big switch statement.  Earlier versions
165ed0d50c3Schristos    used tables to look up the function to use, but
166ed0d50c3Schristos    - if the table contains both assembler and disassembler functions then
167ed0d50c3Schristos      the disassembler contains much of the assembler and vice-versa,
168ed0d50c3Schristos    - there's a lot of inlining possibilities as things grow,
169ed0d50c3Schristos    - using a switch statement avoids the function call overhead.
170ed0d50c3Schristos 
171ed0d50c3Schristos    This function could be moved into `print_insn_normal', but keeping it
172ed0d50c3Schristos    separate makes clear the interface between `print_insn_normal' and each of
173ed0d50c3Schristos    the handlers.  */
174ed0d50c3Schristos 
175ed0d50c3Schristos void
fr30_cgen_print_operand(CGEN_CPU_DESC cd,int opindex,void * xinfo,CGEN_FIELDS * fields,void const * attrs ATTRIBUTE_UNUSED,bfd_vma pc,int length)176ed0d50c3Schristos fr30_cgen_print_operand (CGEN_CPU_DESC cd,
177ed0d50c3Schristos 			   int opindex,
178ed0d50c3Schristos 			   void * xinfo,
179ed0d50c3Schristos 			   CGEN_FIELDS *fields,
180ed0d50c3Schristos 			   void const *attrs ATTRIBUTE_UNUSED,
181ed0d50c3Schristos 			   bfd_vma pc,
182ed0d50c3Schristos 			   int length)
183ed0d50c3Schristos {
184ed0d50c3Schristos   disassemble_info *info = (disassemble_info *) xinfo;
185ed0d50c3Schristos 
186ed0d50c3Schristos   switch (opindex)
187ed0d50c3Schristos     {
188ed0d50c3Schristos     case FR30_OPERAND_CRI :
189ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRi, 0);
190ed0d50c3Schristos       break;
191ed0d50c3Schristos     case FR30_OPERAND_CRJ :
192ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRj, 0);
193ed0d50c3Schristos       break;
194ed0d50c3Schristos     case FR30_OPERAND_R13 :
195ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_h_r13, 0, 0);
196ed0d50c3Schristos       break;
197ed0d50c3Schristos     case FR30_OPERAND_R14 :
198ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_h_r14, 0, 0);
199ed0d50c3Schristos       break;
200ed0d50c3Schristos     case FR30_OPERAND_R15 :
201ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_h_r15, 0, 0);
202ed0d50c3Schristos       break;
203ed0d50c3Schristos     case FR30_OPERAND_RI :
204ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ri, 0);
205ed0d50c3Schristos       break;
206ed0d50c3Schristos     case FR30_OPERAND_RIC :
207ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ric, 0);
208ed0d50c3Schristos       break;
209ed0d50c3Schristos     case FR30_OPERAND_RJ :
210ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rj, 0);
211ed0d50c3Schristos       break;
212ed0d50c3Schristos     case FR30_OPERAND_RJC :
213ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rjc, 0);
214ed0d50c3Schristos       break;
215ed0d50c3Schristos     case FR30_OPERAND_RS1 :
216ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs1, 0);
217ed0d50c3Schristos       break;
218ed0d50c3Schristos     case FR30_OPERAND_RS2 :
219ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs2, 0);
220ed0d50c3Schristos       break;
221ed0d50c3Schristos     case FR30_OPERAND_CC :
222ed0d50c3Schristos       print_normal (cd, info, fields->f_cc, 0, pc, length);
223ed0d50c3Schristos       break;
224ed0d50c3Schristos     case FR30_OPERAND_CCC :
225ed0d50c3Schristos       print_normal (cd, info, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
226ed0d50c3Schristos       break;
227ed0d50c3Schristos     case FR30_OPERAND_DIR10 :
228ed0d50c3Schristos       print_normal (cd, info, fields->f_dir10, 0, pc, length);
229ed0d50c3Schristos       break;
230ed0d50c3Schristos     case FR30_OPERAND_DIR8 :
231ed0d50c3Schristos       print_normal (cd, info, fields->f_dir8, 0, pc, length);
232ed0d50c3Schristos       break;
233ed0d50c3Schristos     case FR30_OPERAND_DIR9 :
234ed0d50c3Schristos       print_normal (cd, info, fields->f_dir9, 0, pc, length);
235ed0d50c3Schristos       break;
236ed0d50c3Schristos     case FR30_OPERAND_DISP10 :
237ed0d50c3Schristos       print_normal (cd, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
238ed0d50c3Schristos       break;
239ed0d50c3Schristos     case FR30_OPERAND_DISP8 :
240ed0d50c3Schristos       print_normal (cd, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
241ed0d50c3Schristos       break;
242ed0d50c3Schristos     case FR30_OPERAND_DISP9 :
243ed0d50c3Schristos       print_normal (cd, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
244ed0d50c3Schristos       break;
245ed0d50c3Schristos     case FR30_OPERAND_I20 :
246ed0d50c3Schristos       print_normal (cd, info, fields->f_i20, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
247ed0d50c3Schristos       break;
248ed0d50c3Schristos     case FR30_OPERAND_I32 :
249ed0d50c3Schristos       print_normal (cd, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT), pc, length);
250ed0d50c3Schristos       break;
251ed0d50c3Schristos     case FR30_OPERAND_I8 :
252ed0d50c3Schristos       print_normal (cd, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
253ed0d50c3Schristos       break;
254ed0d50c3Schristos     case FR30_OPERAND_LABEL12 :
255ed0d50c3Schristos       print_address (cd, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
256ed0d50c3Schristos       break;
257ed0d50c3Schristos     case FR30_OPERAND_LABEL9 :
258ed0d50c3Schristos       print_address (cd, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
259ed0d50c3Schristos       break;
260ed0d50c3Schristos     case FR30_OPERAND_M4 :
261ed0d50c3Schristos       print_m4 (cd, info, fields->f_m4, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
262ed0d50c3Schristos       break;
263ed0d50c3Schristos     case FR30_OPERAND_PS :
264ed0d50c3Schristos       print_keyword (cd, info, & fr30_cgen_opval_h_ps, 0, 0);
265ed0d50c3Schristos       break;
266ed0d50c3Schristos     case FR30_OPERAND_REGLIST_HI_LD :
267ed0d50c3Schristos       print_hi_register_list_ld (cd, info, fields->f_reglist_hi_ld, 0, pc, length);
268ed0d50c3Schristos       break;
269ed0d50c3Schristos     case FR30_OPERAND_REGLIST_HI_ST :
270ed0d50c3Schristos       print_hi_register_list_st (cd, info, fields->f_reglist_hi_st, 0, pc, length);
271ed0d50c3Schristos       break;
272ed0d50c3Schristos     case FR30_OPERAND_REGLIST_LOW_LD :
273ed0d50c3Schristos       print_low_register_list_ld (cd, info, fields->f_reglist_low_ld, 0, pc, length);
274ed0d50c3Schristos       break;
275ed0d50c3Schristos     case FR30_OPERAND_REGLIST_LOW_ST :
276ed0d50c3Schristos       print_low_register_list_st (cd, info, fields->f_reglist_low_st, 0, pc, length);
277ed0d50c3Schristos       break;
278ed0d50c3Schristos     case FR30_OPERAND_S10 :
279ed0d50c3Schristos       print_normal (cd, info, fields->f_s10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
280ed0d50c3Schristos       break;
281ed0d50c3Schristos     case FR30_OPERAND_U10 :
282ed0d50c3Schristos       print_normal (cd, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
283ed0d50c3Schristos       break;
284ed0d50c3Schristos     case FR30_OPERAND_U4 :
285ed0d50c3Schristos       print_normal (cd, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
286ed0d50c3Schristos       break;
287ed0d50c3Schristos     case FR30_OPERAND_U4C :
288ed0d50c3Schristos       print_normal (cd, info, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
289ed0d50c3Schristos       break;
290ed0d50c3Schristos     case FR30_OPERAND_U8 :
291ed0d50c3Schristos       print_normal (cd, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
292ed0d50c3Schristos       break;
293ed0d50c3Schristos     case FR30_OPERAND_UDISP6 :
294ed0d50c3Schristos       print_normal (cd, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
295ed0d50c3Schristos       break;
296ed0d50c3Schristos 
297ed0d50c3Schristos     default :
298ed0d50c3Schristos       /* xgettext:c-format */
29906324dcfSchristos       opcodes_error_handler
30006324dcfSchristos 	(_("internal error: unrecognized field %d while printing insn"),
301ed0d50c3Schristos 	 opindex);
302ed0d50c3Schristos       abort ();
303ed0d50c3Schristos   }
304ed0d50c3Schristos }
305ed0d50c3Schristos 
306ed0d50c3Schristos cgen_print_fn * const fr30_cgen_print_handlers[] =
307ed0d50c3Schristos {
308ed0d50c3Schristos   print_insn_normal,
309ed0d50c3Schristos };
310ed0d50c3Schristos 
311ed0d50c3Schristos 
312ed0d50c3Schristos void
fr30_cgen_init_dis(CGEN_CPU_DESC cd)313ed0d50c3Schristos fr30_cgen_init_dis (CGEN_CPU_DESC cd)
314ed0d50c3Schristos {
315ed0d50c3Schristos   fr30_cgen_init_opcode_table (cd);
316ed0d50c3Schristos   fr30_cgen_init_ibld_table (cd);
317ed0d50c3Schristos   cd->print_handlers = & fr30_cgen_print_handlers[0];
318ed0d50c3Schristos   cd->print_operand = fr30_cgen_print_operand;
319ed0d50c3Schristos }
320ed0d50c3Schristos 
321ed0d50c3Schristos 
322ed0d50c3Schristos /* Default print handler.  */
323ed0d50c3Schristos 
324ed0d50c3Schristos static void
print_normal(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,long value,unsigned int attrs,bfd_vma pc ATTRIBUTE_UNUSED,int length ATTRIBUTE_UNUSED)325ed0d50c3Schristos print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
326ed0d50c3Schristos 	      void *dis_info,
327ed0d50c3Schristos 	      long value,
328ed0d50c3Schristos 	      unsigned int attrs,
329ed0d50c3Schristos 	      bfd_vma pc ATTRIBUTE_UNUSED,
330ed0d50c3Schristos 	      int length ATTRIBUTE_UNUSED)
331ed0d50c3Schristos {
332ed0d50c3Schristos   disassemble_info *info = (disassemble_info *) dis_info;
333ed0d50c3Schristos 
334ed0d50c3Schristos   /* Print the operand as directed by the attributes.  */
335ed0d50c3Schristos   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
336ed0d50c3Schristos     ; /* nothing to do */
337ed0d50c3Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
338ed0d50c3Schristos     (*info->fprintf_func) (info->stream, "%ld", value);
339ed0d50c3Schristos   else
340ed0d50c3Schristos     (*info->fprintf_func) (info->stream, "0x%lx", value);
341ed0d50c3Schristos }
342ed0d50c3Schristos 
343ed0d50c3Schristos /* Default address handler.  */
344ed0d50c3Schristos 
345ed0d50c3Schristos static void
print_address(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,bfd_vma value,unsigned int attrs,bfd_vma pc ATTRIBUTE_UNUSED,int length ATTRIBUTE_UNUSED)346ed0d50c3Schristos print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
347ed0d50c3Schristos 	       void *dis_info,
348ed0d50c3Schristos 	       bfd_vma value,
349ed0d50c3Schristos 	       unsigned int attrs,
350ed0d50c3Schristos 	       bfd_vma pc ATTRIBUTE_UNUSED,
351ed0d50c3Schristos 	       int length ATTRIBUTE_UNUSED)
352ed0d50c3Schristos {
353ed0d50c3Schristos   disassemble_info *info = (disassemble_info *) dis_info;
354ed0d50c3Schristos 
355ed0d50c3Schristos   /* Print the operand as directed by the attributes.  */
356ed0d50c3Schristos   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
357ed0d50c3Schristos     ; /* Nothing to do.  */
358ed0d50c3Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
359ed0d50c3Schristos     (*info->print_address_func) (value, info);
360ed0d50c3Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
361ed0d50c3Schristos     (*info->print_address_func) (value, info);
362ed0d50c3Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
363ed0d50c3Schristos     (*info->fprintf_func) (info->stream, "%ld", (long) value);
364ed0d50c3Schristos   else
365ed0d50c3Schristos     (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
366ed0d50c3Schristos }
367ed0d50c3Schristos 
368ed0d50c3Schristos /* Keyword print handler.  */
369ed0d50c3Schristos 
370ed0d50c3Schristos static void
print_keyword(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,CGEN_KEYWORD * keyword_table,long value,unsigned int attrs ATTRIBUTE_UNUSED)371ed0d50c3Schristos print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
372ed0d50c3Schristos 	       void *dis_info,
373ed0d50c3Schristos 	       CGEN_KEYWORD *keyword_table,
374ed0d50c3Schristos 	       long value,
375ed0d50c3Schristos 	       unsigned int attrs ATTRIBUTE_UNUSED)
376ed0d50c3Schristos {
377ed0d50c3Schristos   disassemble_info *info = (disassemble_info *) dis_info;
378ed0d50c3Schristos   const CGEN_KEYWORD_ENTRY *ke;
379ed0d50c3Schristos 
380ed0d50c3Schristos   ke = cgen_keyword_lookup_value (keyword_table, value);
381ed0d50c3Schristos   if (ke != NULL)
382ed0d50c3Schristos     (*info->fprintf_func) (info->stream, "%s", ke->name);
383ed0d50c3Schristos   else
384ed0d50c3Schristos     (*info->fprintf_func) (info->stream, "???");
385ed0d50c3Schristos }
386ed0d50c3Schristos 
387ed0d50c3Schristos /* Default insn printer.
388ed0d50c3Schristos 
389ed0d50c3Schristos    DIS_INFO is defined as `void *' so the disassembler needn't know anything
390ed0d50c3Schristos    about disassemble_info.  */
391ed0d50c3Schristos 
392ed0d50c3Schristos static void
print_insn_normal(CGEN_CPU_DESC cd,void * dis_info,const CGEN_INSN * insn,CGEN_FIELDS * fields,bfd_vma pc,int length)393ed0d50c3Schristos print_insn_normal (CGEN_CPU_DESC cd,
394ed0d50c3Schristos 		   void *dis_info,
395ed0d50c3Schristos 		   const CGEN_INSN *insn,
396ed0d50c3Schristos 		   CGEN_FIELDS *fields,
397ed0d50c3Schristos 		   bfd_vma pc,
398ed0d50c3Schristos 		   int length)
399ed0d50c3Schristos {
400ed0d50c3Schristos   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
401ed0d50c3Schristos   disassemble_info *info = (disassemble_info *) dis_info;
402ed0d50c3Schristos   const CGEN_SYNTAX_CHAR_TYPE *syn;
403ed0d50c3Schristos 
404ed0d50c3Schristos   CGEN_INIT_PRINT (cd);
405ed0d50c3Schristos 
406ed0d50c3Schristos   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
407ed0d50c3Schristos     {
408ed0d50c3Schristos       if (CGEN_SYNTAX_MNEMONIC_P (*syn))
409ed0d50c3Schristos 	{
410ed0d50c3Schristos 	  (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
411ed0d50c3Schristos 	  continue;
412ed0d50c3Schristos 	}
413ed0d50c3Schristos       if (CGEN_SYNTAX_CHAR_P (*syn))
414ed0d50c3Schristos 	{
415ed0d50c3Schristos 	  (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
416ed0d50c3Schristos 	  continue;
417ed0d50c3Schristos 	}
418ed0d50c3Schristos 
419ed0d50c3Schristos       /* We have an operand.  */
420ed0d50c3Schristos       fr30_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
421ed0d50c3Schristos 				 fields, CGEN_INSN_ATTRS (insn), pc, length);
422ed0d50c3Schristos     }
423ed0d50c3Schristos }
424ed0d50c3Schristos 
425ed0d50c3Schristos /* Subroutine of print_insn. Reads an insn into the given buffers and updates
426ed0d50c3Schristos    the extract info.
427ed0d50c3Schristos    Returns 0 if all is well, non-zero otherwise.  */
428ed0d50c3Schristos 
429ed0d50c3Schristos static int
read_insn(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,bfd_vma pc,disassemble_info * info,bfd_byte * buf,int buflen,CGEN_EXTRACT_INFO * ex_info,unsigned long * insn_value)430ed0d50c3Schristos read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
431ed0d50c3Schristos 	   bfd_vma pc,
432ed0d50c3Schristos 	   disassemble_info *info,
433ed0d50c3Schristos 	   bfd_byte *buf,
434ed0d50c3Schristos 	   int buflen,
435ed0d50c3Schristos 	   CGEN_EXTRACT_INFO *ex_info,
436ed0d50c3Schristos 	   unsigned long *insn_value)
437ed0d50c3Schristos {
438ed0d50c3Schristos   int status = (*info->read_memory_func) (pc, buf, buflen, info);
439ed0d50c3Schristos 
440ed0d50c3Schristos   if (status != 0)
441ed0d50c3Schristos     {
442ed0d50c3Schristos       (*info->memory_error_func) (status, pc, info);
443ed0d50c3Schristos       return -1;
444ed0d50c3Schristos     }
445ed0d50c3Schristos 
446ed0d50c3Schristos   ex_info->dis_info = info;
447ed0d50c3Schristos   ex_info->valid = (1 << buflen) - 1;
448ed0d50c3Schristos   ex_info->insn_bytes = buf;
449ed0d50c3Schristos 
450ed0d50c3Schristos   *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
451ed0d50c3Schristos   return 0;
452ed0d50c3Schristos }
453ed0d50c3Schristos 
454ed0d50c3Schristos /* Utility to print an insn.
455ed0d50c3Schristos    BUF is the base part of the insn, target byte order, BUFLEN bytes long.
456ed0d50c3Schristos    The result is the size of the insn in bytes or zero for an unknown insn
457ed0d50c3Schristos    or -1 if an error occurs fetching data (memory_error_func will have
458ed0d50c3Schristos    been called).  */
459ed0d50c3Schristos 
460ed0d50c3Schristos static int
print_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info,bfd_byte * buf,unsigned int buflen)461ed0d50c3Schristos print_insn (CGEN_CPU_DESC cd,
462ed0d50c3Schristos 	    bfd_vma pc,
463ed0d50c3Schristos 	    disassemble_info *info,
464ed0d50c3Schristos 	    bfd_byte *buf,
465ed0d50c3Schristos 	    unsigned int buflen)
466ed0d50c3Schristos {
467ed0d50c3Schristos   CGEN_INSN_INT insn_value;
468ed0d50c3Schristos   const CGEN_INSN_LIST *insn_list;
469ed0d50c3Schristos   CGEN_EXTRACT_INFO ex_info;
470ed0d50c3Schristos   int basesize;
471ed0d50c3Schristos 
472ed0d50c3Schristos   /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
473ed0d50c3Schristos   basesize = cd->base_insn_bitsize < buflen * 8 ?
474ed0d50c3Schristos                                      cd->base_insn_bitsize : buflen * 8;
475ed0d50c3Schristos   insn_value = cgen_get_insn_value (cd, buf, basesize);
476ed0d50c3Schristos 
477ed0d50c3Schristos 
478ed0d50c3Schristos   /* Fill in ex_info fields like read_insn would.  Don't actually call
479ed0d50c3Schristos      read_insn, since the incoming buffer is already read (and possibly
480ed0d50c3Schristos      modified a la m32r).  */
481ed0d50c3Schristos   ex_info.valid = (1 << buflen) - 1;
482ed0d50c3Schristos   ex_info.dis_info = info;
483ed0d50c3Schristos   ex_info.insn_bytes = buf;
484ed0d50c3Schristos 
485ed0d50c3Schristos   /* The instructions are stored in hash lists.
486ed0d50c3Schristos      Pick the first one and keep trying until we find the right one.  */
487ed0d50c3Schristos 
488ed0d50c3Schristos   insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
489ed0d50c3Schristos   while (insn_list != NULL)
490ed0d50c3Schristos     {
491ed0d50c3Schristos       const CGEN_INSN *insn = insn_list->insn;
492ed0d50c3Schristos       CGEN_FIELDS fields;
493ed0d50c3Schristos       int length;
494ed0d50c3Schristos       unsigned long insn_value_cropped;
495ed0d50c3Schristos 
496ed0d50c3Schristos #ifdef CGEN_VALIDATE_INSN_SUPPORTED
497ed0d50c3Schristos       /* Not needed as insn shouldn't be in hash lists if not supported.  */
498ed0d50c3Schristos       /* Supported by this cpu?  */
499ed0d50c3Schristos       if (! fr30_cgen_insn_supported (cd, insn))
500ed0d50c3Schristos         {
501ed0d50c3Schristos           insn_list = CGEN_DIS_NEXT_INSN (insn_list);
502ed0d50c3Schristos 	  continue;
503ed0d50c3Schristos         }
504ed0d50c3Schristos #endif
505ed0d50c3Schristos 
506ed0d50c3Schristos       /* Basic bit mask must be correct.  */
507ed0d50c3Schristos       /* ??? May wish to allow target to defer this check until the extract
508ed0d50c3Schristos 	 handler.  */
509ed0d50c3Schristos 
510ed0d50c3Schristos       /* Base size may exceed this instruction's size.  Extract the
511ed0d50c3Schristos          relevant part from the buffer. */
512ed0d50c3Schristos       if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
513ed0d50c3Schristos 	  (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
514ed0d50c3Schristos 	insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
515ed0d50c3Schristos 					   info->endian == BFD_ENDIAN_BIG);
516ed0d50c3Schristos       else
517ed0d50c3Schristos 	insn_value_cropped = insn_value;
518ed0d50c3Schristos 
519ed0d50c3Schristos       if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
520ed0d50c3Schristos 	  == CGEN_INSN_BASE_VALUE (insn))
521ed0d50c3Schristos 	{
522ed0d50c3Schristos 	  /* Printing is handled in two passes.  The first pass parses the
523ed0d50c3Schristos 	     machine insn and extracts the fields.  The second pass prints
524ed0d50c3Schristos 	     them.  */
525ed0d50c3Schristos 
526ed0d50c3Schristos 	  /* Make sure the entire insn is loaded into insn_value, if it
527ed0d50c3Schristos 	     can fit.  */
528ed0d50c3Schristos 	  if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
529ed0d50c3Schristos 	      (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
530ed0d50c3Schristos 	    {
531ed0d50c3Schristos 	      unsigned long full_insn_value;
532ed0d50c3Schristos 	      int rc = read_insn (cd, pc, info, buf,
533ed0d50c3Schristos 				  CGEN_INSN_BITSIZE (insn) / 8,
534ed0d50c3Schristos 				  & ex_info, & full_insn_value);
535ed0d50c3Schristos 	      if (rc != 0)
536ed0d50c3Schristos 		return rc;
537ed0d50c3Schristos 	      length = CGEN_EXTRACT_FN (cd, insn)
538ed0d50c3Schristos 		(cd, insn, &ex_info, full_insn_value, &fields, pc);
539ed0d50c3Schristos 	    }
540ed0d50c3Schristos 	  else
541ed0d50c3Schristos 	    length = CGEN_EXTRACT_FN (cd, insn)
542ed0d50c3Schristos 	      (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
543ed0d50c3Schristos 
544ed0d50c3Schristos 	  /* Length < 0 -> error.  */
545ed0d50c3Schristos 	  if (length < 0)
546ed0d50c3Schristos 	    return length;
547ed0d50c3Schristos 	  if (length > 0)
548ed0d50c3Schristos 	    {
549ed0d50c3Schristos 	      CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
550ed0d50c3Schristos 	      /* Length is in bits, result is in bytes.  */
551ed0d50c3Schristos 	      return length / 8;
552ed0d50c3Schristos 	    }
553ed0d50c3Schristos 	}
554ed0d50c3Schristos 
555ed0d50c3Schristos       insn_list = CGEN_DIS_NEXT_INSN (insn_list);
556ed0d50c3Schristos     }
557ed0d50c3Schristos 
558ed0d50c3Schristos   return 0;
559ed0d50c3Schristos }
560ed0d50c3Schristos 
561ed0d50c3Schristos /* Default value for CGEN_PRINT_INSN.
562ed0d50c3Schristos    The result is the size of the insn in bytes or zero for an unknown insn
563ed0d50c3Schristos    or -1 if an error occured fetching bytes.  */
564ed0d50c3Schristos 
565ed0d50c3Schristos #ifndef CGEN_PRINT_INSN
566ed0d50c3Schristos #define CGEN_PRINT_INSN default_print_insn
567ed0d50c3Schristos #endif
568ed0d50c3Schristos 
569ed0d50c3Schristos static int
default_print_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info)570ed0d50c3Schristos default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
571ed0d50c3Schristos {
572ed0d50c3Schristos   bfd_byte buf[CGEN_MAX_INSN_SIZE];
573ed0d50c3Schristos   int buflen;
574ed0d50c3Schristos   int status;
575ed0d50c3Schristos 
576ed0d50c3Schristos   /* Attempt to read the base part of the insn.  */
577ed0d50c3Schristos   buflen = cd->base_insn_bitsize / 8;
578ed0d50c3Schristos   status = (*info->read_memory_func) (pc, buf, buflen, info);
579ed0d50c3Schristos 
580ed0d50c3Schristos   /* Try again with the minimum part, if min < base.  */
581ed0d50c3Schristos   if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
582ed0d50c3Schristos     {
583ed0d50c3Schristos       buflen = cd->min_insn_bitsize / 8;
584ed0d50c3Schristos       status = (*info->read_memory_func) (pc, buf, buflen, info);
585ed0d50c3Schristos     }
586ed0d50c3Schristos 
587ed0d50c3Schristos   if (status != 0)
588ed0d50c3Schristos     {
589ed0d50c3Schristos       (*info->memory_error_func) (status, pc, info);
590ed0d50c3Schristos       return -1;
591ed0d50c3Schristos     }
592ed0d50c3Schristos 
593ed0d50c3Schristos   return print_insn (cd, pc, info, buf, buflen);
594ed0d50c3Schristos }
595ed0d50c3Schristos 
596ed0d50c3Schristos /* Main entry point.
597ed0d50c3Schristos    Print one instruction from PC on INFO->STREAM.
598ed0d50c3Schristos    Return the size of the instruction (in bytes).  */
599ed0d50c3Schristos 
600ed0d50c3Schristos typedef struct cpu_desc_list
601ed0d50c3Schristos {
602ed0d50c3Schristos   struct cpu_desc_list *next;
603ed0d50c3Schristos   CGEN_BITSET *isa;
604ed0d50c3Schristos   int mach;
605ed0d50c3Schristos   int endian;
606ed0d50c3Schristos   CGEN_CPU_DESC cd;
607ed0d50c3Schristos } cpu_desc_list;
608ed0d50c3Schristos 
609ed0d50c3Schristos int
print_insn_fr30(bfd_vma pc,disassemble_info * info)610ed0d50c3Schristos print_insn_fr30 (bfd_vma pc, disassemble_info *info)
611ed0d50c3Schristos {
612ed0d50c3Schristos   static cpu_desc_list *cd_list = 0;
613ed0d50c3Schristos   cpu_desc_list *cl = 0;
614ed0d50c3Schristos   static CGEN_CPU_DESC cd = 0;
615ed0d50c3Schristos   static CGEN_BITSET *prev_isa;
616ed0d50c3Schristos   static int prev_mach;
617ed0d50c3Schristos   static int prev_endian;
618ed0d50c3Schristos   int length;
619ed0d50c3Schristos   CGEN_BITSET *isa;
620ed0d50c3Schristos   int mach;
621ed0d50c3Schristos   int endian = (info->endian == BFD_ENDIAN_BIG
622ed0d50c3Schristos 		? CGEN_ENDIAN_BIG
623ed0d50c3Schristos 		: CGEN_ENDIAN_LITTLE);
624ed0d50c3Schristos   enum bfd_architecture arch;
625ed0d50c3Schristos 
626ed0d50c3Schristos   /* ??? gdb will set mach but leave the architecture as "unknown" */
627ed0d50c3Schristos #ifndef CGEN_BFD_ARCH
628ed0d50c3Schristos #define CGEN_BFD_ARCH bfd_arch_fr30
629ed0d50c3Schristos #endif
630ed0d50c3Schristos   arch = info->arch;
631ed0d50c3Schristos   if (arch == bfd_arch_unknown)
632ed0d50c3Schristos     arch = CGEN_BFD_ARCH;
633ed0d50c3Schristos 
634ed0d50c3Schristos   /* There's no standard way to compute the machine or isa number
635ed0d50c3Schristos      so we leave it to the target.  */
636ed0d50c3Schristos #ifdef CGEN_COMPUTE_MACH
637ed0d50c3Schristos   mach = CGEN_COMPUTE_MACH (info);
638ed0d50c3Schristos #else
639ed0d50c3Schristos   mach = info->mach;
640ed0d50c3Schristos #endif
641ed0d50c3Schristos 
642ed0d50c3Schristos #ifdef CGEN_COMPUTE_ISA
643ed0d50c3Schristos   {
644ed0d50c3Schristos     static CGEN_BITSET *permanent_isa;
645ed0d50c3Schristos 
646ed0d50c3Schristos     if (!permanent_isa)
647ed0d50c3Schristos       permanent_isa = cgen_bitset_create (MAX_ISAS);
648ed0d50c3Schristos     isa = permanent_isa;
649ed0d50c3Schristos     cgen_bitset_clear (isa);
650ed0d50c3Schristos     cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info));
651ed0d50c3Schristos   }
652ed0d50c3Schristos #else
653*b88e3e88Schristos   isa = info->private_data;
654ed0d50c3Schristos #endif
655ed0d50c3Schristos 
656ed0d50c3Schristos   /* If we've switched cpu's, try to find a handle we've used before */
657ed0d50c3Schristos   if (cd
658ed0d50c3Schristos       && (cgen_bitset_compare (isa, prev_isa) != 0
659ed0d50c3Schristos 	  || mach != prev_mach
660ed0d50c3Schristos 	  || endian != prev_endian))
661ed0d50c3Schristos     {
662ed0d50c3Schristos       cd = 0;
663ed0d50c3Schristos       for (cl = cd_list; cl; cl = cl->next)
664ed0d50c3Schristos 	{
665ed0d50c3Schristos 	  if (cgen_bitset_compare (cl->isa, isa) == 0 &&
666ed0d50c3Schristos 	      cl->mach == mach &&
667ed0d50c3Schristos 	      cl->endian == endian)
668ed0d50c3Schristos 	    {
669ed0d50c3Schristos 	      cd = cl->cd;
670ed0d50c3Schristos  	      prev_isa = cd->isas;
671ed0d50c3Schristos 	      break;
672ed0d50c3Schristos 	    }
673ed0d50c3Schristos 	}
674ed0d50c3Schristos     }
675ed0d50c3Schristos 
676ed0d50c3Schristos   /* If we haven't initialized yet, initialize the opcode table.  */
677ed0d50c3Schristos   if (! cd)
678ed0d50c3Schristos     {
679ed0d50c3Schristos       const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
680ed0d50c3Schristos       const char *mach_name;
681ed0d50c3Schristos 
682ed0d50c3Schristos       if (!arch_type)
683ed0d50c3Schristos 	abort ();
684ed0d50c3Schristos       mach_name = arch_type->printable_name;
685ed0d50c3Schristos 
686ed0d50c3Schristos       prev_isa = cgen_bitset_copy (isa);
687ed0d50c3Schristos       prev_mach = mach;
688ed0d50c3Schristos       prev_endian = endian;
689ed0d50c3Schristos       cd = fr30_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
690ed0d50c3Schristos 				 CGEN_CPU_OPEN_BFDMACH, mach_name,
691ed0d50c3Schristos 				 CGEN_CPU_OPEN_ENDIAN, prev_endian,
692ed0d50c3Schristos 				 CGEN_CPU_OPEN_END);
693ed0d50c3Schristos       if (!cd)
694ed0d50c3Schristos 	abort ();
695ed0d50c3Schristos 
696ed0d50c3Schristos       /* Save this away for future reference.  */
697ed0d50c3Schristos       cl = xmalloc (sizeof (struct cpu_desc_list));
698ed0d50c3Schristos       cl->cd = cd;
699ed0d50c3Schristos       cl->isa = prev_isa;
700ed0d50c3Schristos       cl->mach = mach;
701ed0d50c3Schristos       cl->endian = endian;
702ed0d50c3Schristos       cl->next = cd_list;
703ed0d50c3Schristos       cd_list = cl;
704ed0d50c3Schristos 
705ed0d50c3Schristos       fr30_cgen_init_dis (cd);
706ed0d50c3Schristos     }
707ed0d50c3Schristos 
708ed0d50c3Schristos   /* We try to have as much common code as possible.
709ed0d50c3Schristos      But at this point some targets need to take over.  */
710ed0d50c3Schristos   /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
711ed0d50c3Schristos      but if not possible try to move this hook elsewhere rather than
712ed0d50c3Schristos      have two hooks.  */
713ed0d50c3Schristos   length = CGEN_PRINT_INSN (cd, pc, info);
714ed0d50c3Schristos   if (length > 0)
715ed0d50c3Schristos     return length;
716ed0d50c3Schristos   if (length < 0)
717ed0d50c3Schristos     return -1;
718ed0d50c3Schristos 
719ed0d50c3Schristos   (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
720ed0d50c3Schristos   return cd->default_insn_bitsize / 8;
721ed0d50c3Schristos }
722