Ignore:
Timestamp:
Aug 16, 2003, 6:59:22 PM (22 years ago)
Author:
bird
Message:

binutils v2.14 - offical sources.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GNU/src/binutils/opcodes/fr30-dis.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.1.1.2
    r608 r609  
    55- the resultant file is machine generated, cgen-dis.in isn't
    66
    7 Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
     7Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
     8Free Software Foundation, Inc.
    89
    910This file is part of the GNU Binutils and GDB, the GNU debugger.
     
    3233#include "bfd.h"
    3334#include "symcat.h"
     35#include "libiberty.h"
    3436#include "fr30-desc.h"
    3537#include "fr30-opc.h"
     
    4850     PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
    4951              bfd_vma, int));
    50 static int print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma,
    51                                disassemble_info *, char *, int));
     52static int print_insn
     53     PARAMS ((CGEN_CPU_DESC, bfd_vma,  disassemble_info *, char *, unsigned));
    5254static int default_print_insn
    5355     PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
     56static int read_insn
     57     PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, int,
     58              CGEN_EXTRACT_INFO *, unsigned long *));
    5459
    5560
     
    5762
    5863/* -- dis.c */
     64static void print_register_list
     65  PARAMS ((PTR, long, long, int));
     66static void print_hi_register_list_ld
     67  PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
     68static void print_low_register_list_ld
     69  PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
     70static void print_hi_register_list_st
     71  PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
     72static void print_low_register_list_st
     73  PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
     74static void print_m4
     75  PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
    5976
    6077static void
     
    158175/* -- */
    159176
     177void fr30_cgen_print_operand
     178  PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *,
     179           void const *, bfd_vma, int));
     180
    160181/* Main entry point for printing operands.
    161182   XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
     
    171192   This function could be moved into `print_insn_normal', but keeping it
    172193   separate makes clear the interface between `print_insn_normal' and each of
    173    the handlers.
    174 */
     194   the handlers.  */
    175195
    176196void
     
    327347static void
    328348print_normal (cd, dis_info, value, attrs, pc, length)
    329 #ifdef CGEN_PRINT_NORMAL
    330      CGEN_CPU_DESC cd;
    331 #else
    332      CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
    333 #endif
     349     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
    334350     PTR dis_info;
    335351     long value;
    336352     unsigned int attrs;
    337 #ifdef CGEN_PRINT_NORMAL
    338      bfd_vma pc;
    339      int length;
    340 #else
    341353     bfd_vma pc ATTRIBUTE_UNUSED;
    342354     int length ATTRIBUTE_UNUSED;
    343 #endif
    344355{
    345356  disassemble_info *info = (disassemble_info *) dis_info;
     
    362373static void
    363374print_address (cd, dis_info, value, attrs, pc, length)
    364 #ifdef CGEN_PRINT_NORMAL
    365      CGEN_CPU_DESC cd;
    366 #else
    367      CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
    368 #endif
     375     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
    369376     PTR dis_info;
    370377     bfd_vma value;
    371378     unsigned int attrs;
    372 #ifdef CGEN_PRINT_NORMAL
    373      bfd_vma pc;
    374      int length;
    375 #else
    376379     bfd_vma pc ATTRIBUTE_UNUSED;
    377380     int length ATTRIBUTE_UNUSED;
    378 #endif
    379381{
    380382  disassemble_info *info = (disassemble_info *) dis_info;
     
    434436  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
    435437  disassemble_info *info = (disassemble_info *) dis_info;
    436   const unsigned char *syn;
     438  const CGEN_SYNTAX_CHAR_TYPE *syn;
    437439
    438440  CGEN_INIT_PRINT (cd);
     
    461463   the extract info.
    462464   Returns 0 if all is well, non-zero otherwise.  */
     465
    463466static int
    464467read_insn (cd, pc, info, buf, buflen, ex_info, insn_value)
     
    482485  ex_info->insn_bytes = buf;
    483486
    484   switch (buflen)
    485     {
    486     case 1:
    487       *insn_value = buf[0];
    488       break;
    489     case 2:
    490       *insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
    491       break;
    492     case 4:
    493       *insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
    494       break;
    495     default:
    496       abort ();
    497     }
    498 
     487  *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
    499488  return 0;
    500489}
     
    512501     disassemble_info *info;
    513502     char *buf;
    514      int buflen;
    515 {
    516   unsigned long insn_value;
     503     unsigned int buflen;
     504{
     505  CGEN_INSN_INT insn_value;
    517506  const CGEN_INSN_LIST *insn_list;
    518507  CGEN_EXTRACT_INFO ex_info;
    519 
    520   int rc = read_insn (cd, pc, info, buf, buflen, & ex_info, & insn_value);
    521   if (rc != 0)
    522     return rc;
     508  int basesize;
     509
     510  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
     511  basesize = cd->base_insn_bitsize < buflen * 8 ?
     512                                     cd->base_insn_bitsize : buflen * 8;
     513  insn_value = cgen_get_insn_value (cd, buf, basesize);
     514
     515
     516  /* Fill in ex_info fields like read_insn would.  Don't actually call
     517     read_insn, since the incoming buffer is already read (and possibly
     518     modified a la m32r).  */
     519  ex_info.valid = (1 << buflen) - 1;
     520  ex_info.dis_info = info;
     521  ex_info.insn_bytes = buf;
    523522
    524523  /* The instructions are stored in hash lists.
     
    531530      CGEN_FIELDS fields;
    532531      int length;
     532      unsigned long insn_value_cropped;
    533533
    534534#ifdef CGEN_VALIDATE_INSN_SUPPORTED
    535       /* not needed as insn shouldn't be in hash lists if not supported */
     535      /* Not needed as insn shouldn't be in hash lists if not supported. */
    536536      /* Supported by this cpu?  */
    537537      if (! fr30_cgen_insn_supported (cd, insn))
     
    545545      /* ??? May wish to allow target to defer this check until the extract
    546546         handler.  */
    547       if ((insn_value & CGEN_INSN_BASE_MASK (insn))
     547
     548      /* Base size may exceed this instruction's size.  Extract the
     549         relevant part from the buffer. */
     550      if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
     551          (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
     552        insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
     553                                           info->endian == BFD_ENDIAN_BIG);
     554      else
     555        insn_value_cropped = insn_value;
     556
     557      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
    548558          == CGEN_INSN_BASE_VALUE (insn))
    549559        {
     
    554564          /* Make sure the entire insn is loaded into insn_value, if it
    555565             can fit.  */
    556           if ((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize &&
     566          if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
    557567              (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
    558568            {
     
    568578          else
    569579            length = CGEN_EXTRACT_FN (cd, insn)
    570               (cd, insn, &ex_info, insn_value, &fields, pc);
     580              (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
    571581
    572582          /* length < 0 -> error */
     
    602612{
    603613  char buf[CGEN_MAX_INSN_SIZE];
     614  int buflen;
    604615  int status;
    605616
    606   /* Read the base part of the insn.  */
    607 
    608   status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
     617  /* Attempt to read the base part of the insn.  */
     618  buflen = cd->base_insn_bitsize / 8;
     619  status = (*info->read_memory_func) (pc, buf, buflen, info);
     620
     621  /* Try again with the minimum part, if min < base.  */
     622  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
     623    {
     624      buflen = cd->min_insn_bitsize / 8;
     625      status = (*info->read_memory_func) (pc, buf, buflen, info);
     626    }
     627
    609628  if (status != 0)
    610629    {
     
    613632    }
    614633
    615   return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
     634  return print_insn (cd, pc, info, buf, buflen);
    616635}
    617636
     
    619638   Print one instruction from PC on INFO->STREAM.
    620639   Return the size of the instruction (in bytes).  */
     640
     641typedef struct cpu_desc_list {
     642  struct cpu_desc_list *next;
     643  int isa;
     644  int mach;
     645  int endian;
     646  CGEN_CPU_DESC cd;
     647} cpu_desc_list;
    621648
    622649int
     
    625652     disassemble_info *info;
    626653{
     654  static cpu_desc_list *cd_list = 0;
     655  cpu_desc_list *cl = 0;
    627656  static CGEN_CPU_DESC cd = 0;
    628657  static int prev_isa;
     
    643672  if (arch == bfd_arch_unknown)
    644673    arch = CGEN_BFD_ARCH;
    645       
    646   /* There's no standard way to compute the isa number (e.g. for arm thumb)
     674   
     675  /* There's no standard way to compute the machine or isa number
    647676     so we leave it to the target.  */
     677#ifdef CGEN_COMPUTE_MACH
     678  mach = CGEN_COMPUTE_MACH (info);
     679#else
     680  mach = info->mach;
     681#endif
     682
    648683#ifdef CGEN_COMPUTE_ISA
    649684  isa = CGEN_COMPUTE_ISA (info);
    650685#else
    651   isa = 0;
     686  isa = info->insn_sets;
    652687#endif
    653688
    654   mach = info->mach;
    655 
    656   /* If we've switched cpu's, close the current table and open a new one.  */
     689  /* If we've switched cpu's, try to find a handle we've used before */
    657690  if (cd
    658691      && (isa != prev_isa
     
    660693          || endian != prev_endian))
    661694    {
    662       fr30_cgen_cpu_close (cd);
    663695      cd = 0;
    664     }
     696      for (cl = cd_list; cl; cl = cl->next)
     697        {
     698          if (cl->isa == isa &&
     699              cl->mach == mach &&
     700              cl->endian == endian)
     701            {
     702              cd = cl->cd;
     703              break;
     704            }
     705        }
     706    }
    665707
    666708  /* If we haven't initialized yet, initialize the opcode table.  */
     
    683725      if (!cd)
    684726        abort ();
     727
     728      /* save this away for future reference */
     729      cl = xmalloc (sizeof (struct cpu_desc_list));
     730      cl->cd = cd;
     731      cl->isa = isa;
     732      cl->mach = mach;
     733      cl->endian = endian;
     734      cl->next = cd_list;
     735      cd_list = cl;
     736
    685737      fr30_cgen_init_dis (cd);
    686738    }
Note: See TracChangeset for help on using the changeset viewer.