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/m32r-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 "m32r-desc.h"
    3537#include "m32r-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_hash PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
     65static int my_print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
    5966
    6067/* Immediate values are prefixed with '#'.  */
    6168
    62 #define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length) \
    63 do { \
    64   if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_HASH_PREFIX)) \
    65     (*info->fprintf_func) (info->stream, "#"); \
    66 } while (0)
     69#define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length)   \
     70  do                                                            \
     71    {                                                           \
     72      if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_HASH_PREFIX))   \
     73        (*info->fprintf_func) (info->stream, "#");              \
     74    }                                                           \
     75  while (0)
    6776
    6877/* Handle '#' prefixes as operands.  */
     
    8190}
    8291
    83 #undef CGEN_PRINT_INSN
     92#undef  CGEN_PRINT_INSN
    8493#define CGEN_PRINT_INSN my_print_insn
    8594
     
    135144
    136145/* -- */
     146
     147void m32r_cgen_print_operand
     148  PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *,
     149           void const *, bfd_vma, int));
    137150
    138151/* Main entry point for printing operands.
     
    149162   This function could be moved into `print_insn_normal', but keeping it
    150163   separate makes clear the interface between `print_insn_normal' and each of
    151    the handlers.
    152 */
     164   the handlers.  */
    153165
    154166void
     
    355367  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
    356368  disassemble_info *info = (disassemble_info *) dis_info;
    357   const unsigned char *syn;
     369  const CGEN_SYNTAX_CHAR_TYPE *syn;
    358370
    359371  CGEN_INIT_PRINT (cd);
     
    382394   the extract info.
    383395   Returns 0 if all is well, non-zero otherwise.  */
     396
    384397static int
    385398read_insn (cd, pc, info, buf, buflen, ex_info, insn_value)
     
    403416  ex_info->insn_bytes = buf;
    404417
    405   switch (buflen)
    406     {
    407     case 1:
    408       *insn_value = buf[0];
    409       break;
    410     case 2:
    411       *insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
    412       break;
    413     case 4:
    414       *insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
    415       break;
    416     default:
    417       abort ();
    418     }
    419 
     418  *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
    420419  return 0;
    421420}
     
    433432     disassemble_info *info;
    434433     char *buf;
    435      int buflen;
    436 {
    437   unsigned long insn_value;
     434     unsigned int buflen;
     435{
     436  CGEN_INSN_INT insn_value;
    438437  const CGEN_INSN_LIST *insn_list;
    439438  CGEN_EXTRACT_INFO ex_info;
    440 #if 0
    441   int rc = read_insn (cd, pc, info, buf, buflen, & ex_info, & insn_value);
    442   if (rc != 0)
    443     return rc;
    444 #else
     439  int basesize;
     440
     441  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
     442  basesize = cd->base_insn_bitsize < buflen * 8 ?
     443                                     cd->base_insn_bitsize : buflen * 8;
     444  insn_value = cgen_get_insn_value (cd, buf, basesize);
     445
     446
     447  /* Fill in ex_info fields like read_insn would.  Don't actually call
     448     read_insn, since the incoming buffer is already read (and possibly
     449     modified a la m32r).  */
     450  ex_info.valid = (1 << buflen) - 1;
    445451  ex_info.dis_info = info;
    446   ex_info.valid = (1 << buflen) - 1;
    447452  ex_info.insn_bytes = buf;
    448453
    449   switch (buflen)
    450     {
    451     case 1:
    452       insn_value = buf[0];
    453       break;
    454     case 2:
    455       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
    456       break;
    457     case 4:
    458       insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
    459       break;
    460     default:
    461       abort ();
    462     }
    463 #endif
    464454  /* The instructions are stored in hash lists.
    465455     Pick the first one and keep trying until we find the right one.  */
     
    471461      CGEN_FIELDS fields;
    472462      int length;
     463      unsigned long insn_value_cropped;
    473464
    474465#ifdef CGEN_VALIDATE_INSN_SUPPORTED
    475       /* not needed as insn shouldn't be in hash lists if not supported */
     466      /* Not needed as insn shouldn't be in hash lists if not supported. */
    476467      /* Supported by this cpu?  */
    477468      if (! m32r_cgen_insn_supported (cd, insn))
     
    485476      /* ??? May wish to allow target to defer this check until the extract
    486477         handler.  */
    487       if ((insn_value & CGEN_INSN_BASE_MASK (insn))
     478
     479      /* Base size may exceed this instruction's size.  Extract the
     480         relevant part from the buffer. */
     481      if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
     482          (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
     483        insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
     484                                           info->endian == BFD_ENDIAN_BIG);
     485      else
     486        insn_value_cropped = insn_value;
     487
     488      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
    488489          == CGEN_INSN_BASE_VALUE (insn))
    489490        {
     
    494495          /* Make sure the entire insn is loaded into insn_value, if it
    495496             can fit.  */
    496           if ((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize &&
     497          if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
    497498              (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
    498499            {
     
    508509          else
    509510            length = CGEN_EXTRACT_FN (cd, insn)
    510               (cd, insn, &ex_info, insn_value, &fields, pc);
     511              (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
     512
    511513          /* length < 0 -> error */
    512514          if (length < 0)
     
    532534#ifndef CGEN_PRINT_INSN
    533535#define CGEN_PRINT_INSN default_print_insn
     536#endif
    534537
    535538static int
     
    540543{
    541544  char buf[CGEN_MAX_INSN_SIZE];
     545  int buflen;
    542546  int status;
    543547
    544   /* Read the base part of the insn.  */
    545 
    546   status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
     548  /* Attempt to read the base part of the insn.  */
     549  buflen = cd->base_insn_bitsize / 8;
     550  status = (*info->read_memory_func) (pc, buf, buflen, info);
     551
     552  /* Try again with the minimum part, if min < base.  */
     553  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
     554    {
     555      buflen = cd->min_insn_bitsize / 8;
     556      status = (*info->read_memory_func) (pc, buf, buflen, info);
     557    }
     558
    547559  if (status != 0)
    548560    {
     
    551563    }
    552564
    553   return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
    554 }
    555 #endif
     565  return print_insn (cd, pc, info, buf, buflen);
     566}
    556567
    557568/* Main entry point.
    558569   Print one instruction from PC on INFO->STREAM.
    559570   Return the size of the instruction (in bytes).  */
     571
     572typedef struct cpu_desc_list {
     573  struct cpu_desc_list *next;
     574  int isa;
     575  int mach;
     576  int endian;
     577  CGEN_CPU_DESC cd;
     578} cpu_desc_list;
    560579
    561580int
     
    564583     disassemble_info *info;
    565584{
     585  static cpu_desc_list *cd_list = 0;
     586  cpu_desc_list *cl = 0;
    566587  static CGEN_CPU_DESC cd = 0;
    567588  static int prev_isa;
     
    582603  if (arch == bfd_arch_unknown)
    583604    arch = CGEN_BFD_ARCH;
    584       
    585   /* There's no standard way to compute the isa number (e.g. for arm thumb)
     605   
     606  /* There's no standard way to compute the machine or isa number
    586607     so we leave it to the target.  */
     608#ifdef CGEN_COMPUTE_MACH
     609  mach = CGEN_COMPUTE_MACH (info);
     610#else
     611  mach = info->mach;
     612#endif
     613
    587614#ifdef CGEN_COMPUTE_ISA
    588615  isa = CGEN_COMPUTE_ISA (info);
    589616#else
    590   isa = 0;
     617  isa = info->insn_sets;
    591618#endif
    592619
    593   mach = info->mach;
    594 
    595   /* If we've switched cpu's, close the current table and open a new one.  */
     620  /* If we've switched cpu's, try to find a handle we've used before */
    596621  if (cd
    597622      && (isa != prev_isa
     
    599624          || endian != prev_endian))
    600625    {
    601       m32r_cgen_cpu_close (cd);
    602626      cd = 0;
    603     }
     627      for (cl = cd_list; cl; cl = cl->next)
     628        {
     629          if (cl->isa == isa &&
     630              cl->mach == mach &&
     631              cl->endian == endian)
     632            {
     633              cd = cl->cd;
     634              break;
     635            }
     636        }
     637    }
    604638
    605639  /* If we haven't initialized yet, initialize the opcode table.  */
     
    622656      if (!cd)
    623657        abort ();
     658
     659      /* save this away for future reference */
     660      cl = xmalloc (sizeof (struct cpu_desc_list));
     661      cl->cd = cd;
     662      cl->isa = isa;
     663      cl->mach = mach;
     664      cl->endian = endian;
     665      cl->next = cd_list;
     666      cd_list = cl;
     667
    624668      m32r_cgen_init_dis (cd);
    625669    }
Note: See TracChangeset for help on using the changeset viewer.