198f124a6Schristos /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */
22a6b7db3Sskrll /* Disassembler interface for targets using CGEN. -*- C -*-
32a6b7db3Sskrll CGEN: Cpu tools GENerator
42a6b7db3Sskrll
52a6b7db3Sskrll THIS FILE IS MACHINE GENERATED WITH CGEN.
62a6b7db3Sskrll - the resultant file is machine generated, cgen-dis.in isn't
72a6b7db3Sskrll
8*f22f0ef4Schristos Copyright (C) 1996-2022 Free Software Foundation, Inc.
92a6b7db3Sskrll
102a6b7db3Sskrll This file is part of libopcodes.
112a6b7db3Sskrll
122a6b7db3Sskrll This library is free software; you can redistribute it and/or modify
132a6b7db3Sskrll it under the terms of the GNU General Public License as published by
142a6b7db3Sskrll the Free Software Foundation; either version 3, or (at your option)
152a6b7db3Sskrll any later version.
162a6b7db3Sskrll
172a6b7db3Sskrll It is distributed in the hope that it will be useful, but WITHOUT
182a6b7db3Sskrll ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
192a6b7db3Sskrll or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
202a6b7db3Sskrll License for more details.
212a6b7db3Sskrll
222a6b7db3Sskrll You should have received a copy of the GNU General Public License
232a6b7db3Sskrll along with this program; if not, write to the Free Software Foundation, Inc.,
242a6b7db3Sskrll 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252a6b7db3Sskrll
262a6b7db3Sskrll /* ??? Eventually more and more of this stuff can go to cpu-independent files.
272a6b7db3Sskrll Keep that in mind. */
282a6b7db3Sskrll
292a6b7db3Sskrll #include "sysdep.h"
302a6b7db3Sskrll #include <stdio.h>
312a6b7db3Sskrll #include "ansidecl.h"
3298f124a6Schristos #include "disassemble.h"
332a6b7db3Sskrll #include "bfd.h"
342a6b7db3Sskrll #include "symcat.h"
352a6b7db3Sskrll #include "libiberty.h"
362a6b7db3Sskrll #include "fr30-desc.h"
372a6b7db3Sskrll #include "fr30-opc.h"
382a6b7db3Sskrll #include "opintl.h"
392a6b7db3Sskrll
402a6b7db3Sskrll /* Default text to print if an instruction isn't recognized. */
412a6b7db3Sskrll #define UNKNOWN_INSN_MSG _("*unknown*")
422a6b7db3Sskrll
432a6b7db3Sskrll static void print_normal
442a6b7db3Sskrll (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
452a6b7db3Sskrll static void print_address
462a6b7db3Sskrll (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
472a6b7db3Sskrll static void print_keyword
482a6b7db3Sskrll (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
492a6b7db3Sskrll static void print_insn_normal
502a6b7db3Sskrll (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
512a6b7db3Sskrll static int print_insn
522a6b7db3Sskrll (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned);
532a6b7db3Sskrll static int default_print_insn
542a6b7db3Sskrll (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
552a6b7db3Sskrll static int read_insn
562a6b7db3Sskrll (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
572a6b7db3Sskrll unsigned long *);
582a6b7db3Sskrll
592a6b7db3Sskrll /* -- disassembler routines inserted here. */
602a6b7db3Sskrll
612a6b7db3Sskrll /* -- dis.c */
622a6b7db3Sskrll static void
print_register_list(void * dis_info,long value,long offset,int load_store)632a6b7db3Sskrll print_register_list (void * dis_info,
642a6b7db3Sskrll long value,
652a6b7db3Sskrll long offset,
662a6b7db3Sskrll int load_store) /* 0 == load, 1 == store. */
672a6b7db3Sskrll {
682a6b7db3Sskrll disassemble_info *info = dis_info;
692a6b7db3Sskrll int mask;
70b3ac4aedSchristos int reg_index = 0;
712a6b7db3Sskrll char * comma = "";
722a6b7db3Sskrll
732a6b7db3Sskrll if (load_store)
742a6b7db3Sskrll mask = 0x80;
752a6b7db3Sskrll else
762a6b7db3Sskrll mask = 1;
772a6b7db3Sskrll
782a6b7db3Sskrll if (value & mask)
792a6b7db3Sskrll {
80b3ac4aedSchristos (*info->fprintf_func) (info->stream, "r%li", reg_index + offset);
812a6b7db3Sskrll comma = ",";
822a6b7db3Sskrll }
832a6b7db3Sskrll
84b3ac4aedSchristos for (reg_index = 1; reg_index <= 7; ++reg_index)
852a6b7db3Sskrll {
862a6b7db3Sskrll if (load_store)
872a6b7db3Sskrll mask >>= 1;
882a6b7db3Sskrll else
892a6b7db3Sskrll mask <<= 1;
902a6b7db3Sskrll
912a6b7db3Sskrll if (value & mask)
922a6b7db3Sskrll {
93b3ac4aedSchristos (*info->fprintf_func) (info->stream, "%sr%li", comma, reg_index + offset);
942a6b7db3Sskrll comma = ",";
952a6b7db3Sskrll }
962a6b7db3Sskrll }
972a6b7db3Sskrll }
982a6b7db3Sskrll
992a6b7db3Sskrll 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)1002a6b7db3Sskrll print_hi_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1012a6b7db3Sskrll void * dis_info,
1022a6b7db3Sskrll long value,
1032a6b7db3Sskrll unsigned int attrs ATTRIBUTE_UNUSED,
1042a6b7db3Sskrll bfd_vma pc ATTRIBUTE_UNUSED,
1052a6b7db3Sskrll int length ATTRIBUTE_UNUSED)
1062a6b7db3Sskrll {
1072a6b7db3Sskrll print_register_list (dis_info, value, 8, 0 /* Load. */);
1082a6b7db3Sskrll }
1092a6b7db3Sskrll
1102a6b7db3Sskrll 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)1112a6b7db3Sskrll print_low_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1122a6b7db3Sskrll void * dis_info,
1132a6b7db3Sskrll long value,
1142a6b7db3Sskrll unsigned int attrs ATTRIBUTE_UNUSED,
1152a6b7db3Sskrll bfd_vma pc ATTRIBUTE_UNUSED,
1162a6b7db3Sskrll int length ATTRIBUTE_UNUSED)
1172a6b7db3Sskrll {
1182a6b7db3Sskrll print_register_list (dis_info, value, 0, 0 /* Load. */);
1192a6b7db3Sskrll }
1202a6b7db3Sskrll
1212a6b7db3Sskrll 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)1222a6b7db3Sskrll print_hi_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1232a6b7db3Sskrll void * dis_info,
1242a6b7db3Sskrll long value,
1252a6b7db3Sskrll unsigned int attrs ATTRIBUTE_UNUSED,
1262a6b7db3Sskrll bfd_vma pc ATTRIBUTE_UNUSED,
1272a6b7db3Sskrll int length ATTRIBUTE_UNUSED)
1282a6b7db3Sskrll {
1292a6b7db3Sskrll print_register_list (dis_info, value, 8, 1 /* Store. */);
1302a6b7db3Sskrll }
1312a6b7db3Sskrll
1322a6b7db3Sskrll 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)1332a6b7db3Sskrll print_low_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1342a6b7db3Sskrll void * dis_info,
1352a6b7db3Sskrll long value,
1362a6b7db3Sskrll unsigned int attrs ATTRIBUTE_UNUSED,
1372a6b7db3Sskrll bfd_vma pc ATTRIBUTE_UNUSED,
1382a6b7db3Sskrll int length ATTRIBUTE_UNUSED)
1392a6b7db3Sskrll {
1402a6b7db3Sskrll print_register_list (dis_info, value, 0, 1 /* Store. */);
1412a6b7db3Sskrll }
1422a6b7db3Sskrll
1432a6b7db3Sskrll 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)1442a6b7db3Sskrll print_m4 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1452a6b7db3Sskrll void * dis_info,
1462a6b7db3Sskrll long value,
1472a6b7db3Sskrll unsigned int attrs ATTRIBUTE_UNUSED,
1482a6b7db3Sskrll bfd_vma pc ATTRIBUTE_UNUSED,
1492a6b7db3Sskrll int length ATTRIBUTE_UNUSED)
1502a6b7db3Sskrll {
1512a6b7db3Sskrll disassemble_info *info = (disassemble_info *) dis_info;
1522a6b7db3Sskrll
1532a6b7db3Sskrll (*info->fprintf_func) (info->stream, "%ld", value);
1542a6b7db3Sskrll }
1552a6b7db3Sskrll /* -- */
1562a6b7db3Sskrll
1572a6b7db3Sskrll void fr30_cgen_print_operand
158*f22f0ef4Schristos (CGEN_CPU_DESC, int, void *, CGEN_FIELDS *, void const *, bfd_vma, int);
1592a6b7db3Sskrll
1602a6b7db3Sskrll /* Main entry point for printing operands.
1612a6b7db3Sskrll XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
1622a6b7db3Sskrll of dis-asm.h on cgen.h.
1632a6b7db3Sskrll
1642a6b7db3Sskrll This function is basically just a big switch statement. Earlier versions
1652a6b7db3Sskrll used tables to look up the function to use, but
1662a6b7db3Sskrll - if the table contains both assembler and disassembler functions then
1672a6b7db3Sskrll the disassembler contains much of the assembler and vice-versa,
1682a6b7db3Sskrll - there's a lot of inlining possibilities as things grow,
1692a6b7db3Sskrll - using a switch statement avoids the function call overhead.
1702a6b7db3Sskrll
1712a6b7db3Sskrll This function could be moved into `print_insn_normal', but keeping it
1722a6b7db3Sskrll separate makes clear the interface between `print_insn_normal' and each of
1732a6b7db3Sskrll the handlers. */
1742a6b7db3Sskrll
1752a6b7db3Sskrll 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)1762a6b7db3Sskrll fr30_cgen_print_operand (CGEN_CPU_DESC cd,
1772a6b7db3Sskrll int opindex,
1782a6b7db3Sskrll void * xinfo,
1792a6b7db3Sskrll CGEN_FIELDS *fields,
1802a6b7db3Sskrll void const *attrs ATTRIBUTE_UNUSED,
1812a6b7db3Sskrll bfd_vma pc,
1822a6b7db3Sskrll int length)
1832a6b7db3Sskrll {
1842a6b7db3Sskrll disassemble_info *info = (disassemble_info *) xinfo;
1852a6b7db3Sskrll
1862a6b7db3Sskrll switch (opindex)
1872a6b7db3Sskrll {
1882a6b7db3Sskrll case FR30_OPERAND_CRI :
1892a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRi, 0);
1902a6b7db3Sskrll break;
1912a6b7db3Sskrll case FR30_OPERAND_CRJ :
1922a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRj, 0);
1932a6b7db3Sskrll break;
1942a6b7db3Sskrll case FR30_OPERAND_R13 :
1952a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_h_r13, 0, 0);
1962a6b7db3Sskrll break;
1972a6b7db3Sskrll case FR30_OPERAND_R14 :
1982a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_h_r14, 0, 0);
1992a6b7db3Sskrll break;
2002a6b7db3Sskrll case FR30_OPERAND_R15 :
2012a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_h_r15, 0, 0);
2022a6b7db3Sskrll break;
2032a6b7db3Sskrll case FR30_OPERAND_RI :
2042a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ri, 0);
2052a6b7db3Sskrll break;
2062a6b7db3Sskrll case FR30_OPERAND_RIC :
2072a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ric, 0);
2082a6b7db3Sskrll break;
2092a6b7db3Sskrll case FR30_OPERAND_RJ :
2102a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rj, 0);
2112a6b7db3Sskrll break;
2122a6b7db3Sskrll case FR30_OPERAND_RJC :
2132a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rjc, 0);
2142a6b7db3Sskrll break;
2152a6b7db3Sskrll case FR30_OPERAND_RS1 :
2162a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs1, 0);
2172a6b7db3Sskrll break;
2182a6b7db3Sskrll case FR30_OPERAND_RS2 :
2192a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs2, 0);
2202a6b7db3Sskrll break;
2212a6b7db3Sskrll case FR30_OPERAND_CC :
2222a6b7db3Sskrll print_normal (cd, info, fields->f_cc, 0, pc, length);
2232a6b7db3Sskrll break;
2242a6b7db3Sskrll case FR30_OPERAND_CCC :
2252a6b7db3Sskrll print_normal (cd, info, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2262a6b7db3Sskrll break;
2272a6b7db3Sskrll case FR30_OPERAND_DIR10 :
2282a6b7db3Sskrll print_normal (cd, info, fields->f_dir10, 0, pc, length);
2292a6b7db3Sskrll break;
2302a6b7db3Sskrll case FR30_OPERAND_DIR8 :
2312a6b7db3Sskrll print_normal (cd, info, fields->f_dir8, 0, pc, length);
2322a6b7db3Sskrll break;
2332a6b7db3Sskrll case FR30_OPERAND_DIR9 :
2342a6b7db3Sskrll print_normal (cd, info, fields->f_dir9, 0, pc, length);
2352a6b7db3Sskrll break;
2362a6b7db3Sskrll case FR30_OPERAND_DISP10 :
2372a6b7db3Sskrll print_normal (cd, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2382a6b7db3Sskrll break;
2392a6b7db3Sskrll case FR30_OPERAND_DISP8 :
2402a6b7db3Sskrll print_normal (cd, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2412a6b7db3Sskrll break;
2422a6b7db3Sskrll case FR30_OPERAND_DISP9 :
2432a6b7db3Sskrll print_normal (cd, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2442a6b7db3Sskrll break;
2452a6b7db3Sskrll case FR30_OPERAND_I20 :
2462a6b7db3Sskrll print_normal (cd, info, fields->f_i20, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
2472a6b7db3Sskrll break;
2482a6b7db3Sskrll case FR30_OPERAND_I32 :
2492a6b7db3Sskrll print_normal (cd, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT), pc, length);
2502a6b7db3Sskrll break;
2512a6b7db3Sskrll case FR30_OPERAND_I8 :
2522a6b7db3Sskrll print_normal (cd, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2532a6b7db3Sskrll break;
2542a6b7db3Sskrll case FR30_OPERAND_LABEL12 :
2552a6b7db3Sskrll print_address (cd, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
2562a6b7db3Sskrll break;
2572a6b7db3Sskrll case FR30_OPERAND_LABEL9 :
2582a6b7db3Sskrll print_address (cd, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
2592a6b7db3Sskrll break;
2602a6b7db3Sskrll case FR30_OPERAND_M4 :
2612a6b7db3Sskrll print_m4 (cd, info, fields->f_m4, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2622a6b7db3Sskrll break;
2632a6b7db3Sskrll case FR30_OPERAND_PS :
2642a6b7db3Sskrll print_keyword (cd, info, & fr30_cgen_opval_h_ps, 0, 0);
2652a6b7db3Sskrll break;
2662a6b7db3Sskrll case FR30_OPERAND_REGLIST_HI_LD :
2672a6b7db3Sskrll print_hi_register_list_ld (cd, info, fields->f_reglist_hi_ld, 0, pc, length);
2682a6b7db3Sskrll break;
2692a6b7db3Sskrll case FR30_OPERAND_REGLIST_HI_ST :
2702a6b7db3Sskrll print_hi_register_list_st (cd, info, fields->f_reglist_hi_st, 0, pc, length);
2712a6b7db3Sskrll break;
2722a6b7db3Sskrll case FR30_OPERAND_REGLIST_LOW_LD :
2732a6b7db3Sskrll print_low_register_list_ld (cd, info, fields->f_reglist_low_ld, 0, pc, length);
2742a6b7db3Sskrll break;
2752a6b7db3Sskrll case FR30_OPERAND_REGLIST_LOW_ST :
2762a6b7db3Sskrll print_low_register_list_st (cd, info, fields->f_reglist_low_st, 0, pc, length);
2772a6b7db3Sskrll break;
2782a6b7db3Sskrll case FR30_OPERAND_S10 :
2792a6b7db3Sskrll print_normal (cd, info, fields->f_s10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2802a6b7db3Sskrll break;
2812a6b7db3Sskrll case FR30_OPERAND_U10 :
2822a6b7db3Sskrll print_normal (cd, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2832a6b7db3Sskrll break;
2842a6b7db3Sskrll case FR30_OPERAND_U4 :
2852a6b7db3Sskrll print_normal (cd, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2862a6b7db3Sskrll break;
2872a6b7db3Sskrll case FR30_OPERAND_U4C :
2882a6b7db3Sskrll print_normal (cd, info, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2892a6b7db3Sskrll break;
2902a6b7db3Sskrll case FR30_OPERAND_U8 :
2912a6b7db3Sskrll print_normal (cd, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2922a6b7db3Sskrll break;
2932a6b7db3Sskrll case FR30_OPERAND_UDISP6 :
2942a6b7db3Sskrll print_normal (cd, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
2952a6b7db3Sskrll break;
2962a6b7db3Sskrll
2972a6b7db3Sskrll default :
2982a6b7db3Sskrll /* xgettext:c-format */
299fa2c2dd3Schristos opcodes_error_handler
300fa2c2dd3Schristos (_("internal error: unrecognized field %d while printing insn"),
3012a6b7db3Sskrll opindex);
3022a6b7db3Sskrll abort ();
3032a6b7db3Sskrll }
3042a6b7db3Sskrll }
3052a6b7db3Sskrll
3062a6b7db3Sskrll cgen_print_fn * const fr30_cgen_print_handlers[] =
3072a6b7db3Sskrll {
3082a6b7db3Sskrll print_insn_normal,
3092a6b7db3Sskrll };
3102a6b7db3Sskrll
3112a6b7db3Sskrll
3122a6b7db3Sskrll void
fr30_cgen_init_dis(CGEN_CPU_DESC cd)3132a6b7db3Sskrll fr30_cgen_init_dis (CGEN_CPU_DESC cd)
3142a6b7db3Sskrll {
3152a6b7db3Sskrll fr30_cgen_init_opcode_table (cd);
3162a6b7db3Sskrll fr30_cgen_init_ibld_table (cd);
3172a6b7db3Sskrll cd->print_handlers = & fr30_cgen_print_handlers[0];
3182a6b7db3Sskrll cd->print_operand = fr30_cgen_print_operand;
3192a6b7db3Sskrll }
3202a6b7db3Sskrll
3212a6b7db3Sskrll
3222a6b7db3Sskrll /* Default print handler. */
3232a6b7db3Sskrll
3242a6b7db3Sskrll 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)3252a6b7db3Sskrll print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
3262a6b7db3Sskrll void *dis_info,
3272a6b7db3Sskrll long value,
3282a6b7db3Sskrll unsigned int attrs,
3292a6b7db3Sskrll bfd_vma pc ATTRIBUTE_UNUSED,
3302a6b7db3Sskrll int length ATTRIBUTE_UNUSED)
3312a6b7db3Sskrll {
3322a6b7db3Sskrll disassemble_info *info = (disassemble_info *) dis_info;
3332a6b7db3Sskrll
3342a6b7db3Sskrll /* Print the operand as directed by the attributes. */
3352a6b7db3Sskrll if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
3362a6b7db3Sskrll ; /* nothing to do */
3372a6b7db3Sskrll else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
3382a6b7db3Sskrll (*info->fprintf_func) (info->stream, "%ld", value);
3392a6b7db3Sskrll else
3402a6b7db3Sskrll (*info->fprintf_func) (info->stream, "0x%lx", value);
3412a6b7db3Sskrll }
3422a6b7db3Sskrll
3432a6b7db3Sskrll /* Default address handler. */
3442a6b7db3Sskrll
3452a6b7db3Sskrll 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)3462a6b7db3Sskrll print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
3472a6b7db3Sskrll void *dis_info,
3482a6b7db3Sskrll bfd_vma value,
3492a6b7db3Sskrll unsigned int attrs,
3502a6b7db3Sskrll bfd_vma pc ATTRIBUTE_UNUSED,
3512a6b7db3Sskrll int length ATTRIBUTE_UNUSED)
3522a6b7db3Sskrll {
3532a6b7db3Sskrll disassemble_info *info = (disassemble_info *) dis_info;
3542a6b7db3Sskrll
3552a6b7db3Sskrll /* Print the operand as directed by the attributes. */
3562a6b7db3Sskrll if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
3572a6b7db3Sskrll ; /* Nothing to do. */
3582a6b7db3Sskrll else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
3592a6b7db3Sskrll (*info->print_address_func) (value, info);
3602a6b7db3Sskrll else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
3612a6b7db3Sskrll (*info->print_address_func) (value, info);
3622a6b7db3Sskrll else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
3632a6b7db3Sskrll (*info->fprintf_func) (info->stream, "%ld", (long) value);
3642a6b7db3Sskrll else
3652a6b7db3Sskrll (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
3662a6b7db3Sskrll }
3672a6b7db3Sskrll
3682a6b7db3Sskrll /* Keyword print handler. */
3692a6b7db3Sskrll
3702a6b7db3Sskrll static void
print_keyword(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,CGEN_KEYWORD * keyword_table,long value,unsigned int attrs ATTRIBUTE_UNUSED)3712a6b7db3Sskrll print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
3722a6b7db3Sskrll void *dis_info,
3732a6b7db3Sskrll CGEN_KEYWORD *keyword_table,
3742a6b7db3Sskrll long value,
3752a6b7db3Sskrll unsigned int attrs ATTRIBUTE_UNUSED)
3762a6b7db3Sskrll {
3772a6b7db3Sskrll disassemble_info *info = (disassemble_info *) dis_info;
3782a6b7db3Sskrll const CGEN_KEYWORD_ENTRY *ke;
3792a6b7db3Sskrll
3802a6b7db3Sskrll ke = cgen_keyword_lookup_value (keyword_table, value);
3812a6b7db3Sskrll if (ke != NULL)
3822a6b7db3Sskrll (*info->fprintf_func) (info->stream, "%s", ke->name);
3832a6b7db3Sskrll else
3842a6b7db3Sskrll (*info->fprintf_func) (info->stream, "???");
3852a6b7db3Sskrll }
3862a6b7db3Sskrll
3872a6b7db3Sskrll /* Default insn printer.
3882a6b7db3Sskrll
3892a6b7db3Sskrll DIS_INFO is defined as `void *' so the disassembler needn't know anything
3902a6b7db3Sskrll about disassemble_info. */
3912a6b7db3Sskrll
3922a6b7db3Sskrll static void
print_insn_normal(CGEN_CPU_DESC cd,void * dis_info,const CGEN_INSN * insn,CGEN_FIELDS * fields,bfd_vma pc,int length)3932a6b7db3Sskrll print_insn_normal (CGEN_CPU_DESC cd,
3942a6b7db3Sskrll void *dis_info,
3952a6b7db3Sskrll const CGEN_INSN *insn,
3962a6b7db3Sskrll CGEN_FIELDS *fields,
3972a6b7db3Sskrll bfd_vma pc,
3982a6b7db3Sskrll int length)
3992a6b7db3Sskrll {
4002a6b7db3Sskrll const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
4012a6b7db3Sskrll disassemble_info *info = (disassemble_info *) dis_info;
4022a6b7db3Sskrll const CGEN_SYNTAX_CHAR_TYPE *syn;
4032a6b7db3Sskrll
4042a6b7db3Sskrll CGEN_INIT_PRINT (cd);
4052a6b7db3Sskrll
4062a6b7db3Sskrll for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
4072a6b7db3Sskrll {
4082a6b7db3Sskrll if (CGEN_SYNTAX_MNEMONIC_P (*syn))
4092a6b7db3Sskrll {
4102a6b7db3Sskrll (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
4112a6b7db3Sskrll continue;
4122a6b7db3Sskrll }
4132a6b7db3Sskrll if (CGEN_SYNTAX_CHAR_P (*syn))
4142a6b7db3Sskrll {
4152a6b7db3Sskrll (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
4162a6b7db3Sskrll continue;
4172a6b7db3Sskrll }
4182a6b7db3Sskrll
4192a6b7db3Sskrll /* We have an operand. */
4202a6b7db3Sskrll fr30_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
4212a6b7db3Sskrll fields, CGEN_INSN_ATTRS (insn), pc, length);
4222a6b7db3Sskrll }
4232a6b7db3Sskrll }
4242a6b7db3Sskrll
4252a6b7db3Sskrll /* Subroutine of print_insn. Reads an insn into the given buffers and updates
4262a6b7db3Sskrll the extract info.
4272a6b7db3Sskrll Returns 0 if all is well, non-zero otherwise. */
4282a6b7db3Sskrll
4292a6b7db3Sskrll 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)4302a6b7db3Sskrll read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
4312a6b7db3Sskrll bfd_vma pc,
4322a6b7db3Sskrll disassemble_info *info,
4332a6b7db3Sskrll bfd_byte *buf,
4342a6b7db3Sskrll int buflen,
4352a6b7db3Sskrll CGEN_EXTRACT_INFO *ex_info,
4362a6b7db3Sskrll unsigned long *insn_value)
4372a6b7db3Sskrll {
4382a6b7db3Sskrll int status = (*info->read_memory_func) (pc, buf, buflen, info);
4392a6b7db3Sskrll
4402a6b7db3Sskrll if (status != 0)
4412a6b7db3Sskrll {
4422a6b7db3Sskrll (*info->memory_error_func) (status, pc, info);
4432a6b7db3Sskrll return -1;
4442a6b7db3Sskrll }
4452a6b7db3Sskrll
4462a6b7db3Sskrll ex_info->dis_info = info;
4472a6b7db3Sskrll ex_info->valid = (1 << buflen) - 1;
4482a6b7db3Sskrll ex_info->insn_bytes = buf;
4492a6b7db3Sskrll
4502a6b7db3Sskrll *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
4512a6b7db3Sskrll return 0;
4522a6b7db3Sskrll }
4532a6b7db3Sskrll
4542a6b7db3Sskrll /* Utility to print an insn.
4552a6b7db3Sskrll BUF is the base part of the insn, target byte order, BUFLEN bytes long.
4562a6b7db3Sskrll The result is the size of the insn in bytes or zero for an unknown insn
4572a6b7db3Sskrll or -1 if an error occurs fetching data (memory_error_func will have
4582a6b7db3Sskrll been called). */
4592a6b7db3Sskrll
4602a6b7db3Sskrll static int
print_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info,bfd_byte * buf,unsigned int buflen)4612a6b7db3Sskrll print_insn (CGEN_CPU_DESC cd,
4622a6b7db3Sskrll bfd_vma pc,
4632a6b7db3Sskrll disassemble_info *info,
4642a6b7db3Sskrll bfd_byte *buf,
4652a6b7db3Sskrll unsigned int buflen)
4662a6b7db3Sskrll {
4672a6b7db3Sskrll CGEN_INSN_INT insn_value;
4682a6b7db3Sskrll const CGEN_INSN_LIST *insn_list;
4692a6b7db3Sskrll CGEN_EXTRACT_INFO ex_info;
4702a6b7db3Sskrll int basesize;
4712a6b7db3Sskrll
4722a6b7db3Sskrll /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
4732a6b7db3Sskrll basesize = cd->base_insn_bitsize < buflen * 8 ?
4742a6b7db3Sskrll cd->base_insn_bitsize : buflen * 8;
475*f22f0ef4Schristos insn_value = cgen_get_insn_value (cd, buf, basesize, cd->insn_endian);
4762a6b7db3Sskrll
4772a6b7db3Sskrll
4782a6b7db3Sskrll /* Fill in ex_info fields like read_insn would. Don't actually call
4792a6b7db3Sskrll read_insn, since the incoming buffer is already read (and possibly
4802a6b7db3Sskrll modified a la m32r). */
4812a6b7db3Sskrll ex_info.valid = (1 << buflen) - 1;
4822a6b7db3Sskrll ex_info.dis_info = info;
4832a6b7db3Sskrll ex_info.insn_bytes = buf;
4842a6b7db3Sskrll
4852a6b7db3Sskrll /* The instructions are stored in hash lists.
4862a6b7db3Sskrll Pick the first one and keep trying until we find the right one. */
4872a6b7db3Sskrll
4882a6b7db3Sskrll insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
4892a6b7db3Sskrll while (insn_list != NULL)
4902a6b7db3Sskrll {
4912a6b7db3Sskrll const CGEN_INSN *insn = insn_list->insn;
4922a6b7db3Sskrll CGEN_FIELDS fields;
4932a6b7db3Sskrll int length;
4942a6b7db3Sskrll unsigned long insn_value_cropped;
4952a6b7db3Sskrll
4962a6b7db3Sskrll #ifdef CGEN_VALIDATE_INSN_SUPPORTED
4972a6b7db3Sskrll /* Not needed as insn shouldn't be in hash lists if not supported. */
4982a6b7db3Sskrll /* Supported by this cpu? */
4992a6b7db3Sskrll if (! fr30_cgen_insn_supported (cd, insn))
5002a6b7db3Sskrll {
5012a6b7db3Sskrll insn_list = CGEN_DIS_NEXT_INSN (insn_list);
5022a6b7db3Sskrll continue;
5032a6b7db3Sskrll }
5042a6b7db3Sskrll #endif
5052a6b7db3Sskrll
5062a6b7db3Sskrll /* Basic bit mask must be correct. */
5072a6b7db3Sskrll /* ??? May wish to allow target to defer this check until the extract
5082a6b7db3Sskrll handler. */
5092a6b7db3Sskrll
5102a6b7db3Sskrll /* Base size may exceed this instruction's size. Extract the
5112a6b7db3Sskrll relevant part from the buffer. */
5122a6b7db3Sskrll if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
5132a6b7db3Sskrll (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
5142a6b7db3Sskrll insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
5152a6b7db3Sskrll info->endian == BFD_ENDIAN_BIG);
5162a6b7db3Sskrll else
5172a6b7db3Sskrll insn_value_cropped = insn_value;
5182a6b7db3Sskrll
5192a6b7db3Sskrll if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
5202a6b7db3Sskrll == CGEN_INSN_BASE_VALUE (insn))
5212a6b7db3Sskrll {
5222a6b7db3Sskrll /* Printing is handled in two passes. The first pass parses the
5232a6b7db3Sskrll machine insn and extracts the fields. The second pass prints
5242a6b7db3Sskrll them. */
5252a6b7db3Sskrll
5262a6b7db3Sskrll /* Make sure the entire insn is loaded into insn_value, if it
5272a6b7db3Sskrll can fit. */
5282a6b7db3Sskrll if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
5292a6b7db3Sskrll (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
5302a6b7db3Sskrll {
5312a6b7db3Sskrll unsigned long full_insn_value;
5322a6b7db3Sskrll int rc = read_insn (cd, pc, info, buf,
5332a6b7db3Sskrll CGEN_INSN_BITSIZE (insn) / 8,
5342a6b7db3Sskrll & ex_info, & full_insn_value);
5352a6b7db3Sskrll if (rc != 0)
5362a6b7db3Sskrll return rc;
5372a6b7db3Sskrll length = CGEN_EXTRACT_FN (cd, insn)
5382a6b7db3Sskrll (cd, insn, &ex_info, full_insn_value, &fields, pc);
5392a6b7db3Sskrll }
5402a6b7db3Sskrll else
5412a6b7db3Sskrll length = CGEN_EXTRACT_FN (cd, insn)
5422a6b7db3Sskrll (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
5432a6b7db3Sskrll
5442a6b7db3Sskrll /* Length < 0 -> error. */
5452a6b7db3Sskrll if (length < 0)
5462a6b7db3Sskrll return length;
5472a6b7db3Sskrll if (length > 0)
5482a6b7db3Sskrll {
5492a6b7db3Sskrll CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
5502a6b7db3Sskrll /* Length is in bits, result is in bytes. */
5512a6b7db3Sskrll return length / 8;
5522a6b7db3Sskrll }
5532a6b7db3Sskrll }
5542a6b7db3Sskrll
5552a6b7db3Sskrll insn_list = CGEN_DIS_NEXT_INSN (insn_list);
5562a6b7db3Sskrll }
5572a6b7db3Sskrll
5582a6b7db3Sskrll return 0;
5592a6b7db3Sskrll }
5602a6b7db3Sskrll
5612a6b7db3Sskrll /* Default value for CGEN_PRINT_INSN.
5622a6b7db3Sskrll The result is the size of the insn in bytes or zero for an unknown insn
5632a6b7db3Sskrll or -1 if an error occured fetching bytes. */
5642a6b7db3Sskrll
5652a6b7db3Sskrll #ifndef CGEN_PRINT_INSN
5662a6b7db3Sskrll #define CGEN_PRINT_INSN default_print_insn
5672a6b7db3Sskrll #endif
5682a6b7db3Sskrll
5692a6b7db3Sskrll static int
default_print_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info)5702a6b7db3Sskrll default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
5712a6b7db3Sskrll {
5722a6b7db3Sskrll bfd_byte buf[CGEN_MAX_INSN_SIZE];
5732a6b7db3Sskrll int buflen;
5742a6b7db3Sskrll int status;
5752a6b7db3Sskrll
5762a6b7db3Sskrll /* Attempt to read the base part of the insn. */
5772a6b7db3Sskrll buflen = cd->base_insn_bitsize / 8;
5782a6b7db3Sskrll status = (*info->read_memory_func) (pc, buf, buflen, info);
5792a6b7db3Sskrll
5802a6b7db3Sskrll /* Try again with the minimum part, if min < base. */
5812a6b7db3Sskrll if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
5822a6b7db3Sskrll {
5832a6b7db3Sskrll buflen = cd->min_insn_bitsize / 8;
5842a6b7db3Sskrll status = (*info->read_memory_func) (pc, buf, buflen, info);
5852a6b7db3Sskrll }
5862a6b7db3Sskrll
5872a6b7db3Sskrll if (status != 0)
5882a6b7db3Sskrll {
5892a6b7db3Sskrll (*info->memory_error_func) (status, pc, info);
5902a6b7db3Sskrll return -1;
5912a6b7db3Sskrll }
5922a6b7db3Sskrll
5932a6b7db3Sskrll return print_insn (cd, pc, info, buf, buflen);
5942a6b7db3Sskrll }
5952a6b7db3Sskrll
5962a6b7db3Sskrll /* Main entry point.
5972a6b7db3Sskrll Print one instruction from PC on INFO->STREAM.
5982a6b7db3Sskrll Return the size of the instruction (in bytes). */
5992a6b7db3Sskrll
6002a6b7db3Sskrll typedef struct cpu_desc_list
6012a6b7db3Sskrll {
6022a6b7db3Sskrll struct cpu_desc_list *next;
6032a6b7db3Sskrll CGEN_BITSET *isa;
6042a6b7db3Sskrll int mach;
6052a6b7db3Sskrll int endian;
606*f22f0ef4Schristos int insn_endian;
6072a6b7db3Sskrll CGEN_CPU_DESC cd;
6082a6b7db3Sskrll } cpu_desc_list;
6092a6b7db3Sskrll
6102a6b7db3Sskrll int
print_insn_fr30(bfd_vma pc,disassemble_info * info)6112a6b7db3Sskrll print_insn_fr30 (bfd_vma pc, disassemble_info *info)
6122a6b7db3Sskrll {
6132a6b7db3Sskrll static cpu_desc_list *cd_list = 0;
6142a6b7db3Sskrll cpu_desc_list *cl = 0;
6152a6b7db3Sskrll static CGEN_CPU_DESC cd = 0;
6162a6b7db3Sskrll static CGEN_BITSET *prev_isa;
6172a6b7db3Sskrll static int prev_mach;
6182a6b7db3Sskrll static int prev_endian;
619*f22f0ef4Schristos static int prev_insn_endian;
6202a6b7db3Sskrll int length;
6212a6b7db3Sskrll CGEN_BITSET *isa;
6222a6b7db3Sskrll int mach;
6232a6b7db3Sskrll int endian = (info->endian == BFD_ENDIAN_BIG
6242a6b7db3Sskrll ? CGEN_ENDIAN_BIG
6252a6b7db3Sskrll : CGEN_ENDIAN_LITTLE);
626*f22f0ef4Schristos int insn_endian = (info->endian_code == BFD_ENDIAN_BIG
627*f22f0ef4Schristos ? CGEN_ENDIAN_BIG
628*f22f0ef4Schristos : CGEN_ENDIAN_LITTLE);
6292a6b7db3Sskrll enum bfd_architecture arch;
6302a6b7db3Sskrll
6312a6b7db3Sskrll /* ??? gdb will set mach but leave the architecture as "unknown" */
6322a6b7db3Sskrll #ifndef CGEN_BFD_ARCH
6332a6b7db3Sskrll #define CGEN_BFD_ARCH bfd_arch_fr30
6342a6b7db3Sskrll #endif
6352a6b7db3Sskrll arch = info->arch;
6362a6b7db3Sskrll if (arch == bfd_arch_unknown)
6372a6b7db3Sskrll arch = CGEN_BFD_ARCH;
6382a6b7db3Sskrll
6392a6b7db3Sskrll /* There's no standard way to compute the machine or isa number
6402a6b7db3Sskrll so we leave it to the target. */
6412a6b7db3Sskrll #ifdef CGEN_COMPUTE_MACH
6422a6b7db3Sskrll mach = CGEN_COMPUTE_MACH (info);
6432a6b7db3Sskrll #else
6442a6b7db3Sskrll mach = info->mach;
6452a6b7db3Sskrll #endif
6462a6b7db3Sskrll
6472a6b7db3Sskrll #ifdef CGEN_COMPUTE_ISA
6482a6b7db3Sskrll {
6492a6b7db3Sskrll static CGEN_BITSET *permanent_isa;
6502a6b7db3Sskrll
6512a6b7db3Sskrll if (!permanent_isa)
6522a6b7db3Sskrll permanent_isa = cgen_bitset_create (MAX_ISAS);
6532a6b7db3Sskrll isa = permanent_isa;
6542a6b7db3Sskrll cgen_bitset_clear (isa);
6552a6b7db3Sskrll cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info));
6562a6b7db3Sskrll }
6572a6b7db3Sskrll #else
658f7172901Schristos isa = info->private_data;
6592a6b7db3Sskrll #endif
6602a6b7db3Sskrll
6612a6b7db3Sskrll /* If we've switched cpu's, try to find a handle we've used before */
6622a6b7db3Sskrll if (cd
6632a6b7db3Sskrll && (cgen_bitset_compare (isa, prev_isa) != 0
6642a6b7db3Sskrll || mach != prev_mach
6652a6b7db3Sskrll || endian != prev_endian))
6662a6b7db3Sskrll {
6672a6b7db3Sskrll cd = 0;
6682a6b7db3Sskrll for (cl = cd_list; cl; cl = cl->next)
6692a6b7db3Sskrll {
6702a6b7db3Sskrll if (cgen_bitset_compare (cl->isa, isa) == 0 &&
6712a6b7db3Sskrll cl->mach == mach &&
6722a6b7db3Sskrll cl->endian == endian)
6732a6b7db3Sskrll {
6742a6b7db3Sskrll cd = cl->cd;
6752a6b7db3Sskrll prev_isa = cd->isas;
6762a6b7db3Sskrll break;
6772a6b7db3Sskrll }
6782a6b7db3Sskrll }
6792a6b7db3Sskrll }
6802a6b7db3Sskrll
6812a6b7db3Sskrll /* If we haven't initialized yet, initialize the opcode table. */
6822a6b7db3Sskrll if (! cd)
6832a6b7db3Sskrll {
6842a6b7db3Sskrll const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
6852a6b7db3Sskrll const char *mach_name;
6862a6b7db3Sskrll
6872a6b7db3Sskrll if (!arch_type)
6882a6b7db3Sskrll abort ();
6892a6b7db3Sskrll mach_name = arch_type->printable_name;
6902a6b7db3Sskrll
6912a6b7db3Sskrll prev_isa = cgen_bitset_copy (isa);
6922a6b7db3Sskrll prev_mach = mach;
6932a6b7db3Sskrll prev_endian = endian;
694*f22f0ef4Schristos prev_insn_endian = insn_endian;
6952a6b7db3Sskrll cd = fr30_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
6962a6b7db3Sskrll CGEN_CPU_OPEN_BFDMACH, mach_name,
6972a6b7db3Sskrll CGEN_CPU_OPEN_ENDIAN, prev_endian,
698*f22f0ef4Schristos CGEN_CPU_OPEN_INSN_ENDIAN, prev_insn_endian,
6992a6b7db3Sskrll CGEN_CPU_OPEN_END);
7002a6b7db3Sskrll if (!cd)
7012a6b7db3Sskrll abort ();
7022a6b7db3Sskrll
7032a6b7db3Sskrll /* Save this away for future reference. */
7042a6b7db3Sskrll cl = xmalloc (sizeof (struct cpu_desc_list));
7052a6b7db3Sskrll cl->cd = cd;
7062a6b7db3Sskrll cl->isa = prev_isa;
7072a6b7db3Sskrll cl->mach = mach;
7082a6b7db3Sskrll cl->endian = endian;
7092a6b7db3Sskrll cl->next = cd_list;
7102a6b7db3Sskrll cd_list = cl;
7112a6b7db3Sskrll
7122a6b7db3Sskrll fr30_cgen_init_dis (cd);
7132a6b7db3Sskrll }
7142a6b7db3Sskrll
7152a6b7db3Sskrll /* We try to have as much common code as possible.
7162a6b7db3Sskrll But at this point some targets need to take over. */
7172a6b7db3Sskrll /* ??? Some targets may need a hook elsewhere. Try to avoid this,
7182a6b7db3Sskrll but if not possible try to move this hook elsewhere rather than
7192a6b7db3Sskrll have two hooks. */
7202a6b7db3Sskrll length = CGEN_PRINT_INSN (cd, pc, info);
7212a6b7db3Sskrll if (length > 0)
7222a6b7db3Sskrll return length;
7232a6b7db3Sskrll if (length < 0)
7242a6b7db3Sskrll return -1;
7252a6b7db3Sskrll
7262a6b7db3Sskrll (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
7272a6b7db3Sskrll return cd->default_insn_bitsize / 8;
7282a6b7db3Sskrll }
729