OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [or32.c] - Diff between revs 1672 and 1748

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1672 Rev 1748
Line 1... Line 1...
/* Table of opcodes for the OpenRISC 1000 ISA.
/* Table of opcodes for the OpenRISC 1000 ISA.
 
 
   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 
   Copyright (C) 2008 Embecosm Limited
 
 
   Contributed by Damjan Lampret (lampret@opencores.org).
   Contributed by Damjan Lampret (lampret@opencores.org).
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
This file is part of gen_or1k_isa, or1ksim, GDB and GAS.
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
 
   This file is also part of gen_or1k_isa, GDB and GAS.
 
 
This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify it
it under the terms of the GNU General Public License as published by
   under the terms of the GNU General Public License as published by the Free
the Free Software Foundation; either version 2 of the License, or
   Software Foundation; either version 3 of the License, or (at your option)
(at your option) any later version.
   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.
 
 
 
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.  */
 
 
 
/*
 
 * $Log: not supported by cvs2svn $
 
 * Revision 1.51  2006/01/19 19:25:10  nogj
 
 * Pass the instruction operands as part of the op_queue structure.
 
 *
 
 * Revision 1.50  2005/11/18 18:15:21  nogj
 
 * Execute l.ff1 instruction
 
 *
 
 * Revision 1.49  2005/11/06 16:23:07  nogj
 
 * Fix parsing the destination register
 
 *
 
 * Revision 1.48  2005/11/03 19:01:50  lampret
 
 * Added l.fl1
 
 *
 
 * Revision 1.47  2005/09/05 08:47:44  nogj
 
 * Fix most warnings issued by gcc4
 
 *
 
 * Revision 1.46  2005/08/18 22:13:27  phoenix
 
 * fixed l.maci encoding
 
 *
 
 * Revision 1.45  2005/04/27 19:13:13  nogj
 
 * l.rfe does not have a delay slot.  Don't mark it as such.
 
 *
 
 * Revision 1.44  2005/03/31 16:09:57  nogj
 
 * Implement a dynamic recompiler to speed up the execution
 
 *
 
 * Revision 1.43  2005/03/31 16:01:59  nogj
 
 * Reclasify l.trap and l.sys to be an exception instruction
 
 *
 
 * Revision 1.42  2005/03/16 12:25:56  nogj
 
 * Fix the parameters to the l.ff1/l.maci instructions
 
 *
 
 * Revision 1.41  2005/02/09 17:41:03  nogj
 
 * Mark a simulated cpu address as such, by introducing the new oraddr_t type
 
 *
 
 * Revision 1.40  2005/01/27 14:14:13  nogj
 
 * Remove the global op structure
 
 *
 
 * Revision 1.39  2005/01/27 13:35:40  nogj
 
 *  * Fix generate.c to produce a execgen.c with less warnings.
 
 *  * Fix the --enable-simple configure option.
 
 *
 
 * Revision 1.38  2005/01/27 13:15:50  nogj
 
 * Mark wich operand is the destination operand in the architechture definition
 
 *
 
 * Revision 1.37  2005/01/11 15:41:58  andreje
 
 * l.ff1 instruction added
 
 *
 
 * Revision 1.36  2004/07/22 20:17:23  phoenix
 
 * removed includes
 
 *
 
 * Revision 1.35  2004/07/19 23:07:37  phoenix
 
 * Gyorgy Jeney: extensive cleanup
 
 *
 
 * Revision 1.34  2004/06/27 22:56:48  lampret
 
 * Updated instruction set descriptions. Changed FP instructions encoding.
 
 *
 
 * Revision 1.33  2004/05/09 19:52:31  lampret
 
 * Changed desciption of the l.cust5 insns
 
 *
 
 * Revision 1.31  2003/07/01 19:34:49  csanchez
 
 * Added support for l.addc instruction.
 
 *
 
 * Revision 1.30  2003/01/28 03:49:24  lampret
 
 * Added cvs log keywords
 
 *
 
 */
 
 
 
#include <string.h>
   This program is distributed in the hope that it will be useful, but WITHOUT
