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

Subversion Repositories or1k

[/] [or1k/] [tags/] [pre-GNU-merge/] [insight/] [opcodes/] [or32.c] - Diff between revs 133 and 138

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

Rev 133 Rev 138
Line 22... Line 22...
   we need to assign some characteristics to them like signess etc.*/
   we need to assign some characteristics to them like signess etc.*/
#include <string.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
 
 
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
 
#endif
 
#include "parse.h"
#include "opcode/or32.h"
#include "opcode/or32.h"
 
 
/* **INDENT-OFF** */
/* **INDENT-OFF** */
 
 
CONST struct or32_letter or32_letters[] =
CONST struct or32_letter or32_letters[] =
Line 69... Line 72...
CONST struct or32_opcode or32_opcodes[] =
CONST struct or32_opcode or32_opcodes[] =
{
{
 
 
{ "l.j",       "N",            "00 0x0  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_j), OR32_IF_DELAY },
{ "l.j",       "N",            "00 0x0  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_j), OR32_IF_DELAY },
{ "l.jal",     "N",            "00 0x1  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_jal), OR32_IF_DELAY },
{ "l.jal",     "N",            "00 0x1  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_jal), OR32_IF_DELAY },
{ "l.bnf",     "N",            "00 0x3  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bnf), OR32_IF_DELAY },
{ "l.bnf",     "N",            "00 0x3  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bnf), OR32_IF_DELAY | OR32_R_FLAG},
{ "l.bf",      "N",            "00 0x4  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bf), OR32_IF_DELAY },
{ "l.bf",      "N",            "00 0x4  NNNNN NNNNN NNNN NNNN NNNN NNNN", EF(l_bf), OR32_IF_DELAY | OR32_R_FLAG },
{ "l.nop",     "",             "00 0x5  01--- ----- ---- ---- ---- ----", EF(l_nop), 0 },
{ "l.nop",     "",             "00 0x5  01--- ----- ---- ---- ---- ----", EF(l_nop), 0 },
{ "l.movhi",   "rD,K",         "00 0x6  DDDDD ----0 KKKK KKKK KKKK KKKK", EF(l_movhi), 0 }, /*MM*/
{ "l.movhi",   "rD,K",         "00 0x6  DDDDD ----0 KKKK KKKK KKKK KKKK", EF(l_movhi), 0 }, /*MM*/
{ "l.macrc",   "rD",           "00 0x6  DDDDD ----1 0000 0000 0000 0000", EF(l_macrc), 0 }, /*MM*/
{ "l.macrc",   "rD",           "00 0x6  DDDDD ----1 0000 0000 0000 0000", EF(l_macrc), 0 }, /*MM*/
{ "l.mfspr",   "rD,rA,K",      "00 0x7  DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_mfspr), 0 },
{ "l.mfspr",   "rD,rA,K",      "00 0x7  DDDDD AAAAA KKKK KKKK KKKK KKKK", EF(l_mfspr), 0 },
{ "l.sys",     "K",            "00 0x8  00000 00000 KKKK KKKK KKKK KKKK", EF(l_sys), 0 },
{ "l.sys",     "K",            "00 0x8  00000 00000 KKKK KKKK KKKK KKKK", EF(l_sys), 0 },
Line 239... Line 242...
{ "l.slli",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 00LL LLLL", EF(l_sll), 0 },
{ "l.slli",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 00LL LLLL", EF(l_sll), 0 },
{ "l.srli",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 01LL LLLL", EF(l_srl), 0 },
{ "l.srli",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 01LL LLLL", EF(l_srl), 0 },
{ "l.srai",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 10LL LLLL", EF(l_sra), 0 },
{ "l.srai",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 10LL LLLL", EF(l_sra), 0 },
{ "l.rori",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 11LL LLLL", EFI, 0 },
{ "l.rori",    "rD,rA,L",      "10 0xE  DDDDD AAAAA ---- ---- 11LL LLLL", EFI, 0 },
 
 
{ "l.sfeqi",   "rA,I",         "10 0xF  00000 AAAAA IIII IIII IIII IIII", EF(l_sfeq), 0 },
{ "l.sfeqi",   "rA,I",         "10 0xF  00000 AAAAA IIII IIII IIII IIII", EF(l_sfeq), OR32_W_FLAG },
{ "l.sfnei",   "rA,I",         "10 0xF  00001 AAAAA IIII IIII IIII IIII", EF(l_sfne), 0 },
{ "l.sfnei",   "rA,I",         "10 0xF  00001 AAAAA IIII IIII IIII IIII", EF(l_sfne), OR32_W_FLAG },
{ "l.sfgtui",  "rA,I",         "10 0xF  00010 AAAAA IIII IIII IIII IIII", EF(l_sfgtu), 0 },
{ "l.sfgtui",  "rA,I",         "10 0xF  00010 AAAAA IIII IIII IIII IIII", EF(l_sfgtu), OR32_W_FLAG },
{ "l.sfgeui",  "rA,I",         "10 0xF  00011 AAAAA IIII IIII IIII IIII", EF(l_sfgeu), 0 },
{ "l.sfgeui",  "rA,I",         "10 0xF  00011 AAAAA IIII IIII IIII IIII", EF(l_sfgeu), OR32_W_FLAG },
{ "l.sfltui",  "rA,I",         "10 0xF  00100 AAAAA IIII IIII IIII IIII", EF(l_sfltu), 0 },
{ "l.sfltui",  "rA,I",         "10 0xF  00100 AAAAA IIII IIII IIII IIII", EF(l_sfltu), OR32_W_FLAG },
{ "l.sfleui",  "rA,I",         "10 0xF  00101 AAAAA IIII IIII IIII IIII", EF(l_sfleu), 0 },
{ "l.sfleui",  "rA,I",         "10 0xF  00101 AAAAA IIII IIII IIII IIII", EF(l_sfleu), OR32_W_FLAG },
{ "l.sfgtsi",  "rA,I",         "10 0xF  01010 AAAAA IIII IIII IIII IIII", EF(l_sfgts), 0 },
{ "l.sfgtsi",  "rA,I",         "10 0xF  01010 AAAAA IIII IIII IIII IIII", EF(l_sfgts), OR32_W_FLAG },
{ "l.sfgesi",  "rA,I",         "10 0xF  01011 AAAAA IIII IIII IIII IIII", EF(l_sfges), 0 },
{ "l.sfgesi",  "rA,I",         "10 0xF  01011 AAAAA IIII IIII IIII IIII", EF(l_sfges), OR32_W_FLAG },
{ "l.sfltsi",  "rA,I",         "10 0xF  01100 AAAAA IIII IIII IIII IIII", EF(l_sflts), 0 },
{ "l.sfltsi",  "rA,I",         "10 0xF  01100 AAAAA IIII IIII IIII IIII", EF(l_sflts), OR32_W_FLAG },
{ "l.sflesi",  "rA,I",         "10 0xF  01101 AAAAA IIII IIII IIII IIII", EF(l_sfles), 0 },
{ "l.sflesi",  "rA,I",         "10 0xF  01101 AAAAA IIII IIII IIII IIII", EF(l_sfles), OR32_W_FLAG },
 
 
{ "l.sd",      "I(rA),rB",     "11 0x4  IIIII AAAAA BBBB BIII IIII IIII", EFI, 0 },
{ "l.sd",      "I(rA),rB",     "11 0x4  IIIII AAAAA BBBB BIII IIII IIII", EFI, 0 },
{ "l.sw",      "I(rA),rB",     "11 0x5  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sw), 0 },
{ "l.sw",      "I(rA),rB",     "11 0x5  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sw), 0 },
{ "l.sb",      "I(rA),rB",     "11 0x6  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sb), 0 },
{ "l.sb",      "I(rA),rB",     "11 0x6  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sb), 0 },
{ "l.sh",      "I(rA),rB",     "11 0x7  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sh), 0 },
{ "l.sh",      "I(rA),rB",     "11 0x7  IIIII AAAAA BBBB BIII IIII IIII", EF(l_sh), 0 },
Line 271... Line 274...
{ "l.sra",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
{ "l.sra",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 10-- 0x8", EF(l_sra), 0 },
{ "l.ror",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 11-- 0x8", EFI, 0 },
{ "l.ror",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 11-- 0x8", EFI, 0 },
{ "l.div",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x9", EF(l_div), 0 },
{ "l.div",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0x9", EF(l_div), 0 },
{ "l.divu",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xA", EF(l_divu), 0 },
{ "l.divu",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xA", EF(l_divu), 0 },
{ "l.mulu",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0xB", EFI, 0 },
{ "l.mulu",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-11 ---- 0xB", EFI, 0 },
{ "l.exths",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xC", EFI, 0 },
{ "l.exths",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 00-- 0xC", EFI, 0 },
{ "l.extbs",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xC", EFI, 0 },
{ "l.extbs",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 01-- 0xC", EFI, 0 },
{ "l.exthz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xC", EFI, 0 },
{ "l.exthz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 10-- 0xC", EFI, 0 },
{ "l.extbz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xC", EFI, 0 },
{ "l.extbz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 11-- 0xC", EFI, 0 },
{ "l.extws",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xD", EFI, 0 },
{ "l.extws",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 00-- 0xD", EFI, 0 },
{ "l.extwz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xD", EFI, 0 },
{ "l.extwz",   "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 01-- 0xD", EFI, 0 },
{ "l.cmov",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xE", EFI, 0 },
{ "l.cmov",    "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xE", EFI, 0 },
{ "l.ff1",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xF", EFI, 0 },
{ "l.ff1",     "rD,rA,rB",     "11 0x8  DDDDD AAAAA BBBB B-00 ---- 0xF", EFI, 0 },
 
 
{ "l.sfeq",    "rA,rB",        "11 0x9  00000 AAAAA BBBB B--- ---- ----", EF(l_sfeq), 0 },
{ "l.sfeq",    "rA,rB",        "11 0x9  00000 AAAAA BBBB B--- ---- ----", EF(l_sfeq), OR32_W_FLAG },
{ "l.sfne",    "rA,rB",        "11 0x9  00001 AAAAA BBBB B--- ---- ----", EF(l_sfne), 0 },
{ "l.sfne",    "rA,rB",        "11 0x9  00001 AAAAA BBBB B--- ---- ----", EF(l_sfne), OR32_W_FLAG },
{ "l.sfgtu",   "rA,rB",        "11 0x9  00010 AAAAA BBBB B--- ---- ----", EF(l_sfgtu), 0 },
{ "l.sfgtu",   "rA,rB",        "11 0x9  00010 AAAAA BBBB B--- ---- ----", EF(l_sfgtu), OR32_W_FLAG },
{ "l.sfgeu",   "rA,rB",        "11 0x9  00011 AAAAA BBBB B--- ---- ----", EF(l_sfgeu), 0 },
{ "l.sfgeu",   "rA,rB",        "11 0x9  00011 AAAAA BBBB B--- ---- ----", EF(l_sfgeu), OR32_W_FLAG },
{ "l.sfltu",   "rA,rB",        "11 0x9  00100 AAAAA BBBB B--- ---- ----", EF(l_sfltu), 0 },
{ "l.sfltu",   "rA,rB",        "11 0x9  00100 AAAAA BBBB B--- ---- ----", EF(l_sfltu), OR32_W_FLAG },
{ "l.sfleu",   "rA,rB",        "11 0x9  00101 AAAAA BBBB B--- ---- ----", EF(l_sfleu), 0 },
{ "l.sfleu",   "rA,rB",        "11 0x9  00101 AAAAA BBBB B--- ---- ----", EF(l_sfleu), OR32_W_FLAG },
{ "l.sfgts",   "rA,rB",        "11 0x9  01010 AAAAA BBBB B--- ---- ----", EF(l_sfgts), 0 },
{ "l.sfgts",   "rA,rB",        "11 0x9  01010 AAAAA BBBB B--- ---- ----", EF(l_sfgts), OR32_W_FLAG },
{ "l.sfges",   "rA,rB",        "11 0x9  01011 AAAAA BBBB B--- ---- ----", EF(l_sfges), 0 },
{ "l.sfges",   "rA,rB",        "11 0x9  01011 AAAAA BBBB B--- ---- ----", EF(l_sfges), OR32_W_FLAG },
{ "l.sflts",   "rA,rB",        "11 0x9  01100 AAAAA BBBB B--- ---- ----", EF(l_sflts), 0 },
{ "l.sflts",   "rA,rB",        "11 0x9  01100 AAAAA BBBB B--- ---- ----", EF(l_sflts), OR32_W_FLAG },
{ "l.sfles",   "rA,rB",        "11 0x9  01101 AAAAA BBBB B--- ---- ----", EF(l_sfles), 0 },
{ "l.sfles",   "rA,rB",        "11 0x9  01101 AAAAA BBBB B--- ---- ----", EF(l_sfles), OR32_W_FLAG },
 
 
{ "l.cust5",   "",             "11 0xC  ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust5",   "",             "11 0xC  ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust6",   "",             "11 0xD  ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust6",   "",             "11 0xD  ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust7",   "",             "11 0xE  ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust7",   "",             "11 0xE  ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8",   "",             "11 0xF  ----- ----- ---- ---- ---- ----", EFI, 0 },
{ "l.cust8",   "",             "11 0xF  ----- ----- ---- ---- ---- ----", EFI, 0 },
Line 309... Line 312...
 
 
/* **INDENT-ON** */
/* **INDENT-ON** */
 
 
CONST unsigned int num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1;
CONST unsigned int num_opcodes = ((sizeof(or32_opcodes)) / (sizeof(struct or32_opcode))) - 1;
 
 
/* Calculates instruction length in bytes. Either 2 or 4 for OR16
/* Calculates instruction length in bytes. Always 4 for OR32. */
   and always 4 for OR32. */
int
int insn_len(int insn_index)
insn_len(int insn_index)
{
{
#ifdef OR16
 
  char *enc;
 
  int len = 0;
 
 
 
  if (index < 0) {
 
    printf("insn_len(): Unknown instruction.\n");
 
    exit(1);
 
  } else {
 
    CONST struct or32_opcode *pinsn = or32_opcodes[ins_index];
 
    for (enc = pinsn->encoding; *enc != '\0'; enc++)
 
      if ((*enc == '0') && (*(enc+1) == 'x')) {
 
        len += 4;
 
        enc += 2;
 
      }
 
      else if (!isspace(*enc))
 
        len++;
 
    return len / 8;
 
  }
 
#else
 
  insn_index = 0; /* Just to get rid that warning.  */
  insn_index = 0; /* Just to get rid that warning.  */
  return 4;
  return 4;
#endif
 
}
}
 
 
/* Is individual insn's operand signed or unsigned? */
/* Is individual insn's operand signed or unsigned? */
int letter_signed(char l)
int
 
letter_signed(char l)
{
{
  CONST struct or32_letter *pletter;
  CONST struct or32_letter *pletter;
 
 
  for(pletter = or32_letters; pletter->letter != '\0'; pletter++)
  for(pletter = or32_letters; pletter->letter != '\0'; pletter++)
    if (pletter->letter == l)
    if (pletter->letter == l)
Line 351... Line 335...
  printf("letter_signed(%c): Unknown letter.\n", l);
  printf("letter_signed(%c): Unknown letter.\n", l);
  return 0;
  return 0;
}
}
 
 
/* Number of letters in the individual lettered operand. */
/* Number of letters in the individual lettered operand. */
int letter_range(char l)
int
 
letter_range(char l)
{
{
  CONST struct or32_opcode *pinsn;
  CONST struct or32_opcode *pinsn;
  char *enc;
  char *enc;
  int range = 0;
  int range = 0;
 
 
  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))
 
        {
      for (enc = pinsn->encoding; *enc != '\0'; enc++)
      for (enc = pinsn->encoding; *enc != '\0'; enc++)
        if ((*enc == '0') && (*(enc+1) == 'x')) {
            if ((*enc == '0') && (*(enc+1) == 'x'))
          enc += 2;
          enc += 2;
        }
 
        else if (*enc == l)
        else if (*enc == l)
          range++;
          range++;
      return range;
      return range;
    }
    }
  }
  }
  printf("\nABORT: letter_range(%c): Never used letter.\n", l);
  printf("\nABORT: letter_range(%c): Never used letter.\n", l);
  exit(1);
  exit(1);
}
}
 
 
/* MM: Returns index of given instruction name.  */
/* MM: Returns index of given instruction name.  */
int insn_index (char *insn) {
int
 
insn_index (char *insn)
 
{
  int i, found = -1;
  int i, found = -1;
  for (i = 0; (unsigned int)i < num_opcodes; i++)
  for (i = 0; (unsigned int)i < num_opcodes; i++)
    if (!strcmp (or32_opcodes[i].name, insn)) {
    if (!strcmp (or32_opcodes[i].name, insn))
 
      {
      found = i;
      found = i;
      break;
      break;
    }
    }
  return found;
  return found;
}
}
 
 
CONST char *insn_name(int index) {
CONST char *insn_name(int index)
 
{
  if (index >= 0 && (unsigned int)index < num_opcodes)
  if (index >= 0 && (unsigned int)index < num_opcodes)
    return or32_opcodes[index].name;
    return or32_opcodes[index].name;
  else
  else
    return "???";
    return "???";
}
}
 
 
void l_none() {
void l_none()
 
{
}
}
 
 
 
 
/*** Finite automata for instruction decoding building code ***/
/*** Finite automata for instruction decoding building code ***/
 
 
Line 410... Line 401...
  for (enc = enc_initial; *enc != '\0'; )
  for (enc = enc_initial; *enc != '\0'; )
    if ((*enc == '0') && (*(enc+1) == 'x'))
    if ((*enc == '0') && (*(enc+1) == 'x'))
      {
      {
        unsigned long tmp = strtol(enc+2, NULL, 16);
        unsigned long tmp = strtol(enc+2, NULL, 16);
        opc_pos -= 4;
        opc_pos -= 4;
 
        if (param_ch == '0' || param_ch == '1')
 
          {
        if (param_ch == '0')
        if (param_ch == '0')
          tmp = 15 - tmp;
          tmp = 15 - tmp;
        ret |= tmp << opc_pos;
        ret |= tmp << opc_pos;
 
          }
        enc += 3;
        enc += 3;
      }
      }
    else {
    else
      if (*enc == '0' || *enc == '1' || *enc == '-' || isalpha(*enc) ) {
      {
 
        if (*enc == '0' || *enc == '1' || *enc == '-' || isalpha(*enc) )
 
          {
        opc_pos--;
        opc_pos--;
        if (param_ch == *enc)
        if (param_ch == *enc)
          ret |= 1 << opc_pos;
          ret |= 1 << opc_pos;
      }
      }
      enc++;
      enc++;
    }
    }
  return ret;
  return ret;
}
}
 
 
struct temp_insn_struct {
#define MAX_AUTOMATA_SIZE (1200)
  unsigned long insn;
#define MAX_OP_TABLE_SIZE (1200)
  unsigned long insn_mask;
 
  int in_pass;
 
};
 
 
 
#define MAX_AUTOMATA_SIZE (1000)
 
#define LEAF_FLAG         (0x80000000)
#define LEAF_FLAG         (0x80000000)
#define MAX_LEN           (8)
#define MAX_LEN           (8)
 
 
#ifndef MIN
#ifndef MIN
# define MIN(x,y)          ((x) < (y) ? (x) : (y))
# define MIN(x,y)          ((x) < (y) ? (x) : (y))
Line 444... Line 435...
 
 
unsigned long *automata;
unsigned long *automata;
int nuncovered;
int nuncovered;
int curpass = 0;
int curpass = 0;
 
 
unsigned long *cover_insn (struct temp_insn_struct *ti, unsigned long *cur, int pass, unsigned int mask) {
/* MM: Struct that hold runtime build information about instructions.  */
 
struct temp_insn_struct
 
{
 
  unsigned long insn;
 
  unsigned long insn_mask;
 
  int in_pass;
 
} *ti;
 
 
 
struct insn_op_struct *op_data, **op_start;
 
 
 
/* Recursive utility function used to find best match and to build automata.  */
 
 
 
static unsigned long *
 
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;
  unsigned long *next;
  unsigned long *next;
 
 
  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)
 
      {
      cur_mask &= ti[i].insn_mask;
      cur_mask &= ti[i].insn_mask;
      ninstr++;
      ninstr++;
      last_match = i;
      last_match = i;
    }
    }
 
 
  printf ("%08X\n", cur_mask);
  debug("%08X %08X\n", mask, cur_mask);
  if (ninstr == 1) {
  if (ninstr == 0)
 
    return 0;
 
  if (ninstr == 1)
 
    {
    /* Leaf holds instruction index. */
    /* Leaf holds instruction index. */
    printf ("%i>I%i\n", cur - automata, last_match);
      debug("%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(" (%i(%08X & %08X>>%i = %08X, %08X)",len,m, cur_mask, i, (cur_mask >> (unsigned)i), (cur_mask >> (unsigned)i) & m);*/
        /*debug(" (%i(%08X & %08X>>%i = %08X, %08X)",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("!");*/
          /*debug("!");*/
        } else break;
                }
 
              else
 
                break;
      }
      }
    }
    }
    /*debug("\n");*/
    /*debug("\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++)
 
            if (ti[i].in_pass == pass)
 
              fprintf (stderr, "%s ", or32_opcodes[i].name);
 
 
 
          fprintf (stderr, "\n");
      exit (1);
      exit (1);
    }
    }
    printf ("%i> #### %i << %i (%i) ####\n", cur - automata, best_len, best_first, ninstr);
      debug("%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;
    /* Allocate space for pointers.  */
    /* Allocate space for pointers.  */
    cur += (1 << best_len) - 1;
      cur += 1 << best_len;
    cur_mask = 1 << ((unsigned long)best_len) - 1;
      cur_mask = (1 << (unsigned long)best_len) - 1;
 
 
    for (i = 0; i < (1 << best_len) - 1; i++) {
      for (i = 0; i < (1 << (unsigned long)best_len); i++)
 
        {
      int j;
      int j;
 
          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) == i
            && ((ti[j].insn >> best_first) & cur_mask) == 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;
        }
 
      printf ("%i> #%X -> %u\n", next - automata, i, cur - automata);
          /*debug("%08X %08X %i\n", mask, cur_mask, best_first);*/
 
          c = cover_insn (cur, curpass, mask & (~(cur_mask << best_first)));
 
          if (c)
 
            {
 
              debug("%i> #%X -> %u\n", next - automata, i, cur - automata);
      *next = cur - automata;
      *next = cur - automata;
 
              cur = c;
 
            }
 
          else
 
            {
 
              debug("%i> N/A\n", next - automata);
 
              *next = 0;
 
            }
      next++;
      next++;
      cur = cover_insn (ti, cur, curpass, mask & ~cur_mask);
 
    }
    }
  }
  }
  return cur;
  return cur;
}
}
 
 
void build_automata() {
/* Returns number of nonzero bits. */
 
static int
 
num_ones (unsigned long value)
 
{
 
  int c = 0;
 
  while (value)
 
    {
 
      if (value & 1)
 
        c++;
 
      value >>= 1;
 
    }
 
  return c;
 
}
 
 
 
/* Utility function, which converts parameters from or32_opcode format to more binary form.
 
   Parameters are stored in ti struct.  */
 
 
 
static struct insn_op_struct *
 
parse_params (CONST struct or32_opcode *opcode, struct insn_op_struct *cur)
 
{
 
  char *args = opcode->args;
 
  int i, type;
 
 
 
  i = 0;
 
  type = 0;
 
  while (*args != '\0')
 
    {
 
      if (*args == 'r')
 
        {
 
          args++;
 
          type |= OPTYPE_REG;
 
        }
 
      else if (isalpha (*args))
 
        {
 
          unsigned long arg;
 
          arg = insn_extract(*args, opcode->encoding);
 
          debug("%s : %08X ------\n", opcode->name, arg);
 
          if (letter_signed (*args))
 
            {
 
              type |= OPTYPE_SIG;
 
              type |= ((num_ones (arg) - 1) << OPTYPE_SBIT_SHR) & OPTYPE_SBIT;
 
            }
 
 
 
          /* Split argument to sequences of consecutive ones.  */
 
          while (arg)
 
            {
 
              int shr = 0;
 
              unsigned long tmp = arg, mask = 0;
 
              while ((tmp & 1) == 0)
 
                {
 
                  shr++;
 
                  tmp >>= 1;
 
                }
 
              while (tmp & 1)
 
                {
 
                  mask++;
 
                  tmp >>= 1;
 
                }
 
              cur->type = type | shr;
 
              cur->data = mask;
 
              arg &= ~(((1 << mask) - 1) << shr);
 
              debug("|%08X %08X\n", cur->type, cur->data);
 
              cur++;
 
            }
 
          args++;
 
        }
 
      else if (*args == '(')
 
        {
 
          /* Next param is displacement.  Later we will treat them as one operand.  */
 
          cur--;
 
          cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP;
 
          debug(">%08X %08X\n", cur->type, cur->data);
 
          cur++;
 
          type = 0;
 
          i++;
 
          args++;
 
        }
 
      else if (*args == OPERAND_DELIM)
 
        {
 
          cur--;
 
          cur->type = type | cur->type | OPTYPE_OP;
 
          debug(">%08X %08X\n", cur->type, cur->data);
 
          cur++;
 
          type = 0;
 
          i++;
 
          args++;
 
        }
 
      else if (*args == '0')
 
        {
 
          cur->type = type;
 
          cur->data = 0;
 
          debug(">%08X %08X\n", cur->type, cur->data);
 
          cur++;
 
          type = 0;
 
          i++;
 
          args++;
 
        }
 
      else if (*args == ')')
 
        args++;
 
      else
 
        {
 
          fprintf (stderr, "%s : parse error in args.\n", opcode->name);
 
          exit (1);
 
        }
 
    }
 
  cur--;
 
  cur->type = type | cur->type | OPTYPE_OP | OPTYPE_LAST;
 
  debug("#%08X %08X\n", cur->type, cur->data);
 
  cur++;
 
  return cur;
 
}
 
 
 
/* Constructs new automata based on or32_opcodes array.  */
 
 
 
void
 
build_automata()
 
{
  int i, j;
  int i, j;
  struct temp_insn_struct *ti = (struct temp_insn_struct *) malloc (sizeof (struct temp_insn_struct) * num_opcodes);
 
  unsigned long *end;
  unsigned long *end;
 
  struct insn_op_struct *cur;
 
 
  automata = (unsigned long *) malloc (MAX_AUTOMATA_SIZE * sizeof (unsigned long));
  automata = (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;
  printf ("Building automata.\n");
  printf("Building automata... ");
  /* Build temporary information about instructions.  */
  /* Build temporary information about instructions.  */
  for (i = 0; i < num_opcodes; i++) {
  for (i = 0; i < num_opcodes; i++)
 
    {
    unsigned long ones, zeros;
    unsigned long ones, zeros;
    char *encoding = or32_opcodes[i].encoding;
    char *encoding = or32_opcodes[i].encoding;
    ones  = insn_extract('1', encoding);
    ones  = insn_extract('1', encoding);
    zeros = insn_extract('0', encoding);
    zeros = insn_extract('0', encoding);
    ti[i].insn_mask = ones | zeros;
    ti[i].insn_mask = ones | zeros;
    ti[i].insn = ones;
    ti[i].insn = ones;
    ti[i].in_pass = curpass = 0;
    ti[i].in_pass = curpass = 0;
    /*printf ("%s: %s %08X %08X\n", or32_opcodes[i].name, or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn);*/
      /*debug("%s: %s %08X %08X\n", or32_opcodes[i].name,
 
        or32_opcodes[i].encoding, ti[i].insn_mask, ti[i].insn);*/
  }
  }
 
 
  /* Until all are covered search for best criteria to separate them.  */
  /* Until all are covered search for best criteria to separate them.  */
  end = cover_insn (ti, automata, curpass, 0xFFFFFFFF);
  end = cover_insn (automata, curpass, 0xFFFFFFFF);
  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);
  }
  }
  printf ("Num uncovered: %i/%i\n", nuncovered, num_opcodes);
  printf("done, num uncovered: %i/%i.\n", nuncovered, num_opcodes);
  free (ti);
 
 
  printf("Parsing operands data... ");
 
  op_data = (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;
 
  for (i = 0; i < num_opcodes; i++)
 
    {
 
      op_start[i] = cur;
 
      cur = parse_params (&or32_opcodes[i], cur);
 
      if (cur - op_data > MAX_OP_TABLE_SIZE)
 
        {
 
          fprintf (stderr, "Operands table too small, increase MAX_OP_TABLE_SIZE.\n");
 
          exit (1);
 
        }
 
    }
 
  printf("done.\n");
}
}
 
 
void destruct_automata () {
void destruct_automata ()
 
{
 
  free (ti);
  free (automata);
  free (automata);
 
  free (op_data);
 
  free (op_start);
}
}
 
 
/* Decodes instruction and returns instruction index.  */
/* Decodes instruction and returns instruction index.  */
int decode_insn (unsigned int insn) {
int insn_decode (unsigned int insn)
 
{
  unsigned long *a = automata;
  unsigned long *a = automata;
  while (!(*a & LEAF_FLAG)) {
  int i;
    unsigned int first = *a, mask;
  while (!(*a & LEAF_FLAG))
 
    {
 
      unsigned int first = *a;
 
      debug("%i ", a - automata);
    a++;
    a++;
    mask = (1 << *a) - 1;
      i = (insn >> first) & *a;
    a++;
    a++;
    a += (insn >> first) & mask;
      if (!*(a + i))
    a = automata + *a;
        { /* Invalid instruction found?  */
  }
          debug("XXX\n", i);
  return *a & ~LEAF_FLAG;
          return -1;
 
        }
 
      a = automata + *(a + i);
 
    }
 
  i = *a & ~LEAF_FLAG;
 
  debug("%i\n", i);
 
  /* Final check - do we have direct match?
 
     (based on or32_opcodes this should be the only possibility,
 
     but in case of invalid/missing instruction we must perform a check)  */
 
  if ((ti[i].insn_mask & insn) == ti[i].insn)
 
    return i;
 
  else
 
    return -1;
}
}
 
 
/* Parses and returns operand. */
 
/*unsigned int eval_operand (int insn_index, int operand) {
 
  return 0;
 
  }*/
 
 
 
 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.