X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Ffr30-dis.c;h=0f7c8e895f5518a4c50da5bfcddacca81aeb59e4;hb=f1022c90ad7f6b94257c1b2fda3b46a5db9c9867;hp=f9adba50199cf5e622a735360fe3f2d3a8a67d40;hpb=d5b2f4d67cf654227d255e7e72c5f85fe2f020ee;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/fr30-dis.c b/opcodes/fr30-dis.c index f9adba5019..0f7c8e895f 100644 --- a/opcodes/fr30-dis.c +++ b/opcodes/fr30-dis.c @@ -1,26 +1,27 @@ /* Disassembler interface for targets using CGEN. -*- C -*- CGEN: Cpu tools GENerator -THIS FILE IS MACHINE GENERATED WITH CGEN. -- the resultant file is machine generated, cgen-dis.in isn't + THIS FILE IS MACHINE GENERATED WITH CGEN. + - the resultant file is machine generated, cgen-dis.in isn't -Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2005 + Free Software Foundation, Inc. -This file is part of the GNU Binutils and GDB, the GNU debugger. + This file is part of the GNU Binutils and GDB, the GNU debugger. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* ??? Eventually more and more of this stuff can go to cpu-independent files. Keep that in mind. */ @@ -31,6 +32,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., #include "dis-asm.h" #include "bfd.h" #include "symcat.h" +#include "libiberty.h" #include "fr30-desc.h" #include "fr30-opc.h" #include "opintl.h" @@ -38,36 +40,35 @@ along with this program; if not, write to the Free Software Foundation, Inc., /* Default text to print if an instruction isn't recognized. */ #define UNKNOWN_INSN_MSG _("*unknown*") -static void print_normal PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); -static void print_address PARAMS ((CGEN_CPU_DESC, PTR, bfd_vma, unsigned, bfd_vma, int)); -static void print_keyword PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned)); -static void print_insn_normal PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int)); -static int print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, int)); -static int default_print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *)); -static void print_register_list PARAMS ((PTR, long, long, int)); -static void print_hi_register_list_ld PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); -static void print_low_register_list_ld PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); -static void print_hi_register_list_st PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); -static void print_low_register_list_st PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); -static void print_m4 PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); - void fr30_cgen_print_operand PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int)); -static int read_insn PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, int, CGEN_EXTRACT_INFO *, unsigned long *)); +static void print_normal + (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int); +static void print_address + (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED; +static void print_keyword + (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED; +static void print_insn_normal + (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int); +static int print_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned); +static int default_print_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED; +static int read_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *, + unsigned long *); -/* -- disassembler routines inserted here */ +/* -- disassembler routines inserted here. */ /* -- dis.c */ - static void -print_register_list (dis_info, value, offset, load_store) - PTR dis_info; - long value; - long offset; - int load_store; /* 0 == load, 1 == store */ +print_register_list (void * dis_info, + long value, + long offset, + int load_store) /* 0 == load, 1 == store. */ { disassemble_info *info = dis_info; int mask; int index = 0; - char* comma = ""; + char * comma = ""; if (load_store) mask = 0x80; @@ -76,7 +77,7 @@ print_register_list (dis_info, value, offset, load_store) if (value & mask) { - (*info->fprintf_func) (info->stream, "r%i", index + offset); + (*info->fprintf_func) (info->stream, "r%li", index + offset); comma = ","; } @@ -89,74 +90,73 @@ print_register_list (dis_info, value, offset, load_store) if (value & mask) { - (*info->fprintf_func) (info->stream, "%sr%i", comma, index + offset); + (*info->fprintf_func) (info->stream, "%sr%li", comma, index + offset); comma = ","; } } } static void -print_hi_register_list_ld (cd, dis_info, value, attrs, pc, length) - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; - PTR dis_info; - long value; - unsigned int attrs ATTRIBUTE_UNUSED; - bfd_vma pc ATTRIBUTE_UNUSED; - int length ATTRIBUTE_UNUSED; +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) { - print_register_list (dis_info, value, 8, 0/*load*/); + print_register_list (dis_info, value, 8, 0 /* Load. */); } static void -print_low_register_list_ld (cd, dis_info, value, attrs, pc, length) - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; - PTR dis_info; - long value; - unsigned int attrs ATTRIBUTE_UNUSED; - bfd_vma pc ATTRIBUTE_UNUSED; - int length ATTRIBUTE_UNUSED; +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) { - print_register_list (dis_info, value, 0, 0/*load*/); + print_register_list (dis_info, value, 0, 0 /* Load. */); } static void -print_hi_register_list_st (cd, dis_info, value, attrs, pc, length) - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; - PTR dis_info; - long value; - unsigned int attrs ATTRIBUTE_UNUSED; - bfd_vma pc ATTRIBUTE_UNUSED; - int length ATTRIBUTE_UNUSED; +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) { - print_register_list (dis_info, value, 8, 1/*store*/); + print_register_list (dis_info, value, 8, 1 /* Store. */); } static void -print_low_register_list_st (cd, dis_info, value, attrs, pc, length) - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; - PTR dis_info; - long value; - unsigned int attrs ATTRIBUTE_UNUSED; - bfd_vma pc ATTRIBUTE_UNUSED; - int length ATTRIBUTE_UNUSED; +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) { - print_register_list (dis_info, value, 0, 1/*store*/); + print_register_list (dis_info, value, 0, 1 /* Store. */); } static void -print_m4 (cd, dis_info, value, attrs, pc, length) - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; - PTR dis_info; - long value; - unsigned int attrs ATTRIBUTE_UNUSED; - bfd_vma pc ATTRIBUTE_UNUSED; - int length ATTRIBUTE_UNUSED; +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) { disassemble_info *info = (disassemble_info *) dis_info; + (*info->fprintf_func) (info->stream, "%ld", value); } /* -- */ +void fr30_cgen_print_operand + (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int); + /* Main entry point for printing operands. XINFO is a `void *' and not a `disassemble_info *' to not put a requirement of dis-asm.h on cgen.h. @@ -170,20 +170,18 @@ print_m4 (cd, dis_info, value, attrs, pc, length) This function could be moved into `print_insn_normal', but keeping it separate makes clear the interface between `print_insn_normal' and each of - the handlers. -*/ + the handlers. */ void -fr30_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length) - CGEN_CPU_DESC cd; - int opindex; - PTR xinfo; - CGEN_FIELDS *fields; - void const *attrs ATTRIBUTE_UNUSED; - bfd_vma pc; - int length; +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) { - disassemble_info *info = (disassemble_info *) xinfo; + disassemble_info *info = (disassemble_info *) xinfo; switch (opindex) { @@ -311,8 +309,7 @@ cgen_print_fn * const fr30_cgen_print_handlers[] = void -fr30_cgen_init_dis (cd) - CGEN_CPU_DESC cd; +fr30_cgen_init_dis (CGEN_CPU_DESC cd) { fr30_cgen_init_opcode_table (cd); fr30_cgen_init_ibld_table (cd); @@ -324,22 +321,12 @@ fr30_cgen_init_dis (cd) /* Default print handler. */ static void -print_normal (cd, dis_info, value, attrs, pc, length) -#ifdef CGEN_PRINT_NORMAL - CGEN_CPU_DESC cd; -#else - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; -#endif - PTR dis_info; - long value; - unsigned int attrs; -#ifdef CGEN_PRINT_NORMAL - bfd_vma pc; - int length; -#else - bfd_vma pc ATTRIBUTE_UNUSED; - int length ATTRIBUTE_UNUSED; -#endif +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) { disassemble_info *info = (disassemble_info *) dis_info; @@ -359,22 +346,12 @@ print_normal (cd, dis_info, value, attrs, pc, length) /* Default address handler. */ static void -print_address (cd, dis_info, value, attrs, pc, length) -#ifdef CGEN_PRINT_NORMAL - CGEN_CPU_DESC cd; -#else - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; -#endif - PTR dis_info; - bfd_vma value; - unsigned int attrs; -#ifdef CGEN_PRINT_NORMAL - bfd_vma pc; - int length; -#else - bfd_vma pc ATTRIBUTE_UNUSED; - int length ATTRIBUTE_UNUSED; -#endif +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) { disassemble_info *info = (disassemble_info *) dis_info; @@ -384,7 +361,7 @@ print_address (cd, dis_info, value, attrs, pc, length) /* Print the operand as directed by the attributes. */ if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) - ; /* nothing to do */ + ; /* Nothing to do. */ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR)) (*info->print_address_func) (value, info); else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR)) @@ -398,12 +375,11 @@ print_address (cd, dis_info, value, attrs, pc, length) /* Keyword print handler. */ static void -print_keyword (cd, dis_info, keyword_table, value, attrs) - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; - PTR dis_info; - CGEN_KEYWORD *keyword_table; - long value; - unsigned int attrs ATTRIBUTE_UNUSED; +print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void *dis_info, + CGEN_KEYWORD *keyword_table, + long value, + unsigned int attrs ATTRIBUTE_UNUSED) { disassemble_info *info = (disassemble_info *) dis_info; const CGEN_KEYWORD_ENTRY *ke; @@ -417,17 +393,16 @@ print_keyword (cd, dis_info, keyword_table, value, attrs) /* Default insn printer. - DIS_INFO is defined as `PTR' so the disassembler needn't know anything + DIS_INFO is defined as `void *' so the disassembler needn't know anything about disassemble_info. */ static void -print_insn_normal (cd, dis_info, insn, fields, pc, length) - CGEN_CPU_DESC cd; - PTR dis_info; - const CGEN_INSN *insn; - CGEN_FIELDS *fields; - bfd_vma pc; - int length; +print_insn_normal (CGEN_CPU_DESC cd, + void *dis_info, + const CGEN_INSN *insn, + CGEN_FIELDS *fields, + bfd_vma pc, + int length) { const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); disassemble_info *info = (disassemble_info *) dis_info; @@ -457,17 +432,18 @@ print_insn_normal (cd, dis_info, insn, fields, pc, length) /* Subroutine of print_insn. Reads an insn into the given buffers and updates the extract info. Returns 0 if all is well, non-zero otherwise. */ + static int -read_insn (cd, pc, info, buf, buflen, ex_info, insn_value) - CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; - bfd_vma pc; - disassemble_info *info; - char *buf; - int buflen; - CGEN_EXTRACT_INFO *ex_info; - unsigned long *insn_value; +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) { int status = (*info->read_memory_func) (pc, buf, buflen, info); + if (status != 0) { (*info->memory_error_func) (status, pc, info); @@ -489,19 +465,22 @@ read_insn (cd, pc, info, buf, buflen, ex_info, insn_value) been called). */ static int -print_insn (cd, pc, info, buf, buflen) - CGEN_CPU_DESC cd; - bfd_vma pc; - disassemble_info *info; - char *buf; - int buflen; +print_insn (CGEN_CPU_DESC cd, + bfd_vma pc, + disassemble_info *info, + bfd_byte *buf, + unsigned int buflen) { CGEN_INSN_INT insn_value; const CGEN_INSN_LIST *insn_list; CGEN_EXTRACT_INFO ex_info; + int basesize; /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */ - insn_value = cgen_get_insn_value (cd, buf, buflen * 8); + basesize = cd->base_insn_bitsize < buflen * 8 ? + cd->base_insn_bitsize : buflen * 8; + insn_value = cgen_get_insn_value (cd, buf, basesize); + /* Fill in ex_info fields like read_insn would. Don't actually call read_insn, since the incoming buffer is already read (and possibly @@ -513,7 +492,7 @@ print_insn (cd, pc, info, buf, buflen) /* The instructions are stored in hash lists. Pick the first one and keep trying until we find the right one. */ - insn_list = CGEN_DIS_LOOKUP_INSN (cd, buf, insn_value); + insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value); while (insn_list != NULL) { const CGEN_INSN *insn = insn_list->insn; @@ -522,7 +501,7 @@ print_insn (cd, pc, info, buf, buflen) unsigned long insn_value_cropped; #ifdef CGEN_VALIDATE_INSN_SUPPORTED - /* not needed as insn shouldn't be in hash lists if not supported */ + /* Not needed as insn shouldn't be in hash lists if not supported. */ /* Supported by this cpu? */ if (! fr30_cgen_insn_supported (cd, insn)) { @@ -537,7 +516,7 @@ print_insn (cd, pc, info, buf, buflen) /* Base size may exceed this instruction's size. Extract the relevant part from the buffer. */ - if ((CGEN_INSN_BITSIZE (insn) / 8) < buflen && + if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen && (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn), info->endian == BFD_ENDIAN_BIG); @@ -553,7 +532,7 @@ print_insn (cd, pc, info, buf, buflen) /* Make sure the entire insn is loaded into insn_value, if it can fit. */ - if ((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize && + if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) && (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) { unsigned long full_insn_value; @@ -569,13 +548,13 @@ print_insn (cd, pc, info, buf, buflen) length = CGEN_EXTRACT_FN (cd, insn) (cd, insn, &ex_info, insn_value_cropped, &fields, pc); - /* length < 0 -> error */ + /* Length < 0 -> error. */ if (length < 0) return length; if (length > 0) { CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length); - /* length is in bits, result is in bytes */ + /* Length is in bits, result is in bytes. */ return length / 8; } } @@ -595,12 +574,9 @@ print_insn (cd, pc, info, buf, buflen) #endif static int -default_print_insn (cd, pc, info) - CGEN_CPU_DESC cd; - bfd_vma pc; - disassemble_info *info; +default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) { - char buf[CGEN_MAX_INSN_SIZE]; + bfd_byte buf[CGEN_MAX_INSN_SIZE]; int buflen; int status; @@ -628,11 +604,20 @@ default_print_insn (cd, pc, info) Print one instruction from PC on INFO->STREAM. Return the size of the instruction (in bytes). */ +typedef struct cpu_desc_list +{ + struct cpu_desc_list *next; + int isa; + int mach; + int endian; + CGEN_CPU_DESC cd; +} cpu_desc_list; + int -print_insn_fr30 (pc, info) - bfd_vma pc; - disassemble_info *info; +print_insn_fr30 (bfd_vma pc, disassemble_info *info) { + static cpu_desc_list *cd_list = 0; + cpu_desc_list *cl = 0; static CGEN_CPU_DESC cd = 0; static int prev_isa; static int prev_mach; @@ -663,18 +648,27 @@ print_insn_fr30 (pc, info) #ifdef CGEN_COMPUTE_ISA isa = CGEN_COMPUTE_ISA (info); #else - isa = 0; + isa = info->insn_sets; #endif - /* If we've switched cpu's, close the current table and open a new one. */ + /* If we've switched cpu's, try to find a handle we've used before */ if (cd && (isa != prev_isa || mach != prev_mach || endian != prev_endian)) { - fr30_cgen_cpu_close (cd); cd = 0; - } + for (cl = cd_list; cl; cl = cl->next) + { + if (cl->isa == isa && + cl->mach == mach && + cl->endian == endian) + { + cd = cl->cd; + break; + } + } + } /* If we haven't initialized yet, initialize the opcode table. */ if (! cd) @@ -695,6 +689,16 @@ print_insn_fr30 (pc, info) CGEN_CPU_OPEN_END); if (!cd) abort (); + + /* Save this away for future reference. */ + cl = xmalloc (sizeof (struct cpu_desc_list)); + cl->cd = cd; + cl->isa = isa; + cl->mach = mach; + cl->endian = endian; + cl->next = cd_list; + cd_list = cl; + fr30_cgen_init_dis (cd); }