#include <stdio.h>
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#include <stdlib.h>
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#include <ctype.h>
   more details.
 
 
 
   You should have received a copy of the GNU General Public License along
 
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#ifdef HAVE_CONFIG_H
/* This program is commented throughout in a fashion suitable for processing
 
   with Doxygen. */
 
 
 
 
 
/* Autoconf and/or portability configuration */
# include "config.h"
# include "config.h"
#endif
 
#ifdef HAS_EXECUTION
 
# ifdef HAVE_INTTYPES_H
 
#  include <inttypes.h> /* ...but to get arch.h we need uint{8,16,32}_t... */
 
# endif
 
# include "port.h"
# include "port.h"
# include "arch.h" /* ...but to get abstract.h, we need oraddr_t... */
 
# include "abstract.h" /* To get struct iqueue_entry... */
 
# include "debug.h" /* To get debug() */
 
#endif
 
#include "opcode/or32.h"
 
 
 
/* **INDENT-OFF** */
/* System includes */
 
#include <stdlib.h>
 
#include <stdio.h>
 
 
 
/* Package includes */
 
#include "opcode/or32.h"
 
 
/* We treat all letters the same in encode/decode routines so
/* We treat all letters the same in encode/decode routines so
   we need to assign some characteristics to them like signess etc.*/
   we need to assign some characteristics to them like signess etc.*/
CONST struct or32_letter or32_letters[] =
CONST struct or32_letter or32_letters[] = {
{
 
{ 'A', NUM_UNSIGNED },
{ 'A', NUM_UNSIGNED },
{ 'B', NUM_UNSIGNED },
{ 'B', NUM_UNSIGNED },
{ 'D', NUM_UNSIGNED },
{ 'D', NUM_UNSIGNED },
{ 'I', NUM_SIGNED },
{ 'I', NUM_SIGNED },
{ 'K', NUM_UNSIGNED },
{ 'K', NUM_UNSIGNED },
Line 135... Line 63...
  Recommendation: irrelevant instruction bits should be set with a value of
  Recommendation: irrelevant instruction bits should be set with a value of
  bits in same positions of instruction preceding current instruction in the
  bits in same positions of instruction preceding current instruction in the
  code (when assembling).
  code (when assembling).
*/
*/
 
 
#ifdef HAS_EXECUTION
#ifdef HAVE_EXECUTION
# if SIMPLE_EXECUTION
# if SIMPLE_EXECUTION
#  define EFN &l_none
#  define EFN &l_none
#  define EF(func) &(func)
#  define EF(func) &(func)
#  define EFI &l_invalid
#  define EFI &l_invalid
# elif COMPLEX_EXECUTION
# elif COMPLEX_EXECUTION
Line 153... Line 81...
# else /* DYNAMIC_EXECUTION */
# else /* DYNAMIC_EXECUTION */
#  define EFN &l_none
#  define EFN &l_none
#  define EF(func) &(gen_ ##func)
#  define EF(func) &(gen_ ##func)
#  define EFI &gen_l_invalid
#  define EFI &gen_l_invalid
# endif
# endif
#else /* HAS_EXECUTION */
#else /* HAVE_EXECUTION */
# define EFN &l_none
# define EFN &l_none
# define EF(func) EFN
# define EF(func) EFN
# define EFI EFN
# define EFI EFN
#endif /* HAS_EXECUTION */
#endif /* HAVE_EXECUTION */
 
 
CONST struct or32_opcode or32_opcodes[] =
CONST struct or32_opcode or32_opcodes[] = {
{
 
 
 
{ "l.j",       "N",            "00 0x0  NNNNN NNNNN NNNN NNNN NNNN NNNN",
{ "l.j",       "N",            "00 0x0  NNNNN NNNNN NNNN NNNN NNNN NNNN",
  EF(l_j), OR32_IF_DELAY, it_jump },
  EF(l_j), OR32_IF_DELAY, it_jump },
{ "l.jal",     "N",            "00 0x1  NNNNN NNNNN NNNN NNNN NNNN NNNN",
{ "l.jal",     "N",            "00 0x1  NNNNN NNNNN NNNN NNNN NNNN NNNN",
  EF(l_jal), OR32_IF_DELAY, it_jump },
  EF(l_jal), OR32_IF_DELAY, it_jump },
Line 642... Line 569...
 
 
#undef EFI
#undef EFI
#undef EFN
#undef EFN
#undef EF 
#undef EF 
 
 
/* **INDENT-ON** */
CONST int num_opcodes =
 
  ((sizeof (or32_opcodes)) / (sizeof (struct or32_opcode))) - 1;
/* Define dummy, if debug is not defined.  */
 
#ifndef HAS_DEBUG
 
#define debug(l, fmt...) ;
 
#endif
 
 
 
CONST int num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1;
 
 
 
/* Calculates instruction length in bytes. Always 4 for OR32. */
/* Calculates instruction length in bytes. Always 4 for OR32. */
int
int
insn_len(int insn_index)
insn_len(int insn_index)
{
{
Line 685... Line 606...
  CONST struct or32_opcode *pinsn;
  CONST struct or32_opcode *pinsn;
  char *enc;
  char *enc;
  int range = 0;
  int range = 0;
 
 
  /* Is value cached? */
  /* Is value cached? */
  if ((range = range_cache[(unsigned char)l])) return range;
  if ((range = range_cache[(unsigned char) l]))
 
    return range;
 
 
  for(pinsn = or32_opcodes; strlen(pinsn->name); pinsn++)
  for(pinsn = or32_opcodes; strlen(pinsn->name); pinsn++)
    {
    {
      if (strchr(pinsn->encoding,l))
      if (strchr(pinsn->encoding,l))
        {
        {
Line 728... Line 650...
    return or32_opcodes[index].name;
    return or32_opcodes[index].name;
  else
  else
    return "???";
    return "???";
}
}
 
 
#if defined(HAS_EXECUTION) && SIMPLE_EXECUTION
#if defined(HAVE_EXECUTION) && SIMPLE_EXECUTION
void
void
l_none(struct iqueue_entry *current)
l_none(struct iqueue_entry *current)
{
{
}
}
#elif defined(HAS_EXECUTION) && DYNAMIC_EXECUTION
#elif defined(HAVE_EXECUTION) && DYNAMIC_EXECUTION
void
void
l_none(struct op_queue *opq, int *param_t, int delay_slot)
l_none(struct op_queue *opq, int *param_t, int delay_slot)
{
{
}
}
#else
#else
Line 799... Line 721...
/* MM: Struct that holds runtime build information about instructions.  */
/* MM: Struct that holds runtime build information about instructions.  */
struct temp_insn_struct *ti;
struct temp_insn_struct *ti;
 
 
struct insn_op_struct *op_data, **op_start;
struct insn_op_struct *op_data, **op_start;
 
 
/* Recursive utility function used to find best match and to build automata.  */
static void
 
or32_debug (int level, const char *format, ...)
 
{
 
#if DEBUG
 
  char *p;
 
  va_list ap;
 
 
 
  if ((p = malloc (1000)) == NULL)
 
    return;
 
  va_start (ap, format);
 
  (void) vsnprintf (p, 1000, format, ap);
 
  va_end (ap);
 
  printf ("%s\n", p);
 
  fflush (stdout);
 
  free (p);
 
#endif
 
}
 
 
 
/* Recursive utility function used to find best match and to build automata.  */
static unsigned long *
static unsigned long *
cover_insn (unsigned long *cur, int pass, unsigned int mask)
cover_insn (unsigned long *cur, int pass, unsigned int mask)
{
{
  int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
  int best_first = 0, best_len = 0, i, last_match = -1, ninstr = 0;
  unsigned long cur_mask = mask;
  unsigned long cur_mask = mask;
Line 816... Line 755...
        cur_mask &= ti[i].insn_mask;
        cur_mask &= ti[i].insn_mask;
        ninstr++;
        ninstr++;
        last_match = i;
        last_match = i;
      }
      }
 
 
  debug(8, "%08X %08X\n", mask, cur_mask);
  or32_debug (8, "%08X %08lX\n", mask, cur_mask);
  if (ninstr == 0)
  if (ninstr == 0)
    return 0;
    return 0;
  if (ninstr == 1)
  if (ninstr == 1)
    {
    {
      /* Leaf holds instruction index. */
      /* Leaf holds instruction index. */
      debug(8, "%i>I%i %s\n", cur - automata, last_match, or32_opcodes[last_match].name);
      or32_debug (8, "%i>I%i %s\n", cur - automata, last_match,
 
             or32_opcodes[last_match].name);
      *cur = LEAF_FLAG | last_match;
      *cur = LEAF_FLAG | last_match;
      cur++;
      cur++;
      nuncovered--;
      nuncovered--;
    } else {
    }
 
  else
 
    {
      /* Find longest match.  */
      /* Find longest match.  */
      for (i = 0; i < 32; i++)
      for (i = 0; i < 32; i++)
        {
        {
          int len;
          int len;
          for (len = best_len + 1; len < MIN(MAX_LEN, 33 - i); len++)
          for (len = best_len + 1; len < MIN(MAX_LEN, 33 - i); len++)
            {
            {
              unsigned long m = (1UL << ((unsigned long)len)) - 1;
              unsigned long m = (1UL << ((unsigned long)len)) - 1;
              debug(9, " (%i(%08X & %08X>>%i = %08X, %08X)",len,m, cur_mask, i, (cur_mask >> (unsigned)i), (cur_mask >> (unsigned)i) & m);
              or32_debug (9, " (%i(%08lX & %08lX>>%i = %08lX, %08lX)", len, m,
 
                     cur_mask, i, (cur_mask >> (unsigned) i),
 
                     (cur_mask >> (unsigned) i) & m);
              if ((m & (cur_mask >> (unsigned)i)) == m)
              if ((m & (cur_mask >> (unsigned)i)) == m)
                {
                {
                  best_len = len;
                  best_len = len;
                  best_first = i;
                  best_first = i;
                  debug(9, "!");
                  or32_debug (9, "!");
                }
                }
              else
              else
                break;
                break;
            }
            }
        }
        }
      debug(9, "\n");
      or32_debug (9, "\n");
      if (!best_len)
      if (!best_len)
        {
        {
          fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr, mask);
          fprintf (stderr, "%i instructions match mask 0x%08X:\n", ninstr,
 
                   mask);
          for (i = 0; i < num_opcodes; i++)
          for (i = 0; i < num_opcodes; i++)
            if (ti[i].in_pass == pass)
            if (ti[i].in_pass == pass)
              fprintf (stderr, "%s ", or32_opcodes[i].name);
              fprintf (stderr, "%s ", or32_opcodes[i].name);
 
 
          fprintf (stderr, "\n");
          fprintf (stderr, "\n");
          exit (1);
          exit (1);
        }
        }
      debug(8, "%i> #### %i << %i (%i) ####\n", cur - automata, best_len, best_first, ninstr);
      or32_debug (8, "%i> #### %i << %i (%i) ####\n", cur - automata, best_len,
 
             best_first, ninstr);
      *cur = best_first;
      *cur = best_first;
      cur++;
      cur++;
      *cur = (1 << best_len) - 1;
      *cur = (1 << best_len) - 1;
      cur++;
      cur++;
      next = cur;
      next = cur;
Line 873... Line 819...
          int j;
          int j;
          unsigned long *c;
          unsigned long *c;
          curpass++;
          curpass++;
          for (j = 0; j < num_opcodes; j++)
          for (j = 0; j < num_opcodes; j++)
            if (ti[j].in_pass == pass
            if (ti[j].in_pass == pass
                && ((ti[j].insn >> best_first) & cur_mask) == (unsigned long) i
                && ((ti[j].insn >> best_first) & cur_mask) ==
 
                (unsigned long) i
                && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
                && ((ti[j].insn_mask >> best_first) & cur_mask) == cur_mask)
              ti[j].in_pass = curpass;
              ti[j].in_pass = curpass;
 
 
          debug(9, "%08X %08X %i\n", mask, cur_mask, best_first);
          or32_debug (9, "%08X %08lX %i\n", mask, cur_mask, best_first);
          c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
          c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
          if (c)
          if (c)
            {
            {
              debug(8, "%i> #%X -> %u\n", next - automata, i, cur - automata);
              or32_debug (8, "%i> #%X -> %u\n", next - automata, i,
 
                     cur - automata);
              *next = cur - automata;
              *next = cur - automata;
              cur = c;
              cur = c;
            }
            }
          else
          else
            {
            {
              debug(8, "%i> N/A\n", next - automata);
              or32_debug (8, "%i> N/A\n", next - automata);
              *next = 0;
              *next = 0;
            }
            }
          next++;
          next++;
        }
        }
    }
    }
Line 923... Line 871...
  int num_cur_op = 0;;
  int num_cur_op = 0;;
 
 
  i = 0;
  i = 0;
  type = 0;
  type = 0;
  /* In case we don't have any parameters, we add dummy read from r0.  */
  /* In case we don't have any parameters, we add dummy read from r0.  */
  if (!(*args)) {
  if (!(*args))
 
    {
    cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
    cur->type = OPTYPE_REG | OPTYPE_OP | OPTYPE_LAST;
    cur->data = 0;
    cur->data = 0;
    debug(9, "#%08X %08X\n", cur->type, cur->data);
      or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
    cur++;
    cur++;
    return cur;
    return cur;
  }
  }
 
 
  while (*args != '\0')
  while (*args != '\0')
Line 944... Line 893...
        }
        }
      else if (isalpha (*args))
      else if (isalpha (*args))
        {
        {
          unsigned long arg;
          unsigned long arg;
          arg = insn_extract(*args, opcode->encoding);
          arg = insn_extract(*args, opcode->encoding);
          debug(9, "%s : %08X ------\n", opcode->name, arg);
          or32_debug (9, "%s : %08lX ------\n", opcode->name, arg);
          if (letter_signed (*args))
          if (letter_signed (*args))
            {
            {
              type |= OPTYPE_SIG;
              type |= OPTYPE_SIG;
              type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
              type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
            }
            }
Line 970... Line 919...
                  tmp >>= 1;
                  tmp >>= 1;
                }
                }
              cur->type = type | shr;
              cur->type = type | shr;
              cur->data = mask;
              cur->data = mask;
              arg &= ~(((1 << mask) - 1) << shr);
              arg &= ~(((1 << mask) - 1) << shr);
              debug(6, "|%08X %08X\n", cur->type, cur->data);
              or32_debug (6, "|%08lX %08lX\n", cur->type, cur->data);
              cur++;
              cur++;
              num_cur_op++;
              num_cur_op++;
            }
            }
          args++;
          args++;
        }
        }
      else if (*args == '(')
      else if (*args == '(')
        {
        {
          /* Next param is displacement.  Later we will treat them as one operand.  */
          /* Next param is displacement.  Later we will treat them as one operand.  */
          /* Set the OPTYPE_DIS flag on all insn_op_structs that belong to this
          /* Set the OPTYPE_DIS flag on all insn_op_structs that belong to this
           * operand */
           * operand */
          while(num_cur_op > 0) {
          while (num_cur_op > 0)
 
            {
            cur[-num_cur_op].type |= type | OPTYPE_DIS;
            cur[-num_cur_op].type |= type | OPTYPE_DIS;
            num_cur_op--;
            num_cur_op--;
          }
          }
          cur[-1].type |= OPTYPE_OP;
          cur[-1].type |= OPTYPE_OP;
          debug(9, ">%08X %08X\n", cur->type, cur->data);
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
          type = 0;
          type = 0;
          i++;
          i++;
          args++;
          args++;
        }
        }
      else if (*args == OPERAND_DELIM)
      else if (*args == OPERAND_DELIM)
        {
        {
          cur--;
          cur--;
          cur->type = type | cur->type | OPTYPE_OP;
          cur->type = type | cur->type | OPTYPE_OP;
          debug(9, ">%08X %08X\n", cur->type, cur->data);
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
          cur++;
          cur++;
          type = 0;
          type = 0;
          i++;
          i++;
          args++;
          args++;
        }
        }
      else if (*args == '0')
      else if (*args == '0')
        {
        {
          cur->type = type;
          cur->type = type;
          cur->data = 0;
          cur->data = 0;
          debug(9, ">%08X %08X\n", cur->type, cur->data);
          or32_debug (9, ">%08lX %08lX\n", cur->type, cur->data);
          cur++;
          cur++;
          type = 0;
          type = 0;
          i++;
          i++;
          args++;
          args++;
        }
        }
Line 1021... Line 971...
          exit (1);
          exit (1);
        }
        }
    }
    }
  cur--;
  cur--;
  cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
  cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
  debug(9, "#%08X %08X\n", cur->type, cur->data);
  or32_debug (9, "#%08lX %08lX\n", cur->type, cur->data);
  cur++;
  cur++;
  return cur;
  return cur;
}
}
 
 
/* Constructs new automata based on or32_opcodes array.  */
/* Constructs new automata based on or32_opcodes array.  */
Line 1035... Line 985...
{
{
  int i;
  int i;
  unsigned long *end;
  unsigned long *end;
  struct insn_op_struct *cur;
  struct insn_op_struct *cur;
 
 
  automata = (unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
  automata =
  ti = (struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) * num_opcodes);
    (unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
 
  ti =
 
    (struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) *
 
                                        num_opcodes);
 
 
  nuncovered = num_opcodes;
  nuncovered = num_opcodes;
 
 
#ifdef HAS_EXECUTION
#ifdef HAVE_EXECUTION
  printf("Building automata... ");
  printf("Building automata... ");
#endif
#endif
 
 
  /* Build temporary information about instructions.  */
  /* Build temporary information about instructions.  */
  for (i = 0; i < num_opcodes; i++)
  for (i = 0; i < num_opcodes; i++)
Line 1065... Line 1018...
  if (end - automata > MAX_AUTOMATA_SIZE)
  if (end - automata > MAX_AUTOMATA_SIZE)
    {
    {
      fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
      fprintf (stderr, "Automata too large. Increase MAX_AUTOMATA_SIZE.");
      exit (1);
      exit (1);
    }
    }
#ifdef HAS_EXECUTION
#ifdef HAVE_EXECUTION
  printf("done, num uncovered: %i/%i.\n", nuncovered, num_opcodes);
  printf("done, num uncovered: %i/%i.\n", nuncovered, num_opcodes);
#endif
#endif
 
 
#ifdef HAS_EXECUTION
#ifdef HAVE_EXECUTION
  printf("Parsing operands data... ");
  printf("Parsing operands data... ");
#endif
#endif
  op_data = (struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE * sizeof (struct insn_op_struct));
  op_data =
  op_start = (struct insn_op_struct **) malloc (num_opcodes * sizeof (struct insn_op_struct *));
    (struct insn_op_struct *) malloc (MAX_OP_TABLE_SIZE *
 
                                      sizeof (struct insn_op_struct));
 
  op_start =
 
    (struct insn_op_struct **) malloc (num_opcodes *
 
                                       sizeof (struct insn_op_struct *));
  cur = op_data;
  cur = op_data;
  for (i = 0; i < num_opcodes; i++)
  for (i = 0; i < num_opcodes; i++)
    {
    {
      op_start[i] = cur;
      op_start[i] = cur;
      cur = parse_params (&or32_opcodes[i], cur);
      cur = parse_params (&or32_opcodes[i], cur);
      if (cur - op_data > MAX_OP_TABLE_SIZE)
      if (cur - op_data > MAX_OP_TABLE_SIZE)
        {
        {
          fprintf (stderr, "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
          fprintf (stderr,
 
                   "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
          exit (1);
          exit (1);
        }
        }
    }
    }
#ifdef HAS_EXECUTION
#ifdef HAVE_EXECUTION
  printf("done.\n");
  printf("done.\n");
#endif
#endif
}
}
 
 
void destruct_automata ()
void
 
destruct_automata ()
{
{
  free (ti);
  free (ti);
  free (automata);
  free (automata);
  free (op_data);
  free (op_data);
  free (op_start);
  free (op_start);
}
}
 
 
/* Decodes instruction and returns instruction index.  */
/* Decodes instruction and returns instruction index.  */
int insn_decode (unsigned int insn)
int
 
insn_decode (unsigned int insn)
{
{
  unsigned long *a = automata;
  unsigned long *a = automata;
  int i;
  int i;
  while (!(*a & LEAF_FLAG))
  while (!(*a & LEAF_FLAG))
    {
    {
Line 1168... Line 1128...
  int param_pos = 0;
  int param_pos = 0;
 
 
  for (enc = enc_initial; *enc != '\0'; enc++)
  for (enc = enc_initial; *enc != '\0'; enc++)
    if (*enc == param_ch)
    if (*enc == param_ch)
      {
      {
        if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
        if (enc - 2 >= enc_initial && (*(enc - 2) == '0')
 
            && (*(enc - 1) == 'x'))
          continue;
          continue;
        else
        else
          param_pos++;
          param_pos++;
      }
      }
 
 
Line 1206... Line 1167...
    else if (*enc == param_ch)
    else if (*enc == param_ch)
      {
      {
        opc_pos--;
        opc_pos--;
        param_pos--;
        param_pos--;
#if DEBUG
#if DEBUG
        printf("\n  ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
        printf ("\n  ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos,
 
                param_pos);
#endif  
#endif  
        if (islower(param_ch))
        if (islower(param_ch))
          ret -= ((insn >> opc_pos) & 0x1) << param_pos;
          ret -= ((insn >> opc_pos) & 0x1) << param_pos;
        else
        else
          ret += ((insn >> opc_pos) & 0x1) << param_pos;
          ret += ((insn >> opc_pos) & 0x1) << param_pos;
Line 1245... Line 1207...
     unsigned long insn;
     unsigned long insn;
{
{
  int regnum = or32_extract(param_ch, encoding, insn);
  int regnum = or32_extract(param_ch, encoding, insn);
 
 
  sprintf (dest, "r%d", regnum);
  sprintf (dest, "r%d", regnum);
  while (*dest) dest++;
  while (*dest)
 
    dest++;
  return dest;
  return dest;
}
}
 
 
/* Print immediate. Used only by print_insn. */
/* Print immediate. Used only by print_insn. */
 
 
Line 1271... Line 1234...
      else
      else
        sprintf (dest, "0x%x", imm);
        sprintf (dest, "0x%x", imm);
    }
    }
  else
  else
    sprintf (dest, "%#x", imm);
    sprintf (dest, "%#x", imm);
  while (*dest) dest++;
  while (*dest)
 
    dest++;
  return dest;
  return dest;
}
}
 
 
/* Disassemble one instruction from insn to disassemble.
/* Disassemble one instruction from insn to disassemble.
   Return the size of the instruction.  */
   Return the size of the instruction.  */
Line 1300... Line 1264...
    {
    {
      struct or32_opcode const *opcode = &or32_opcodes[index];
      struct or32_opcode const *opcode = &or32_opcodes[index];
      char *s;
      char *s;
 
 
      strcpy (dest, opcode->name);
      strcpy (dest, opcode->name);
      while (*dest) dest++;
      while (*dest)
 
        dest++;
      *dest++ = ' ';
      *dest++ = ' ';
      *dest = 0;
      *dest = 0;
 
 
      for (s = opcode->args; *s != '\0'; ++s)
      for (s = opcode->args; *s != '\0'; ++s)
        {
        {
Line 1317... Line 1282...
              dest = or32_print_register(dest, *++s, opcode->encoding, insn);
              dest = or32_print_register(dest, *++s, opcode->encoding, insn);
              break;
              break;
 
 
            default:
            default:
              if (strchr (opcode->encoding, *s))
              if (strchr (opcode->encoding, *s))
                dest = or32_print_immediate (dest, *s, opcode->encoding, insn);
                dest =
              else {
                  or32_print_immediate (dest, *s, opcode->encoding, insn);
 
              else
 
                {
                *dest++ = *s;
                *dest++ = *s;
                *dest = 0;
                *dest = 0;
              }
              }
            }
            }
        }
        }
    }
    }
  else
  else
    {
    {
      /* This used to be %8x for binutils.  */
      /* This used to be %8x for binutils.  */
      sprintf(dest, ".word 0x%08lx", insn);
      sprintf(dest, ".word 0x%08lx", insn);
      while (*dest) dest++;
      while (*dest)
 
        dest++;
    }
    }
  return insn_len (insn);
  return insn_len (insn);
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.