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

Subversion Repositories or2k

[/] [or2k/] [trunk/] [analysis-bin/] [insnanalysis/] [or1k-32-insn.c] - Diff between revs 21 and 22

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 21 Rev 22
/*
/*
  Or1K instruction set-specific decoding and analysis functions.
  Or1K instruction set-specific decoding and analysis functions.
 
 
  Julius Baxter, julius.baxter@orsoc.se
  Julius Baxter, julius.baxter@orsoc.se
 
 
*/
*/
 
 
 
 
#include "stdio.h"
#include "stdio.h"
#include "stdint.h"
#include "stdint.h"
#include "stdlib.h"
#include "stdlib.h"
#include "string.h"
#include "string.h"
#include "assert.h"
#include "assert.h"
#include "or1k-32-insn.h"
#include "or1k-32-insn.h"
 
 
// These should also be in insnanalysis.h insnanalysis.h
// Define the appropriate instruction type, and instruction_properties type
 
// These should also be defined in insnanalysis.h
typedef uint32_t instruction;
typedef uint32_t instruction;
typedef struct or1k_32_instruction_properties instruction_properties ;
typedef struct or1k_32_instruction_properties instruction_properties ;
 
 
#include "insn-lists.h"
#include "insn-lists.h"
 
 
 
// Enable debug printf'ing straight to stdout -- will be a LOT of output
#define DEBUG_PRINT 0
#define DEBUG_PRINT 0
 
 
 
// Choose the output format, uncomment only one
 
//#define DISPLAY_STRING
 
#define DISPLAY_CSV
 
 
 
 
// Variable to keep track of unique instructions we have
// Variable to keep track of unique instructions we have
int num_setup_insns;
int num_setup_insns;
int num_seen_insns;
int num_seen_insns;
 
 
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
 
 
// Keep enough instructions required to do the maximum n-tuple set
// Keep enough instructions required to do the maximum n-tuple set
// analysis.
// analysis.
int or1k_32_recent_insns[OR1K_MAX_GROUPINGS_ANALYSIS];
int or1k_32_recent_insns[OR1K_MAX_GROUPINGS_ANALYSIS];
 
 
 
// Function to take the raw binary instruction, and configure the insn_props
 
// struct with the appropriate settings for that instruction (string, attributes
 
// etc.)
 
// TODO: vector instructions aren't picked up - but compiler never generates
 
// them, so not a big issue.
int or1k_32_analyse_insn(uint32_t insn,
int or1k_32_analyse_insn(uint32_t insn,
                         struct or1k_32_instruction_properties  * insn_props)
                         struct or1k_32_instruction_properties  * insn_props)
{
{
 
 
  switch(insn_or1k_opcode(insn))
  switch(insn_or1k_opcode(insn))
    {
    {
    case 0x00:
    case 0x00:
      insn_props->insn_string="l.j";
      insn_props->insn_string="l.j";
      insn_props->insn_index=0;
      insn_props->insn_index=0;
      insn_props->has_jumptarg = 1;
      insn_props->has_jumptarg = 1;
      break;
      break;
 
 
    case 0x01:
    case 0x01:
      insn_props->insn_string="l.jal";
      insn_props->insn_string="l.jal";
      insn_props->insn_index=1;
      insn_props->insn_index=1;
      insn_props->has_jumptarg = 1;
      insn_props->has_jumptarg = 1;
      break;
      break;
 
 
     case 0x03:
     case 0x03:
      insn_props->insn_string="l.bnf";
      insn_props->insn_string="l.bnf";
      insn_props->insn_index=2;
      insn_props->insn_index=2;
      insn_props->has_branchtarg = 1;
      insn_props->has_branchtarg = 1;
      break;
      break;
 
 
    case 0x04:
    case 0x04:
      insn_props->insn_string="l.bf";
      insn_props->insn_string="l.bf";
      insn_props->insn_index=3;
      insn_props->insn_index=3;
      insn_props->has_branchtarg = 1;
      insn_props->has_branchtarg = 1;
      break;
      break;
 
 
    case 0x05:
    case 0x05:
      insn_props->insn_string="l.nop";
      insn_props->insn_string="l.nop";
      insn_props->insn_index=4;
      insn_props->insn_index=4;
      break;
      break;
 
 
    case 0x06:
    case 0x06:
      if((insn_or1k_opcode_0x06_get_id(insn)))
      if((insn_or1k_opcode_0x06_get_id(insn)))
        {
        {
          insn_props->insn_string="l.macrc";
          insn_props->insn_string="l.macrc";
          insn_props->insn_index=5;
          insn_props->insn_index=5;
        }
        }
      else
      else
        {
        {
          insn_props->insn_string="l.movhi";
          insn_props->insn_string="l.movhi";
          insn_props->insn_index=6;
          insn_props->insn_index=6;
          insn_props->has_rD = 1;
          insn_props->has_rD = 1;
          insn_props->has_imm = 1;
          insn_props->has_imm = 1;
        }
        }
 
 
      break;
      break;
 
 
    case 0x08:
    case 0x08:
 
 
      switch(insn_or1k_opcode_0x08_get_id(insn))
      switch(insn_or1k_opcode_0x08_get_id(insn))
        {
        {
        case 0x0:
        case 0x0:
          insn_props->insn_string="l.sys";
          insn_props->insn_string="l.sys";
          insn_props->insn_index=7;
          insn_props->insn_index=7;
          insn_props->has_imm = 1;
          insn_props->has_imm = 1;
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.trap";
          insn_props->insn_string="l.trap";
          insn_props->insn_index=8;
          insn_props->insn_index=8;
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.msync";
          insn_props->insn_string="l.msync";
          insn_props->insn_index=9;
          insn_props->insn_index=9;
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.psync";
          insn_props->insn_string="l.psync";
          insn_props->insn_index=10;
          insn_props->insn_index=10;
          break;
          break;
        case 0x6:
        case 0x6:
          insn_props->insn_string="l.csync";
          insn_props->insn_string="l.csync";
          insn_props->insn_index=11;
          insn_props->insn_index=11;
          break;
          break;
        default:
        default:
          printf("Unknown id (0x%x) in opcode 0x8",
          printf("Unknown id (0x%x) in opcode 0x8",
                 insn_or1k_opcode_0x08_get_id(insn) );
                 insn_or1k_opcode_0x08_get_id(insn) );
          return 1;
          return 1;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x09:
    case 0x09:
      insn_props->insn_string="l.rfe";
      insn_props->insn_string="l.rfe";
      insn_props->insn_index=12;
      insn_props->insn_index=12;
      break;
      break;
 
 
    case 0x0a:
    case 0x0a:
      switch(insn_or1k_opcode_0x0a_get_op_hi(insn))
      switch(insn_or1k_opcode_0x0a_get_op_hi(insn))
        {
        {
        case 0x1:
        case 0x1:
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              break;
              break;
            case 0x1:
            case 0x1:
              break;
              break;
            case 0x2:
            case 0x2:
              break;
              break;
            case 0x3:
            case 0x3:
              break;
              break;
            case 0x4:
            case 0x4:
              break;
              break;
            case 0x5:
            case 0x5:
              break;
              break;
            case 0x6:
            case 0x6:
              break;
              break;
            case 0x7:
            case 0x7:
              break;
              break;
            case 0x8:
            case 0x8:
              break;
              break;
            case 0x9:
            case 0x9:
              break;
              break;
            case 0xa:
            case 0xa:
              break;
              break;
            case 0xb:
            case 0xb:
              break;
              break;
            default:
            default:
              printf("Unknown lv.all_xx insn");
              printf("Unknown lv.all_xx insn");
              return 1;
              return 1;
            }
            }
        case 0x2:
        case 0x2:
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              break;
              break;
            case 0x1:
            case 0x1:
              break;
              break;
            case 0x2:
            case 0x2:
              break;
              break;
            case 0x3:
            case 0x3:
              break;
              break;
            case 0x4:
            case 0x4:
              break;
              break;
            case 0x5:
            case 0x5:
              break;
              break;
            case 0x6:
            case 0x6:
              break;
              break;
            case 0x7:
            case 0x7:
              break;
              break;
            case 0x8:
            case 0x8:
              break;
              break;
            case 0x9:
            case 0x9:
              break;
              break;
            case 0xa:
            case 0xa:
              break;
              break;
            case 0xb:
            case 0xb:
              break;
              break;
            default:
            default:
              printf("Unknown lv.any_xx insn");
              printf("Unknown lv.any_xx insn");
              return 1;
              return 1;
            }
            }
          break;
          break;
        case 0x3:
        case 0x3:
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              break;
              break;
            case 0x1:
            case 0x1:
              break;
              break;
            case 0x2:
            case 0x2:
              break;
              break;
            case 0x3:
            case 0x3:
              break;
              break;
            case 0x4:
            case 0x4:
              break;
              break;
            case 0x5:
            case 0x5:
              break;
              break;
            case 0x6:
            case 0x6:
              break;
              break;
            case 0x7:
            case 0x7:
              break;
              break;
            case 0x8:
            case 0x8:
              break;
              break;
            case 0x9:
            case 0x9:
              break;
              break;
            case 0xa:
            case 0xa:
              break;
              break;
            default:
            default:
              printf("Unknown lv.add/and/avg_xx insn");
              printf("Unknown lv.add/and/avg_xx insn");
              return 1;
              return 1;
            }
            }
          break;
          break;
        case 0x4:
        case 0x4:
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              break;
              break;
            case 0x1:
            case 0x1:
              break;
              break;
            case 0x2:
            case 0x2:
              break;
              break;
            case 0x3:
            case 0x3:
              break;
              break;
            case 0x4:
            case 0x4:
              break;
              break;
            case 0x5:
            case 0x5:
              break;
              break;
            case 0x6:
            case 0x6:
              break;
              break;
            case 0x7:
            case 0x7:
              break;
              break;
            case 0x8:
            case 0x8:
              break;
              break;
            case 0x9:
            case 0x9:
              break;
              break;
            case 0xa:
            case 0xa:
              break;
              break;
            case 0xb:
            case 0xb:
              break;
              break;
            default:
            default:
              printf("Unknown lv.cmp_xx insn");
              printf("Unknown lv.cmp_xx insn");
              return 1;
              return 1;
            }
            }
          break;
          break;
        case 0x5:
        case 0x5:
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
            {
            {
            case 0x4:
            case 0x4:
              break;
              break;
            case 0x5:
            case 0x5:
              break;
              break;
            case 0x6:
            case 0x6:
              break;
              break;
            case 0x7:
            case 0x7:
              break;
              break;
            case 0x8:
            case 0x8:
              break;
              break;
            case 0x9:
            case 0x9:
              break;
              break;
            case 0xa:
            case 0xa:
              break;
              break;
            case 0xb:
            case 0xb:
              break;
              break;
            case 0xc:
            case 0xc:
              break;
              break;
            case 0xd:
            case 0xd:
              break;
              break;
            case 0xe:
            case 0xe:
              break;
              break;
            case 0xf:
            case 0xf:
              break;
              break;
            default:
            default:
              printf("Unknown lv.alu_xx insn");
              printf("Unknown lv.alu_xx insn");
              return 1;
              return 1;
            }
            }
          break;
          break;
        case 0x6:
        case 0x6:
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              break;
              break;
            case 0x1:
            case 0x1:
              break;
              break;
            case 0x2:
            case 0x2:
              break;
              break;
            case 0x3:
            case 0x3:
              break;
              break;
            case 0x4:
            case 0x4:
              break;
              break;
            case 0x5:
            case 0x5:
              break;
              break;
            case 0x6:
            case 0x6:
              break;
              break;
            case 0x7:
            case 0x7:
              break;
              break;
            case 0x8:
            case 0x8:
              break;
              break;
            case 0x9:
            case 0x9:
              break;
              break;
            case 0xa:
            case 0xa:
              break;
              break;
            case 0xb:
            case 0xb:
              break;
              break;
            case 0xc:
            case 0xc:
              break;
              break;
            case 0xd:
            case 0xd:
              break;
              break;
            case 0xe:
            case 0xe:
              break;
              break;
            case 0xf:
            case 0xf:
              break;
              break;
            default:
            default:
              printf("Unknown lv.pack_xx insn");
              printf("Unknown lv.pack_xx insn");
              return 1;
              return 1;
            }
            }
          break;
          break;
        case 0x7:
        case 0x7:
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              break;
              break;
            case 0x1:
            case 0x1:
              break;
              break;
            case 0x2:
            case 0x2:
              break;
              break;
            case 0x3:
            case 0x3:
              break;
              break;
            case 0x4:
            case 0x4:
              break;
              break;
            case 0x5:
            case 0x5:
              break;
              break;
            case 0x6:
            case 0x6:
              break;
              break;
            case 0x7:
            case 0x7:
              break;
              break;
            case 0x8:
            case 0x8:
              break;
              break;
            case 0x9:
            case 0x9:
              break;
              break;
            case 0xa:
            case 0xa:
              break;
              break;
            case 0xb:
            case 0xb:
              break;
              break;
            default:
            default:
              printf("Unknown lv.sub/unpack/xor_xx insn");
              printf("Unknown lv.sub/unpack/xor_xx insn");
              return 1;
              return 1;
            }
            }
          break;
          break;
        case 0xc:
        case 0xc:
          break;
          break;
        case 0xd:
        case 0xd:
          break;
          break;
        case 0xe:
        case 0xe:
          break;
          break;
        case 0xf:
        case 0xf:
          break;
          break;
        default:
        default:
          printf("Unknown lv.xxx insn hi op");
          printf("Unknown lv.xxx insn hi op");
          return 1;
          return 1;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x11:
    case 0x11:
      insn_props->insn_string="l.jr";
      insn_props->insn_string="l.jr";
      insn_props->insn_index=13;
      insn_props->insn_index=13;
      insn_props->has_rB = 1;
      insn_props->has_rB = 1;
      break;
      break;
 
 
    case 0x12:
    case 0x12:
      insn_props->insn_string="l.jalr";
      insn_props->insn_string="l.jalr";
      insn_props->insn_index=14;
      insn_props->insn_index=14;
      insn_props->has_rB = 1;
      insn_props->has_rB = 1;
      break;
      break;
 
 
    case 0x13:
    case 0x13:
      insn_props->insn_string="l.maci";
      insn_props->insn_string="l.maci";
      insn_props->insn_index=15;
      insn_props->insn_index=15;
      break;
      break;
 
 
    case 0x1c:
    case 0x1c:
      insn_props->insn_string="l.cust1";
      insn_props->insn_string="l.cust1";
      insn_props->insn_index=16;
      insn_props->insn_index=16;
      break;
      break;
 
 
    case 0x1d:
    case 0x1d:
      insn_props->insn_string="l.cust2";
      insn_props->insn_string="l.cust2";
      insn_props->insn_index=17;
      insn_props->insn_index=17;
      break;
      break;
 
 
    case 0x1e:
    case 0x1e:
      insn_props->insn_string="l.cust3";
      insn_props->insn_string="l.cust3";
      insn_props->insn_index=18;
      insn_props->insn_index=18;
      break;
      break;
 
 
    case 0x1f:
    case 0x1f:
      insn_props->insn_string="l.cust4";
      insn_props->insn_string="l.cust4";
      insn_props->insn_index=19;
      insn_props->insn_index=19;
      break;
      break;
 
 
    case 0x20:
    case 0x20:
      insn_props->insn_string="l.ld";
      insn_props->insn_string="l.ld";
      insn_props->insn_index=20;
      insn_props->insn_index=20;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x21:
    case 0x21:
      insn_props->insn_string="l.lwz";
      insn_props->insn_string="l.lwz";
      insn_props->insn_index=21;
      insn_props->insn_index=21;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x22:
    case 0x22:
      insn_props->insn_string="l.lws";
      insn_props->insn_string="l.lws";
      insn_props->insn_index=22;
      insn_props->insn_index=22;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x23:
    case 0x23:
      insn_props->insn_string="l.lbz";
      insn_props->insn_string="l.lbz";
      insn_props->insn_index=23;
      insn_props->insn_index=23;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x24:
    case 0x24:
      insn_props->insn_string="l.lbs";
      insn_props->insn_string="l.lbs";
      insn_props->insn_index=24;
      insn_props->insn_index=24;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x25:
    case 0x25:
      insn_props->insn_string="l.lhz";
      insn_props->insn_string="l.lhz";
      insn_props->insn_index=25;
      insn_props->insn_index=25;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x26:
    case 0x26:
      insn_props->insn_string="l.lhs";
      insn_props->insn_string="l.lhs";
      insn_props->insn_index=26;
      insn_props->insn_index=26;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
 
 
    case 0x27:
    case 0x27:
      insn_props->insn_string="l.addi";
      insn_props->insn_string="l.addi";
      insn_props->insn_index=27;
      insn_props->insn_index=27;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x28:
    case 0x28:
      insn_props->insn_string="l.addic";
      insn_props->insn_string="l.addic";
      insn_props->insn_index=28;
      insn_props->insn_index=28;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x29:
    case 0x29:
      insn_props->insn_string="l.andi";
      insn_props->insn_string="l.andi";
      insn_props->insn_index=29;
      insn_props->insn_index=29;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x2a:
    case 0x2a:
      insn_props->insn_string="l.ori";
      insn_props->insn_string="l.ori";
      insn_props->insn_index=30;
      insn_props->insn_index=30;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x2b:
    case 0x2b:
      insn_props->insn_string="l.xori";
      insn_props->insn_string="l.xori";
      insn_props->insn_index=31;
      insn_props->insn_index=31;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x2c:
    case 0x2c:
      insn_props->insn_string="l.muli";
      insn_props->insn_string="l.muli";
      insn_props->insn_index=32;
      insn_props->insn_index=32;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x2d:
    case 0x2d:
      insn_props->insn_string="l.mfspr";
      insn_props->insn_string="l.mfspr";
      insn_props->insn_index=33;
      insn_props->insn_index=33;
      insn_props->has_rD = 1;
      insn_props->has_rD = 1;
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
    case 0x2e:
    case 0x2e:
      switch(insn_or1k_opcode_0x2e_get_op(insn))
      switch(insn_or1k_opcode_0x2e_get_op(insn))
        {
        {
        case 0x0:
        case 0x0:
          insn_props->insn_string="l.slli";
          insn_props->insn_string="l.slli";
          insn_props->insn_index=34;
          insn_props->insn_index=34;
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.srli";
          insn_props->insn_string="l.srli";
          insn_props->insn_index=35;
          insn_props->insn_index=35;
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.srai";
          insn_props->insn_string="l.srai";
          insn_props->insn_index=36;
          insn_props->insn_index=36;
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.rori";
          insn_props->insn_string="l.rori";
          insn_props->insn_index=37;
          insn_props->insn_index=37;
          break;
          break;
        default:
        default:
          printf("Unknown shift op (0x%x)",
          printf("Unknown shift op (0x%x)",
                 insn_or1k_opcode_0x2e_get_op(insn));
                 insn_or1k_opcode_0x2e_get_op(insn));
          return 1;
          return 1;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x2f:
    case 0x2f:
      switch(insn_or1k_opcode_0x2f_get_op(insn))
      switch(insn_or1k_opcode_0x2f_get_op(insn))
        {
        {
        case 0x0:
        case 0x0:
          insn_props->insn_string="l.sfeqi";
          insn_props->insn_string="l.sfeqi";
          insn_props->insn_index=38;
          insn_props->insn_index=38;
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.sfnei";
          insn_props->insn_string="l.sfnei";
          insn_props->insn_index=39;
          insn_props->insn_index=39;
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.sfgtui";
          insn_props->insn_string="l.sfgtui";
          insn_props->insn_index=40;
          insn_props->insn_index=40;
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.sfgeui";
          insn_props->insn_string="l.sfgeui";
          insn_props->insn_index=41;
          insn_props->insn_index=41;
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.sfltui";
          insn_props->insn_string="l.sfltui";
          insn_props->insn_index=42;
          insn_props->insn_index=42;
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.sfleui";
          insn_props->insn_string="l.sfleui";
          insn_props->insn_index=43;
          insn_props->insn_index=43;
          break;
          break;
        case 0xa:
        case 0xa:
          insn_props->insn_string="l.sfgtsi";
          insn_props->insn_string="l.sfgtsi";
          insn_props->insn_index=44;
          insn_props->insn_index=44;
          break;
          break;
        case 0xb:
        case 0xb:
          insn_props->insn_string="l.sfgesi";
          insn_props->insn_string="l.sfgesi";
          insn_props->insn_index=45;
          insn_props->insn_index=45;
          break;
          break;
        case 0xc:
        case 0xc:
          insn_props->insn_string="l.sfltsi";
          insn_props->insn_string="l.sfltsi";
          insn_props->insn_index=46;
          insn_props->insn_index=46;
          break;
          break;
        case 0xd:
        case 0xd:
          insn_props->insn_string="l.sflesi";
          insn_props->insn_string="l.sflesi";
          insn_props->insn_index=47;
          insn_props->insn_index=47;
          break;
          break;
 
 
        default:
        default:
          printf("Unknown set flag op (0x%x)",
          printf("Unknown set flag op (0x%x)",
                 insn_or1k_opcode_0x2f_get_op(insn));
                 insn_or1k_opcode_0x2f_get_op(insn));
          return 1;
          return 1;
          break;
          break;
        }
        }
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_imm = 1;
      insn_props->has_imm = 1;
      break;
      break;
 
 
 
 
    case 0x30:
    case 0x30:
      insn_props->insn_string="l.mtspr";
      insn_props->insn_string="l.mtspr";
      insn_props->insn_index=48;
      insn_props->insn_index=48;
      break;
      break;
 
 
    case 0x31:
    case 0x31:
      switch (insn_or1k_opcode_0x31_get_op(insn))
      switch (insn_or1k_opcode_0x31_get_op(insn))
        {
        {
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.mac";
          insn_props->insn_string="l.mac";
          insn_props->insn_index=49;
          insn_props->insn_index=49;
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.msb";
          insn_props->insn_string="l.msb";
          insn_props->insn_index=50;
          insn_props->insn_index=50;
          break;
          break;
        default:
        default:
          printf("Unknown mac op (0x%x)",
          printf("Unknown mac op (0x%x)",
                 insn_or1k_opcode_0x31_get_op(insn));
                 insn_or1k_opcode_0x31_get_op(insn));
          return 1;
          return 1;
        }
        }
      break;
      break;
 
 
    case 0x32:
    case 0x32:
      switch(insn_or1k_opcode_0x32_get_op_hi(insn))
      switch(insn_or1k_opcode_0x32_get_op_hi(insn))
        {
        {
        case 0x0:
        case 0x0:
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              insn_props->insn_string="lf.add.s";
              insn_props->insn_string="lf.add.s";
              insn_props->insn_index=51;
              insn_props->insn_index=51;
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="lf.sub.s";
              insn_props->insn_string="lf.sub.s";
              insn_props->insn_index=52;
              insn_props->insn_index=52;
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="lf.mul.s";
              insn_props->insn_string="lf.mul.s";
              insn_props->insn_index=53;
              insn_props->insn_index=53;
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="lf.div.s";
              insn_props->insn_string="lf.div.s";
              insn_props->insn_index=54;
              insn_props->insn_index=54;
              break;
              break;
            case 0x4:
            case 0x4:
              insn_props->insn_string="lf.itof.s";
              insn_props->insn_string="lf.itof.s";
              insn_props->insn_index=55;
              insn_props->insn_index=55;
              break;
              break;
            case 0x5:
            case 0x5:
              insn_props->insn_string="lf.ftoi.s";
              insn_props->insn_string="lf.ftoi.s";
              insn_props->insn_index=56;
              insn_props->insn_index=56;
              break;
              break;
            case 0x6:
            case 0x6:
              insn_props->insn_string="lf.rem.s";
              insn_props->insn_string="lf.rem.s";
              insn_props->insn_index=57;
              insn_props->insn_index=57;
              break;
              break;
            case 0x7:
            case 0x7:
              insn_props->insn_string="lf.madd.s";
              insn_props->insn_string="lf.madd.s";
              insn_props->insn_index=58;
              insn_props->insn_index=58;
              break;
              break;
            case 0x8:
            case 0x8:
              insn_props->insn_string="lf.sfeq.s";
              insn_props->insn_string="lf.sfeq.s";
              insn_props->insn_index=59;
              insn_props->insn_index=59;
              break;
              break;
            case 0x9:
            case 0x9:
              insn_props->insn_string="lf.sfne.s";
              insn_props->insn_string="lf.sfne.s";
              insn_props->insn_index=60;
              insn_props->insn_index=60;
              break;
              break;
            case 0xa:
            case 0xa:
              insn_props->insn_string="lf.sfgt.s";
              insn_props->insn_string="lf.sfgt.s";
              insn_props->insn_index=61;
              insn_props->insn_index=61;
              break;
              break;
            case 0xb:
            case 0xb:
              insn_props->insn_string="lf.sfge.s";
              insn_props->insn_string="lf.sfge.s";
              insn_props->insn_index=62;
              insn_props->insn_index=62;
              break;
              break;
            case 0xc:
            case 0xc:
              insn_props->insn_string="lf.sflt.s";
              insn_props->insn_string="lf.sflt.s";
              insn_props->insn_index=63;
              insn_props->insn_index=63;
              break;
              break;
            case 0xd:
            case 0xd:
              insn_props->insn_string="lf.sfle.s";
              insn_props->insn_string="lf.sfle.s";
              insn_props->insn_index=64;
              insn_props->insn_index=64;
              break;
              break;
            default:
            default:
              printf("Unknown lf.xxx.s op (0x%x)",
              printf("Unknown lf.xxx.s op (0x%x)",
                     insn_or1k_opcode_0x32_get_op_lo(insn));
                     insn_or1k_opcode_0x32_get_op_lo(insn));
              break;
              break;
            }
            }
          break;
          break;
 
 
        case 0x1:
        case 0x1:
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
            {
            {
            case 0x0:
            case 0x0:
              insn_props->insn_string="lf.add.d";
              insn_props->insn_string="lf.add.d";
              insn_props->insn_index=65;
              insn_props->insn_index=65;
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="lf.sub.d";
              insn_props->insn_string="lf.sub.d";
              insn_props->insn_index=66;
              insn_props->insn_index=66;
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="lf.mul.d";
              insn_props->insn_string="lf.mul.d";
              insn_props->insn_index=67;
              insn_props->insn_index=67;
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="lf.div.d";
              insn_props->insn_string="lf.div.d";
              insn_props->insn_index=68;
              insn_props->insn_index=68;
              break;
              break;
            case 0x4:
            case 0x4:
              insn_props->insn_string="lf.itof.d";
              insn_props->insn_string="lf.itof.d";
              insn_props->insn_index=69;
              insn_props->insn_index=69;
              break;
              break;
            case 0x5:
            case 0x5:
              insn_props->insn_string="lf.ftoi.d";
              insn_props->insn_string="lf.ftoi.d";
              insn_props->insn_index=70;
              insn_props->insn_index=70;
              break;
              break;
            case 0x6:
            case 0x6:
              insn_props->insn_string="lf.rem.d";
              insn_props->insn_string="lf.rem.d";
              insn_props->insn_index=71;
              insn_props->insn_index=71;
              break;
              break;
            case 0x7:
            case 0x7:
              insn_props->insn_string="lf.madd.d";
              insn_props->insn_string="lf.madd.d";
              insn_props->insn_index=72;
              insn_props->insn_index=72;
              break;
              break;
            case 0x8:
            case 0x8:
              insn_props->insn_string="lf.sfeq.d";
              insn_props->insn_string="lf.sfeq.d";
              insn_props->insn_index=73;
              insn_props->insn_index=73;
              break;
              break;
            case 0x9:
            case 0x9:
              insn_props->insn_string="lf.sfne.d";
              insn_props->insn_string="lf.sfne.d";
              insn_props->insn_index=74;
              insn_props->insn_index=74;
              break;
              break;
            case 0xa:
            case 0xa:
              insn_props->insn_string="lf.sfgt.d";
              insn_props->insn_string="lf.sfgt.d";
              insn_props->insn_index=75;
              insn_props->insn_index=75;
              break;
              break;
            case 0xb:
            case 0xb:
              insn_props->insn_string="lf.sfge.d";
              insn_props->insn_string="lf.sfge.d";
              insn_props->insn_index=76;
              insn_props->insn_index=76;
              break;
              break;
            case 0xc:
            case 0xc:
              insn_props->insn_string="lf.sflt.d";
              insn_props->insn_string="lf.sflt.d";
              insn_props->insn_index=77;
              insn_props->insn_index=77;
              break;
              break;
            case 0xd:
            case 0xd:
              insn_props->insn_string="lf.sfle.d";
              insn_props->insn_string="lf.sfle.d";
              insn_props->insn_index=78;
              insn_props->insn_index=78;
              break;
              break;
            default:
            default:
              printf("Unknown lf.xxx.d op (0x%x)",
              printf("Unknown lf.xxx.d op (0x%x)",
                     insn_or1k_opcode_0x32_get_op_lo(insn));
                     insn_or1k_opcode_0x32_get_op_lo(insn));
              break;
              break;
            }
            }
          break;
          break;
 
 
        case 0xd:
        case 0xd:
          insn_props->insn_string="lf.cust1.s";
          insn_props->insn_string="lf.cust1.s";
          insn_props->insn_index=79;
          insn_props->insn_index=79;
          break;
          break;
 
 
        case 0xe:
        case 0xe:
          insn_props->insn_string="lf.cust1.d";
          insn_props->insn_string="lf.cust1.d";
          insn_props->insn_index=80;
          insn_props->insn_index=80;
          break;
          break;
 
 
        default:
        default:
          printf("Unknown lf.xxx opcode hi (0x%x)",
          printf("Unknown lf.xxx opcode hi (0x%x)",
                 insn_or1k_opcode_0x32_get_op_hi(insn));
                 insn_or1k_opcode_0x32_get_op_hi(insn));
          return 1;
          return 1;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x34:
    case 0x34:
      insn_props->insn_string="l.sd";
      insn_props->insn_string="l.sd";
      insn_props->insn_index=81;
      insn_props->insn_index=81;
      break;
      break;
 
 
    case 0x35:
    case 0x35:
      insn_props->insn_string="l.sw";
      insn_props->insn_string="l.sw";
      insn_props->has_split_imm = 1;
      insn_props->has_split_imm = 1;
      insn_props->insn_index=82;
      insn_props->insn_index=82;
      break;
      break;
 
 
    case 0x36:
    case 0x36:
      insn_props->insn_string="l.sb";
      insn_props->insn_string="l.sb";
      insn_props->has_split_imm = 1;
      insn_props->has_split_imm = 1;
      insn_props->insn_index=83;
      insn_props->insn_index=83;
      break;
      break;
 
 
    case 0x37:
    case 0x37:
      insn_props->insn_string="l.sh";
      insn_props->insn_string="l.sh";
      insn_props->has_split_imm = 1;
      insn_props->has_split_imm = 1;
      insn_props->insn_index=84;
      insn_props->insn_index=84;
      break;
      break;
 
 
    case 0x38:
    case 0x38:
       insn_props->has_rD = 1;
       insn_props->has_rD = 1;
       insn_props->has_rA = 1;
       insn_props->has_rA = 1;
       insn_props->has_rB = 1;
       insn_props->has_rB = 1;
       switch(insn_or1k_opcode_0x38_get_op_lo(insn))
       switch(insn_or1k_opcode_0x38_get_op_lo(insn))
         {
         {
         case 0x0:
         case 0x0:
          insn_props->insn_string="l.add";
          insn_props->insn_string="l.add";
          insn_props->insn_index=85;
          insn_props->insn_index=85;
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.addc";
          insn_props->insn_string="l.addc";
          insn_props->insn_index=86;
          insn_props->insn_index=86;
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.sub";
          insn_props->insn_string="l.sub";
          insn_props->insn_index=87;
          insn_props->insn_index=87;
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.and";
          insn_props->insn_string="l.and";
          insn_props->insn_index=88;
          insn_props->insn_index=88;
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.or";
          insn_props->insn_string="l.or";
          insn_props->insn_index=89;
          insn_props->insn_index=89;
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.xor";
          insn_props->insn_string="l.xor";
          insn_props->insn_index=90;
          insn_props->insn_index=90;
          break;
          break;
        case 0x6:
        case 0x6:
          insn_props->insn_string="l.mul";
          insn_props->insn_string="l.mul";
          insn_props->insn_index=91;
          insn_props->insn_index=91;
          break;
          break;
        case 0x8:
        case 0x8:
          switch (insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
          switch (insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
            {
            {
            case 0x0:
            case 0x0:
              insn_props->insn_string="l.sll";
              insn_props->insn_string="l.sll";
              insn_props->insn_index=92;
              insn_props->insn_index=92;
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="l.srl";
              insn_props->insn_string="l.srl";
              insn_props->insn_index=93;
              insn_props->insn_index=93;
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="l.sra";
              insn_props->insn_string="l.sra";
              insn_props->insn_index=94;
              insn_props->insn_index=94;
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="l.ror";
              insn_props->insn_string="l.ror";
              insn_props->insn_index=95;
              insn_props->insn_index=95;
              break;
              break;
            default:
            default:
              printf("Unknown ALU op 0x8 hi op (0x%x)",
              printf("Unknown ALU op 0x8 hi op (0x%x)",
                     insn_or1k_opcode_0x38_get_op_hi_4bit(insn));
                     insn_or1k_opcode_0x38_get_op_hi_4bit(insn));
              return 1;
              return 1;
              break;
              break;
            }
            }
          break;
          break;
        case 0x9:
        case 0x9:
          insn_props->insn_string="l.div";
          insn_props->insn_string="l.div";
          insn_props->insn_index=96;
          insn_props->insn_index=96;
          break;
          break;
        case 0xa:
        case 0xa:
          insn_props->insn_string="l.divu";
          insn_props->insn_string="l.divu";
          insn_props->insn_index=97;
          insn_props->insn_index=97;
          break;
          break;
        case 0xb:
        case 0xb:
          insn_props->insn_string="l.mulu";
          insn_props->insn_string="l.mulu";
          insn_props->insn_index=98;
          insn_props->insn_index=98;
          break;
          break;
        case 0xc:
        case 0xc:
          switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
          switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
            {
            {
            case 0x0:
            case 0x0:
              insn_props->insn_string="l.exths";
              insn_props->insn_string="l.exths";
              insn_props->insn_index=99;
              insn_props->insn_index=99;
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="l.extbs";
              insn_props->insn_string="l.extbs";
              insn_props->insn_index=100;
              insn_props->insn_index=100;
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="l.exthz";
              insn_props->insn_string="l.exthz";
              insn_props->insn_index=101;
              insn_props->insn_index=101;
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="l.extbz";
              insn_props->insn_string="l.extbz";
              insn_props->insn_index=102;
              insn_props->insn_index=102;
              break;
              break;
            }
            }
          insn_props->has_rB = 0;
          insn_props->has_rB = 0;
          break;
          break;
 
 
        case 0xd:
        case 0xd:
          insn_props->insn_string="l.extws";
          insn_props->insn_string="l.extws";
          insn_props->insn_index=103;
          insn_props->insn_index=103;
          insn_props->has_rB = 0;
          insn_props->has_rB = 0;
          break;
          break;
 
 
        case 0xe:
        case 0xe:
          insn_props->insn_string="l.cmov";
          insn_props->insn_string="l.cmov";
          insn_props->insn_index=104;
          insn_props->insn_index=104;
          break;
          break;
 
 
        case 0xf:
        case 0xf:
          if (insn_or1k_opcode_0x38_get_op_hi_2bit(insn) & 0x1)
          if (insn_or1k_opcode_0x38_get_op_hi_2bit(insn) & 0x1)
            {
            {
              insn_props->insn_string="l.fl1";
              insn_props->insn_string="l.fl1";
              insn_props->insn_index=105;
              insn_props->insn_index=105;
            }
            }
          else
          else
            {
            {
              insn_props->insn_string="l.ff1";
              insn_props->insn_string="l.ff1";
              insn_props->insn_index=106;
              insn_props->insn_index=106;
            }
            }
          insn_props->has_rB = 0;
          insn_props->has_rB = 0;
          break;
          break;
 
 
        default:
        default:
          printf("Unknown ALU lo op (0x%x)",
          printf("Unknown ALU lo op (0x%x)",
                 insn_or1k_opcode_0x38_get_op_lo(insn));
                 insn_or1k_opcode_0x38_get_op_lo(insn));
          return 1;
          return 1;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x39:
    case 0x39:
      insn_props->has_rA = 1;
      insn_props->has_rA = 1;
      insn_props->has_rB = 1;
      insn_props->has_rB = 1;
      switch (insn_or1k_opcode_0x39_get_op(insn))
      switch (insn_or1k_opcode_0x39_get_op(insn))
        {
        {
        case 0x0:
        case 0x0:
          insn_props->insn_string="l.sfeq";
          insn_props->insn_string="l.sfeq";
          insn_props->insn_index=107;
          insn_props->insn_index=107;
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.sfne";
          insn_props->insn_string="l.sfne";
          insn_props->insn_index=108;
          insn_props->insn_index=108;
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.sfgtu";
          insn_props->insn_string="l.sfgtu";
          insn_props->insn_index=109;
          insn_props->insn_index=109;
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.sfgeu";
          insn_props->insn_string="l.sfgeu";
          insn_props->insn_index=110;
          insn_props->insn_index=110;
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.sfltu";
          insn_props->insn_string="l.sfltu";
          insn_props->insn_index=111;
          insn_props->insn_index=111;
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.sfleu";
          insn_props->insn_string="l.sfleu";
          insn_props->insn_index=112;
          insn_props->insn_index=112;
          break;
          break;
        case 0xa:
        case 0xa:
          insn_props->insn_string="l.sfgts";
          insn_props->insn_string="l.sfgts";
          insn_props->insn_index=113;
          insn_props->insn_index=113;
          break;
          break;
        case 0xb:
        case 0xb:
          insn_props->insn_string="l.sfges";
          insn_props->insn_string="l.sfges";
          insn_props->insn_index=114;
          insn_props->insn_index=114;
          break;
          break;
        case 0xc:
        case 0xc:
          insn_props->insn_string="l.sflts";
          insn_props->insn_string="l.sflts";
          insn_props->insn_index=115;
          insn_props->insn_index=115;
          break;
          break;
        case 0xd:
        case 0xd:
          insn_props->insn_string="l.sfles";
          insn_props->insn_string="l.sfles";
          insn_props->insn_index=116;
          insn_props->insn_index=116;
          break;
          break;
        default:
        default:
          printf("Unknown opcode for l.sfxxx opcode (0x%x)",
          printf("Unknown opcode for l.sfxxx opcode (0x%x)",
                 insn_or1k_opcode_0x39_get_op(insn));
                 insn_or1k_opcode_0x39_get_op(insn));
          return 1;
          return 1;
          break;
          break;
        }
        }
      break;
      break;
 
 
    default:
    default:
      printf("Unknown opcode 0x%x",insn_or1k_opcode(insn));
      printf("Unknown opcode 0x%x",insn_or1k_opcode(insn));
      return 1;
      return 1;
      break;
      break;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
 
 
 
// Entry point for statistics collection.
 
// Passed binary copy of instruction, and pointer to properties struct
 
// Each function that can collect staistics is called.
void or1k_32_collect_stats(uint32_t insn,
void or1k_32_collect_stats(uint32_t insn,
                         struct or1k_32_instruction_properties  * insn_props)
                         struct or1k_32_instruction_properties  * insn_props)
{
{
  // Add this instruction's occurance to our data
  // Add this instruction's occurance to our data
  insn_lists_add(insn, insn_props);
  insn_lists_add(insn, insn_props);
 
 
  // n-tuple groupings stats recording here!  
  // n-tuple groupings stats recording here!  
  // only if we've seen enough to do all the sequence analysis
  // only if we've seen enough to do all the sequence analysis
  if (num_seen_insns > OR1K_MAX_GROUPINGS_ANALYSIS+1)
  if (num_seen_insns > OR1K_MAX_GROUPINGS_ANALYSIS+1)
    {
    {
      int n;
      int n;
      for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
      for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
        insn_lists_group_add(n, insn_props);
        insn_lists_group_add(n, insn_props);
    }
    }
 
 
  // Finished adding to stats for this instruction
  // Finished adding to stats for this instruction
 
 
 
 
}
}
 
 
// Function to add entry to, or increment incidences of, value in the value list
// Function to add entry to, or increment incidences of, value in the value list
void or1k_add_in_list(struct or1k_value_list * list, int32_t value)
void or1k_add_in_list(struct or1k_value_list * list, int32_t value)
{
{
  int i;
  int i;
  // See if it's already in the list
  // See if it's already in the list
  i=list->count;
  i=list->count;
 
 
  while(i)
  while(i)
    {
    {
      i--;
      i--;
      if(list->values[i][0] == value)
      if(list->values[i][0] == value)
        {
        {
          (list->values[i][1])++;
          (list->values[i][1])++;
          return;
          return;
        }
        }
    }
    }
 
 
  if (list->count < OR1K_VALUE_MAX_ENTRIES)
  if (list->count < OR1K_VALUE_MAX_ENTRIES)
    {
    {
      // Not found, add it to the list
      // Not found, add it to the list
      list->values[(list->count)][0] = value;
      list->values[(list->count)][0] = value;
      list->values[(list->count)][1] = 1;
      list->values[(list->count)][1] = 1;
      list->count++;
      list->count++;
    }
    }
}
}
 
 
// List management/analysis functions - accessed through insn_lists() set of
// List management/analysis functions - accessed through insn_lists() set of
// functions
// functions
 
 
 
// Clear the list structs
void or1k_32_insn_lists_init(void)
void or1k_32_insn_lists_init(void)
{
{
  num_setup_insns = 0;
  num_setup_insns = 0;
  num_seen_insns = 0;
  num_seen_insns = 0;
  // Clear the pointer array so we can tell if things are used or not
  // Clear the pointer array so we can tell if things are used or not
  memset(or1k_32_insns, '\0',
  memset(or1k_32_insns, '\0',
         sizeof(struct or1k_insn_info *)*OR1K_32_MAX_INSNS);
         sizeof(struct or1k_insn_info *)*OR1K_32_MAX_INSNS);
}
}
 
 
// Alloc struct and put it into the list
// Alloc struct and put it into the list
void or1k_32_insn_lists_init_insn(uint32_t insn,
void or1k_32_insn_lists_init_insn(uint32_t insn,
                        struct or1k_32_instruction_properties *insn_props)
                        struct or1k_32_instruction_properties *insn_props)
{
{
  // Add an instruction in or1k_32_insns[num_unique_instructions];
  // Add an instruction in or1k_32_insns[num_unique_instructions];
  // use calloc() so it clears it all first (hopefully!).. assumption!
  // use calloc() so it clears it all first (hopefully!).. assumption!
  struct or1k_insn_info * new_insn
  struct or1k_insn_info * new_insn
    = (struct or1k_insn_info *) calloc (sizeof(struct or1k_insn_info), 1);
    = (struct or1k_insn_info *) calloc (sizeof(struct or1k_insn_info), 1);
 
 
  // Copy the string pointer
  // Copy the string pointer
  new_insn->insn_string = insn_props->insn_string,
  new_insn->insn_string = insn_props->insn_string,
 
 
  // Install the pointer for this newly allocated struct in its corresponding
  // Install the pointer for this newly allocated struct in its corresponding
  // index, as set when we decode the instruction
  // index, as set when we decode the instruction
  or1k_32_insns[insn_props->insn_index] = new_insn;
  or1k_32_insns[insn_props->insn_index] = new_insn;
 
 
  // Clear the set statistics counters
  // Clear the set statistics counters
  int set_itr;
  int set_itr;
  for(set_itr=0;set_itr<OR1K_MAX_GROUPINGS_ANALYSIS;set_itr++)
  for(set_itr=0;set_itr<OR1K_MAX_GROUPINGS_ANALYSIS;set_itr++)
    or1k_32_insns[insn_props->insn_index]->groupings[set_itr][0][0] = 0;
    or1k_32_insns[insn_props->insn_index]->groupings[set_itr][0][0] = 0;
 
 
  // Increment number of instructions we have set up
  // Increment number of instructions we have set up
  num_setup_insns++;
  num_setup_insns++;
 
 
  // Debugging:
  // Debugging:
  //printf("Adding %dth instruction - %s\n",
  //printf("Adding %dth instruction - %s\n",
  //num_setup_insns, new_insn->insn_string);
  //num_setup_insns, new_insn->insn_string);
 
 
}
}
 
 
 
 
 
 
// Add stats for this instruction
// Add stats for this instruction
void or1k_32_insn_lists_add(uint32_t insn,
void or1k_32_insn_lists_add(uint32_t insn,
                            struct or1k_32_instruction_properties *insn_props)
                            struct or1k_32_instruction_properties *insn_props)
{
{
  // Check if the entry for this instruction has been setup yet
  // Check if the entry for this instruction has been setup yet
  if (or1k_32_insns[insn_props->insn_index] == NULL)
  if (or1k_32_insns[insn_props->insn_index] == NULL)
    {
    {
      // Here we allocate space for the instruction's stats
      // Here we allocate space for the instruction's stats
      or1k_32_insn_lists_init_insn(insn, insn_props);
      or1k_32_insn_lists_init_insn(insn, insn_props);
    }
    }
 
 
  // Increment occurance count
  // Increment occurance count
  ((or1k_32_insns[insn_props->insn_index])->count)++;
  ((or1k_32_insns[insn_props->insn_index])->count)++;
 
 
  // Add branch target value information, if instruction has it
  // Add branch target value information, if instruction has it
  if (insn_props->has_branchtarg)
  if (insn_props->has_branchtarg)
    {
    {
      (or1k_32_insns[insn_props->insn_index])->has_branchtarg = 1;
      (or1k_32_insns[insn_props->insn_index])->has_branchtarg = 1;
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->branch_info),
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->branch_info),
                       (int32_t)insn_or1k_opcode_0x03_get_branchoff(insn));
                       (int32_t)insn_or1k_opcode_0x03_get_branchoff(insn));
    }
    }
 
 
  // Add immediate value if it's got one
  // Add immediate value if it's got one
  if (insn_props->has_imm)
  if (insn_props->has_imm)
    {
    {
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
                       (int32_t)insn_or1k_32_imm(insn));
                       (int32_t)insn_or1k_32_imm(insn));
    }
    }
 
 
  // Add split immediate value if it's got one
  // Add split immediate value if it's got one
  if (insn_props->has_split_imm)
  if (insn_props->has_split_imm)
    {
    {
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
                       (int32_t)insn_or1k_32_split_imm(insn));
                       (int32_t)insn_or1k_32_split_imm(insn));
    }
    }
 
 
 
 
  // Increment count of use for particular rD
  // Increment count of use for particular rD
  if (insn_props->has_rD)
  if (insn_props->has_rD)
    {
    {
      (or1k_32_insns[insn_props->insn_index])->has_rD = 1;
      (or1k_32_insns[insn_props->insn_index])->has_rD = 1;
      ((or1k_32_insns[insn_props->insn_index])->rD_use_freq[insn_or1k_32_rD(insn)])++;
      ((or1k_32_insns[insn_props->insn_index])->rD_use_freq[insn_or1k_32_rD(insn)])++;
    }
    }
 
 
  // Increment count of use for particular rA
  // Increment count of use for particular rA
  if (insn_props->has_rA)
  if (insn_props->has_rA)
    {
    {
      (or1k_32_insns[insn_props->insn_index])->has_rA = 1;
      (or1k_32_insns[insn_props->insn_index])->has_rA = 1;
      ((or1k_32_insns[insn_props->insn_index])->rA_use_freq[insn_or1k_32_rA(insn)])++;
      ((or1k_32_insns[insn_props->insn_index])->rA_use_freq[insn_or1k_32_rA(insn)])++;
    }
    }
 
 
  // Increment count of use for particular rB
  // Increment count of use for particular rB
  if (insn_props->has_rB)
  if (insn_props->has_rB)
    {
    {
      (or1k_32_insns[insn_props->insn_index])->has_rB = 1;
      (or1k_32_insns[insn_props->insn_index])->has_rB = 1;
      ((or1k_32_insns[insn_props->insn_index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
      ((or1k_32_insns[insn_props->insn_index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
    }
    }
 
 
  // Increment overall instructions "seen" counter
  // Increment overall instructions "seen" counter
  num_seen_insns++;
  num_seen_insns++;
 
 
  // Shift along the recently seen instructions
  // Shift along the recently seen instructions
  int i;
  int i;
  for(i=OR1K_MAX_GROUPINGS_ANALYSIS-1;i>0;i--)
  for(i=OR1K_MAX_GROUPINGS_ANALYSIS-1;i>0;i--)
    or1k_32_recent_insns[i] = or1k_32_recent_insns[i-1];
    or1k_32_recent_insns[i] = or1k_32_recent_insns[i-1];
  or1k_32_recent_insns[0] = insn_props->insn_index;
  or1k_32_recent_insns[0] = insn_props->insn_index;
 
 
}
}
 
 
 
 
 
 
 
 
// Do the n-tuple set analysis for the most recently added instruction
// Do the n-tuple set checking for the current instruction
void or1k_32_ntuple_add(int n,
void or1k_32_ntuple_add(int n,
                        struct or1k_32_instruction_properties *insn_props)
                        struct or1k_32_instruction_properties *insn_props)
{
{
 
 
  if (n<2)
  if (n<2)
    {
    {
      fprintf(stderr,"or1k_32_ntuple_add: tuple number < 2 (%d)",n);
      fprintf(stderr,"or1k_32_ntuple_add: tuple number < 2 (%d)",n);
      return;
      return;
    }
    }
 
 
  struct or1k_insn_info * insn_info = or1k_32_insns[insn_props->insn_index];
  struct or1k_insn_info * insn_info = or1k_32_insns[insn_props->insn_index];
 
 
  // Get the number of sets for these n-tuple groups we've seen so far.
  // Get the number of sets for these n-tuple groups we've seen so far.
  int sets_for_ntuple = insn_info->groupings[n-1][0][0];
  int sets_for_ntuple = insn_info->groupings[n-1][0][0];
#if DEBUG_PRINT
#if DEBUG_PRINT
  printf("%s\t:\t%d-tuple add - sets so far : %d\n",insn_info->insn_string, n, sets_for_ntuple);
  printf("%s\t:\t%d-tuple add - sets so far : %d\n",
 
         insn_info->insn_string, n, sets_for_ntuple);
#endif
#endif
 
 
  int set_match_index;
  int set_match_index;
  int tuple_set_itr, tuple_set_match;
  int tuple_set_itr, tuple_set_match;
 
 
  tuple_set_match = 0;
  tuple_set_match = 0;
 
 
  // now find if the current n instructions in or1k_32_recent_insns[] matches
  // now find if the current n instructions in or1k_32_recent_insns[] matches
  // any set of n instructions we're keeping track of in groupings[][][].
  // any set of n instructions we're keeping track of in groupings[][][].
#if DEBUG_PRINT
#if DEBUG_PRINT
  printf("%s\tChecking\t%d\tsets for ntuple:\t",insn_info->insn_string,sets_for_ntuple);
  printf("%s\tChecking\t%d\tsets for ntuple:\t",
 
         insn_info->insn_string,sets_for_ntuple);
  for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
  for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
    printf("%s ",
    printf("%s ",
           or1k_32_insns[(or1k_32_recent_insns[n - 1 - tuple_set_itr])]->insn_string);
           or1k_32_insns[(or1k_32_recent_insns[n - 1 - tuple_set_itr])]->insn_string);
  printf("\n");
  printf("\n");
#endif  
#endif  
  for (set_match_index=0; set_match_index<sets_for_ntuple; set_match_index++)
  for (set_match_index=0; set_match_index<sets_for_ntuple; set_match_index++)
    {
    {
      // Check this set for a match with our existing trace
      // Check this set for a match with our existing trace
      // Example:
      // Example:
      // In case of a triple (n=3), 1st set, [3][1][0] corresponds to the third
      // In case of a triple (n=3), 1st set, [3][1][0] corresponds to the third
      // instruction in the trace (or1k_32_recent_insns[2]), [3][1][1] should 
      // instruction in the trace (or1k_32_recent_insns[2]), [3][1][1] should 
      // be the second in the trace, and [3][1][2] should be the first in the 
      // be the second in the trace, and [3][1][2] should be the first in the 
      // trace (same index as insn_props->insn_index)
      // trace (same index as insn_props->insn_index)
 
 
#if DEBUG_PRINT
#if DEBUG_PRINT
      printf("Chk:\t");
      printf("Chk:\t");
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
        printf("%s ",
        printf("%s ",
               or1k_32_insns[(insn_info->groupings[n-1][set_match_index+1][tuple_set_itr])]->insn_string);
               or1k_32_insns[(insn_info->groupings[n-1][set_match_index+1][tuple_set_itr])]->insn_string);
      printf("\t(%d)\n", insn_info->groupings[n-1][set_match_index+1][n]);
      printf("\t(%d)\n", insn_info->groupings[n-1][set_match_index+1][n]);
#endif      
#endif      
      tuple_set_match = 1;
      tuple_set_match = 1;
      // Presuppose a match, de-assert and break out of the loop as soon as we
      // Presuppose a match, de-assert and break out of the loop as soon as we
      // detect a mismatch.
      // detect a mismatch.
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
        {
        {
 
 
          if (insn_info->groupings[n-1][set_match_index+1][tuple_set_itr]
          if (insn_info->groupings[n-1][set_match_index+1][tuple_set_itr]
              != or1k_32_recent_insns[n - 1 - tuple_set_itr])
              != or1k_32_recent_insns[n - 1 - tuple_set_itr])
            {
            {
              tuple_set_match = 0;
              tuple_set_match = 0;
              break; // No match, so break out of this for() loop
              break; // No match, so break out of this for() loop
            }
            }
        }
        }
 
 
      if (!tuple_set_match)
      if (!tuple_set_match)
        continue; // go again...
        continue; // go again...
      else
      else
        break; // Bail out, we've found our match
        break; // Bail out, we've found our match
    }
    }
 
 
  if (tuple_set_match)
  if (tuple_set_match)
    {
    {
      // Found a match - just increment the counter (set_match_index should
      // Found a match - just increment the counter (set_match_index should
      // be pointing at the right set)            
      // be pointing at the right set)            
#if DEBUG_PRINT
#if DEBUG_PRINT
      printf("Match!\n");
      printf("Match!\n");
#endif
#endif
 
 
      (insn_info->groupings[n-1][set_match_index+1][n])++;
      (insn_info->groupings[n-1][set_match_index+1][n])++;
    }
    }
  else
  else
    {
    {
      // If we can record a new set
      // If we can record a new set
      if (sets_for_ntuple < OR1K_MAX_ENTRIES_PER_GROUP)
      if (sets_for_ntuple < OR1K_MAX_ENTRIES_PER_GROUP)
        {
        {
#if DEBUG_PRINT
#if DEBUG_PRINT
          printf("New entry\n");
          printf("New entry\n");
#endif
#endif
 
 
          // Increment the number of sets we have for this n-tuple starting
          // Increment the number of sets we have for this n-tuple starting
          // on the current instruction  
          // on the current instruction  
          sets_for_ntuple++;
          sets_for_ntuple++;
          // Add new set to the end (all n instructions, copy in)
          // Add new set to the end (all n instructions, copy in)
          for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
          for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
            insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr]
            insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr]
              = or1k_32_recent_insns[n - 1 - tuple_set_itr];
              = or1k_32_recent_insns[n - 1 - tuple_set_itr];
          // Set the count for this set to 1
          // Set the count for this set to 1
          (insn_info->groupings[n-1][sets_for_ntuple][n]) = 1;
          (insn_info->groupings[n-1][sets_for_ntuple][n]) = 1;
          // Increment the counter of these n-tuple sets
          // Increment the counter of these n-tuple sets
          insn_info->groupings[n-1][0][0] = sets_for_ntuple;
          insn_info->groupings[n-1][0][0] = sets_for_ntuple;
        }
        }
    }
    }
 
 
  // Debugging :
 
#if DEBUG_PRINT
#if DEBUG_PRINT
 
  // Verbose announcement of found instruction
   if (tuple_set_match)
   if (tuple_set_match)
  {
  {
     printf("%s\t:\tMatch for %d-tuple - set %d - cnt: %d - ",
     printf("%s\t:\tMatch for %d-tuple - set %d - cnt: %d - ",
      insn_info->insn_string, n, set_match_index,
      insn_info->insn_string, n, set_match_index,
             insn_info->groupings[n-1][set_match_index+1][n]);
             insn_info->groupings[n-1][set_match_index+1][n]);
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
        printf("%s ",
        printf("%s ",
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
    printf("\n");
    printf("\n");
  }
  }
  else
  else
    {
    {
     printf("%s\t:\tNew %d-tuple - set %d - cnt: %d - ",
     printf("%s\t:\tNew %d-tuple - set %d - cnt: %d - ",
             insn_info->insn_string, n, sets_for_ntuple,
             insn_info->insn_string, n, sets_for_ntuple,
             insn_info->groupings[n-1][sets_for_ntuple][n]);
             insn_info->groupings[n-1][sets_for_ntuple][n]);
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
        printf("%s ",
        printf("%s ",
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
    printf("\n");
    printf("\n");
  }
  }
#endif
#endif
 
 
}
}
 
 
 
// Generate a list for the most-frequently seen instructions
#define DISPLAY_STRING
 
//#define DISPLAY_CSV
 
 
 
void or1k_32_most_freq_insn(FILE * stream)
void or1k_32_most_freq_insn(FILE * stream)
{
{
  // Print out most frequent instruction
  // Print out most frequent instruction
  int i, largest, largest_index;
  int i, largest, largest_index;
  int instructions_to_print = num_setup_insns;
  int instructions_to_print = num_setup_insns;
 
 
 
#ifdef DISPLAY_CSV
 
  fprintf(stream,"\"Most frequent instructions, descending\",\n");
 
  fprintf(stream,"\"Instruction\",\"Occurances\",\"Frequency\",\n");
 
#endif
 
 
  while (instructions_to_print)
  while (instructions_to_print)
    {
    {
      --instructions_to_print;
      --instructions_to_print;
      largest=0;
      largest=0;
      // Go through the list, find the largest, print it, eliminate it
      // Go through the list, find the largest, print it, eliminate it
      for(i=0;i<OR1K_32_MAX_INSNS;i++)
      for(i=0;i<OR1K_32_MAX_INSNS;i++)
        if (or1k_32_insns[i]!=NULL){
        if (or1k_32_insns[i]!=NULL){
          if(((or1k_32_insns[i])->count) > largest)
          if(((or1k_32_insns[i])->count) > largest)
            {
            {
              largest = ((or1k_32_insns[i])->count);
              largest = ((or1k_32_insns[i])->count);
              largest_index = i;
              largest_index = i;
            }
            }
        }
        }
      fprintf(stream,
      fprintf(stream,
#ifdef DISPLAY_STRING      
#ifdef DISPLAY_STRING      
             "Insn:\t%s\t\tCount:\t\t%d\t(%f%%)\n",
             "Insn:\t%s\t\tCount:\t\t%d\t(%f%%)\n",
#endif
#endif
#ifdef DISPLAY_CSV
#ifdef DISPLAY_CSV
             // CSV format - "opcode string",frequency,percentage
             // CSV format - "opcode string",frequency,percentage
             "\"%s\",%d,%f\n",
             "\"%s\",%d,%f\n",
#endif
#endif
             ((or1k_32_insns[largest_index])->insn_string),
             ((or1k_32_insns[largest_index])->insn_string),
             ((or1k_32_insns[largest_index])->count),
             ((or1k_32_insns[largest_index])->count),
             (float)(((float)((or1k_32_insns[largest_index])->count))/
             (float)(((float)((or1k_32_insns[largest_index])->count))/
                     ((float)num_seen_insns))*100.f);
                     ((float)num_seen_insns))*100.f);
 
 
 
 
      ((or1k_32_insns[largest_index])->count) = -1; // Eliminate this one
      ((or1k_32_insns[largest_index])->count) = -1; // Eliminate this one
 
 
    }
    }
}
}
 
 
 
 
// Print out top x of each kept statistic for the requested instruction
// Generate a list for the most-frequently seen n-tuple set
void or1k_32_insn_top_x(struct or1k_insn_info *insn_info, FILE * stream,
void or1k_32_most_freq_ntuple(int n, FILE * stream, int max_stats)
 
{
 
 
 
  fprintf(stream,
 
#ifdef DISPLAY_STRING
 
          "Top %d %d-tuple groupings of instructions\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
          "\"Top %d %d-tuple groupings of instructions\",\n",
 
#endif
 
          max_stats, n);
 
 
 
  // First get a copy of all the n-tuple values for each applicable
 
  // instruction.
 
  int set_counts[OR1K_32_MAX_INSNS][OR1K_MAX_ENTRIES_PER_GROUP];
 
  int insn_index;
 
  int set_index;
 
  int num_sets;
 
  struct or1k_insn_info *insn_info;
 
 
 
  // Copy each instruction's set totals into our local array
 
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
 
    {
 
      if (or1k_32_insns[insn_index] != NULL)
 
        {
 
          insn_info = or1k_32_insns[insn_index];
 
          num_sets = insn_info->groupings[n-1][0][0];
 
          for(set_index=0;set_index<num_sets;set_index++)
 
            set_counts[insn_index][set_index] =
 
              insn_info->groupings[n-1][set_index+1][n];
 
        }
 
    }
 
 
 
  // Go through the set numbers, look at the most frequent one, print it out
 
  // clear its count and continue
 
 
 
 
 
  int largest_insn_index, largest_set_index, largest_count;
 
  int tuple_set_itr;
 
 
 
 
 
#ifdef DISPLAY_CSV
 
  for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
 
    fprintf(stream, "\"insn%d\",",n-1-tuple_set_itr);
 
  fprintf(stream, "\"count\",\n");
 
#endif
 
 
 
  while(max_stats--)
 
    {
 
      largest_count = 0;
 
      // Go through each instruction we have
 
      for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
 
        {
 
          if (or1k_32_insns[insn_index] != NULL)
 
            {
 
              insn_info = or1k_32_insns[insn_index];
 
              // Get the total number of sets for the n-tup. of this instruction
 
              num_sets = insn_info->groupings[n-1][0][0];
 
              for(set_index=0;set_index<num_sets;set_index++)
 
                {
 
                  // Go through each set, check if it's largest
 
                  if (set_counts[insn_index][set_index] >
 
                      largest_count)
 
                    {
 
                      largest_insn_index = insn_index;
 
                      largest_set_index = set_index;
 
                      largest_count = set_counts[insn_index][set_index];
 
                    }
 
                }
 
            }
 
        }
 
      // Have indexes of the next largest n-tuple, print it out.
 
 
 
      insn_info = or1k_32_insns[largest_insn_index];
 
#ifdef DISPLAY_STRING
 
      fprintf(stream,"set :");
 
#endif
 
 
 
      //      insn_info->insn_string, n, set_match_index, 
 
      //        insn_info->groupings[n-1][set_match_index+1][n]);
 
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
 
        fprintf(stream,
 
#ifdef DISPLAY_STRING
 
                " %s",
 
#endif
 
#ifdef DISPLAY_CSV
 
                "\"%s\",",
 
#endif
 
                or1k_32_insns[(insn_info->groupings[n-1][largest_set_index][tuple_set_itr])]->insn_string);
 
 
 
      fprintf(stream,
 
#ifdef DISPLAY_STRING
 
              "\tcount: %d\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
              "%d,\n",
 
#endif
 
              set_counts[largest_insn_index][largest_set_index]);
 
 
 
        // Remove this value from getting selected from largest again
 
        set_counts[largest_insn_index][largest_set_index] = -1;
 
    }
 
 
 
}
 
 
 
 
 
 
 
 
 
// Print out top n of each kept statistic for the requested instruction
 
void or1k_32_insn_top_n(struct or1k_insn_info *insn_info, FILE * stream,
                        int max_stats)
                        int max_stats)
{
{
  int i, j, largest_i;
  int i, j, largest_i;
 
 
  fprintf(stream,
  fprintf(stream,
          "Insn: \"%s\" statistics (%d times (%f%%)):\n",
#ifdef DISPLAY_STRING
 
          "Insn: \"%s\" statistics (%d times (%f%%))\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
          "\"Insn:\",\"%s\",\"occurances:\",%d,%f\n",
 
#endif
          insn_info->insn_string,
          insn_info->insn_string,
          insn_info->count,
          insn_info->count,
          (float)(((float)((insn_info)->count))/
          (float)(((float)((insn_info)->count))/
                  ((float)num_seen_insns))*100.f
                  ((float)num_seen_insns))*100.f
          );
          );
 
 
 
 
 
 
  // Start dumping applicable stats
  // Start dumping applicable stats
 
 
  // Print out top max_stats branch targets
  // Print out top max_stats branch targets
  if (insn_info->has_branchtarg)
  if (insn_info->has_branchtarg)
    {
    {
      fprintf(stream,"Branch values:\n");
      fprintf(stream,
 
#ifdef DISPLAY_STRING
 
              "Branch values:\n"
 
#endif
 
#ifdef DISPLAY_CSV
 
              "\"branch distance\",\"occurances\"\n"
 
#endif
 
              );
      i = 0;
      i = 0;
      while(i<insn_info->branch_info.count && i < max_stats)
      while(i<insn_info->branch_info.count && i < max_stats)
        {
        {
          largest_i=0;
          largest_i=0;
          for(j=0;j<insn_info->branch_info.count;j++)
          for(j=0;j<insn_info->branch_info.count;j++)
            largest_i = (insn_info->branch_info.values[j][1] >
            largest_i = (insn_info->branch_info.values[j][1] >
                         insn_info->branch_info.values[largest_i][1]) ?
                         insn_info->branch_info.values[largest_i][1]) ?
              j : largest_i;
              j : largest_i;
 
 
          // largest_i has index of most frequent value
          // largest_i has index of most frequent value
          fprintf(stream,
          fprintf(stream,
 
#ifdef DISPLAY_STRING
                  "value:\t0x%x\tcount:\t%d\n",
                  "value:\t0x%x\tcount:\t%d\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
                  "0x%x,%d\n",
 
#endif
                  insn_info->branch_info.values[largest_i][0],
                  insn_info->branch_info.values[largest_i][0],
                  insn_info->branch_info.values[largest_i][1]);
                  insn_info->branch_info.values[largest_i][1]);
          insn_info->branch_info.values[largest_i][1] = -1; // clear this one
          insn_info->branch_info.values[largest_i][1] = -1; // clear this one
          i++;
          i++;
        }
        }
    }
    }
  if (insn_info->has_imm)
  if (insn_info->has_imm)
    {
    {
      fprintf(stream,"Immediate values:\n");
      fprintf(stream,
 
#ifdef DISPLAY_STRING
 
              "Immediate values:\n"
 
#endif
 
#ifdef DISPLAY_CSV
 
              "\"immediate value\",\"count\"\n"
 
#endif
 
              );
      i = 0;
      i = 0;
      while(i<insn_info->imm_info.count && i < max_stats)
      while(i<insn_info->imm_info.count && i < max_stats)
        {
        {
          largest_i=0;
          largest_i=0;
          for(j=0;j<insn_info->imm_info.count;j++)
          for(j=0;j<insn_info->imm_info.count;j++)
            largest_i = (insn_info->imm_info.values[j][1] >
            largest_i = (insn_info->imm_info.values[j][1] >
                         insn_info->imm_info.values[largest_i][1]) ?
                         insn_info->imm_info.values[largest_i][1]) ?
              j : largest_i;
              j : largest_i;
 
 
          // largest_i has index of most frequent value
          // largest_i has index of most frequent value
          fprintf(stream,
          fprintf(stream,
 
#ifdef DISPLAY_STRING
                  "value:\t0x%x\tcount:\t%d\n",
                  "value:\t0x%x\tcount:\t%d\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
                  "0x%x,%d\n",
 
#endif
                  insn_info->imm_info.values[largest_i][0],
                  insn_info->imm_info.values[largest_i][0],
                  insn_info->imm_info.values[largest_i][1]);
                  insn_info->imm_info.values[largest_i][1]);
          insn_info->imm_info.values[largest_i][1] = -1; // clear this one
          insn_info->imm_info.values[largest_i][1] = -1; // clear this one
          i++;
          i++;
        }
        }
    }
    }
 
 
  if (insn_info->has_rD)
  if (insn_info->has_rD)
    {
    {
      fprintf(stream,"rD usage:\n");
      fprintf(stream,
 
#ifdef DISPLAY_STRING
 
              "rD usage:\n"
 
#endif
 
#ifdef DISPLAY_CSV
 
              "\"rD\",\"count\"\n"
 
#endif
 
              );
      i = 0;
      i = 0;
      while(i<32 && i < max_stats)
      while(i<32 && i < max_stats)
        {
        {
          largest_i=0;
          largest_i=0;
          for(j=0;j<32;j++)
          for(j=0;j<32;j++)
            largest_i = (insn_info->rD_use_freq[j] >
            largest_i = (insn_info->rD_use_freq[j] >
                         insn_info->rD_use_freq[largest_i]) ?
                         insn_info->rD_use_freq[largest_i]) ?
              j : largest_i;
              j : largest_i;
 
 
          // No more interesting numbers
          // No more interesting numbers
          if (insn_info->rD_use_freq[largest_i] == 0)
          if (insn_info->rD_use_freq[largest_i] == 0)
            break;
            break;
 
 
          // largest_i has index of most frequent value
          // largest_i has index of most frequent value
          fprintf(stream,
          fprintf(stream,
 
#ifdef DISPLAY_STRING
                  "r%d\tcount:\t%d\n",
                  "r%d\tcount:\t%d\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
                  "\"r%d\",%d\n",
 
#endif
                  largest_i,
                  largest_i,
                  insn_info->rD_use_freq[largest_i]);
                  insn_info->rD_use_freq[largest_i]);
          insn_info->rD_use_freq[largest_i] = -1; // clear this one
          insn_info->rD_use_freq[largest_i] = -1; // clear this one
          i++;
          i++;
        }
        }
    }
    }
 
 
  if (insn_info->has_rA)
  if (insn_info->has_rA)
    {
    {
      fprintf(stream,"rA usage:\n");
      fprintf(stream,
 
#ifdef DISPLAY_STRING
 
              "rA usage:\n"
 
#endif
 
#ifdef DISPLAY_CSV
 
              "\"rA\",\"count\"\n"
 
#endif
 
              );
      i = 0;
      i = 0;
      while(i<32 && i < max_stats)
      while(i<32 && i < max_stats)
        {
        {
          largest_i=0;
          largest_i=0;
          for(j=0;j<32;j++)
          for(j=0;j<32;j++)
            largest_i = (insn_info->rA_use_freq[j] >
            largest_i = (insn_info->rA_use_freq[j] >
                         insn_info->rA_use_freq[largest_i]) ?
                         insn_info->rA_use_freq[largest_i]) ?
              j : largest_i;
              j : largest_i;
 
 
          // No more interesting numbers
          // No more interesting numbers
          if (insn_info->rA_use_freq[largest_i] == 0)
          if (insn_info->rA_use_freq[largest_i] == 0)
            break;
            break;
 
 
 
 
          // largest_i has index of most frequent value
          // largest_i has index of most frequent value
          fprintf(stream,
          fprintf(stream,
 
#ifdef DISPLAY_STRING
                  "r%d\tcount:\t%d\n",
                  "r%d\tcount:\t%d\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
                  "\"r%d\",%d\n",
 
#endif
                  largest_i,
                  largest_i,
                  insn_info->rA_use_freq[largest_i]);
                  insn_info->rA_use_freq[largest_i]);
          insn_info->rA_use_freq[largest_i] = -1; // clear this one
          insn_info->rA_use_freq[largest_i] = -1; // clear this one
          i++;
          i++;
        }
        }
    }
    }
 
 
  if (insn_info->has_rB)
  if (insn_info->has_rB)
    {
    {
      fprintf(stream,"rB usage:\n");
      fprintf(stream,
 
#ifdef DISPLAY_STRING
 
              "rB usage:\n"
 
#endif
 
#ifdef DISPLAY_CSV
 
              "\"rB\",\"count\"\n"
 
#endif
 
              );
      i = 0;
      i = 0;
      while(i<32 && i < max_stats)
      while(i<32 && i < max_stats)
        {
        {
          largest_i=0;
          largest_i=0;
          for(j=0;j<32;j++)
          for(j=0;j<32;j++)
            largest_i = (insn_info->rB_use_freq[j] >
            largest_i = (insn_info->rB_use_freq[j] >
                         insn_info->rB_use_freq[largest_i]) ?
                         insn_info->rB_use_freq[largest_i]) ?
              j : largest_i;
              j : largest_i;
 
 
          // No more interesting numbers
          // No more interesting numbers
          if (insn_info->rB_use_freq[largest_i] == 0)
          if (insn_info->rB_use_freq[largest_i] == 0)
            break;
            break;
 
 
 
 
          // largest_i has index of most frequent value
          // largest_i has index of most frequent value
          fprintf(stream,
          fprintf(stream,
 
#ifdef DISPLAY_STRING
                  "r%d\tcount:\t%d\n",
                  "r%d\tcount:\t%d\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
                  "\"r%d\",%d\n",
 
#endif
                  largest_i,
                  largest_i,
                  insn_info->rB_use_freq[largest_i]);
                  insn_info->rB_use_freq[largest_i]);
          insn_info->rB_use_freq[largest_i] = -1; // clear this one
          insn_info->rB_use_freq[largest_i] = -1; // clear this one
          i++;
          i++;
        }
        }
    }
    }
}
}
 
 
 
 
 
 
// Print out the most common n-tuple groupings for an instruction
// Print out the most common n-tuple groupings for an instruction
void or1k_32_generate_ntuple_stats(int n, struct or1k_insn_info *insn_info,
void or1k_32_generate_ntuple_stats(int n, struct or1k_insn_info *insn_info,
                                   FILE * stream)
                                   FILE * stream)
{
{
  // Maximum number we'll print out
  // Maximum number we'll print out
#define MAX_NTUPLE_LISTING 5
#define MAX_NTUPLE_LISTING 5
 
 
 
 
  int (*ntuplelist)[OR1K_MAX_GROUPINGS_ANALYSIS+1];
  int (*ntuplelist)[OR1K_MAX_GROUPINGS_ANALYSIS+1];
  int *set;
  int *set;
  int set_count, set_count2;
  int set_count, set_count2;
 
 
  // Get total number of sets for this n-tuple, eg:
  // Get total number of sets for this n-tuple, eg:
  // if n=2 (pairs) then groupings[1] is where our list is, and we store the number
  // if n=2 (pairs) then groupings[1] is where our list is, and we store the 
  // of sets in [0][0] of that n-tuple data.
  // number of sets in [0][0] of that n-tuple data.
  int total_sets_for_ntuple =  insn_info->groupings[n-1][0][0];
  int total_sets_for_ntuple =  insn_info->groupings[n-1][0][0];
 
 
  if (total_sets_for_ntuple == 0)
  if (total_sets_for_ntuple == 0)
    return;
    return;
 
 
  fprintf(stream, "%d-tuple groupings finishing with %s (%d)\n",n, insn_info->insn_string,
  fprintf(stream,
          total_sets_for_ntuple);
#ifdef DISPLAY_STRING     
 
          "%d-tuple groupings finishing with %s (%d)\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
          "\"%d-tuple groupings\",\n",
 
#endif     
 
          n, insn_info->insn_string, total_sets_for_ntuple);
 
 
 
 
  // Debug - dump out all of the info for the sets
  // Debug - dump out all of the info for the sets
#if DEBUG_PRINT
#if DEBUG_PRINT
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
    {
    {
 
 
      printf("set: %d - count %d - set: ", set_count, insn_info->groupings[n-1][set_count+1][n]);
      printf("set: %d - count %d - set: ", set_count,
 
             insn_info->groupings[n-1][set_count+1][n]);
 
 
      for(set_count2=0;set_count2<n;set_count2++)
      for(set_count2=0;set_count2<n;set_count2++)
        fprintf(stream, "%s\t",
        fprintf(stream, "%s\t",
                or1k_32_insns[(insn_info->groupings[n-1][set_count+1][set_count2])]->insn_string);
                or1k_32_insns[(insn_info->groupings[n-1][set_count+1][set_count2])]->insn_string);
      printf("\n");
      printf("\n");
    }
    }
#endif
#endif
 
 
  // A pointer to the n-tuple sets
  // A pointer to the n-tuple sets
  // This is actually a pointer to a 2-dimensional integer array, looking like:
  // This is actually a pointer to a 2-dimensional integer array, looking like:
  // [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1], so in 2-dimensional 
  // [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1], so in 
  // array pointer fashion, we should provide the "column" sizing.
  // 2-dimensional array pointer fashion, we should provide the "column" sizing.
      ntuplelist = insn_info->groupings[n-1];
      ntuplelist = insn_info->groupings[n-1];
 
 
  // Let's make a copy of the counts for each... so we don't trash them
  // Let's make a copy of the counts for each... so we don't trash them
  int set_count_copy[OR1K_MAX_ENTRIES_PER_GROUP+1];
  int set_count_copy[OR1K_MAX_ENTRIES_PER_GROUP+1];
 
 
  assert(total_sets_for_ntuple <= OR1K_MAX_ENTRIES_PER_GROUP);
  assert(total_sets_for_ntuple <= OR1K_MAX_ENTRIES_PER_GROUP);
 
 
  // Go through the list, copy the counts for each
  // Go through the list, copy the counts for each
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
    {
    {
      // Pointer to a set's data
      // Pointer to a set's data
      set = ntuplelist[set_count+1];
      set = ntuplelist[set_count+1];
      // Fish out the copy (0 to n-1 will be the instruction index, n will be the count)
      // Fish out the copy (0 to n-1 will be the instruction index, n will be 
 
      // the count)
      set_count_copy[set_count+1] = set[n];
      set_count_copy[set_count+1] = set[n];
      //printf("Set %d, count %d (%d) (%d)\n", set_count+1, set_count_copy[set_count+1], 
 
      //set[n], insn_info->groupings[n-1][set_count+1][n] );
 
    }
    }
 
 
  // Now go through, finding the most frequent n-tuple of instructions and
  // Now go through, finding the most frequent n-tuple of instructions and
  // print it out
  // print it out
  int largest_indx = 0;
  int largest_indx = 0;
  set_count=0;
  set_count=0;
  while(set_count < total_sets_for_ntuple && set_count < MAX_NTUPLE_LISTING)
  while(set_count < total_sets_for_ntuple && set_count < MAX_NTUPLE_LISTING)
    {
    {
      largest_indx = 0;
      largest_indx = 0;
      for(set_count2=0;set_count2<total_sets_for_ntuple;set_count2++)
      for(set_count2=0;set_count2<total_sets_for_ntuple;set_count2++)
        largest_indx = (set_count_copy[set_count2 + 1] >
        largest_indx = (set_count_copy[set_count2 + 1] >
                        set_count_copy[largest_indx + 1]) ?
                        set_count_copy[largest_indx + 1]) ?
          set_count2 : largest_indx;
          set_count2 : largest_indx;
      // largest_indx is the index of the set with the highest occurance, so
      // largest_indx is the index of the set with the highest occurance, so
      // let's print it out, but first get a pointer to the set's data
      // let's print it out, but first get a pointer to the set's data
      set = (int*)ntuplelist[largest_indx+1];
      set = (int*)ntuplelist[largest_indx+1];
 
 
      // Print out the sequence of prior isntructions
      // Print out the sequence of prior isntructions
 
#ifdef DISPLAY_STRING
      fprintf(stream,"Seq:\t");
      fprintf(stream,"Seq:\t");
 
#endif
 
#ifdef DISPLAY_CSV
 
      for(set_count2=0;set_count2<n;set_count2++)
 
        fprintf(stream, "\"insn%d\",",n-1-set_count2);
 
      fprintf(stream, "\"count\",\n");
 
#endif
      // Go through the indexes of the previous instructions, get their
      // Go through the indexes of the previous instructions, get their
      // strings, and print them out
      // strings, and print them out
      for(set_count2=0;set_count2<n;set_count2++)
      for(set_count2=0;set_count2<n;set_count2++)
        fprintf(stream, "%s\t", or1k_32_insns[(set[set_count2])]->insn_string);
        fprintf(stream,
 
#ifdef DISPLAY_STRING
 
                "%s\t",
 
#endif
 
#ifdef DISPLAY_CSV
 
                "\"%s\",",
 
#endif
 
                or1k_32_insns[(set[set_count2])]->insn_string);
 
 
      // now print out the occurances
      // now print out the occurances
      fprintf(stream, "\t%d\ttimes (%f%%)\n", set[n],
      fprintf(stream,
 
#ifdef DISPLAY_STRING
 
              "\t%d\ttimes (%f%%)\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
              "%d,\n",
 
#endif
 
              set[n],
              (float)((float)set[n]/(float)insn_info->count)*100.0f);
              (float)((float)set[n]/(float)insn_info->count)*100.0f);
 
 
      // done printing this one out.. let's clear its count
      // done printing this one out.. let's clear its count
      set_count_copy[largest_indx + 1] = -1;
      set_count_copy[largest_indx + 1] = -1;
 
 
      set_count++;
      set_count++;
    }
    }
 
 
  return;
  return;
 
 
}
}
 
 
 
 
// Print out the stats relating to the sequences of instructions most
// Print out the stats relating to the sequences of instructions most
// common before seeing this instruction
// common before seeing this instruction
void or1k_32_generate_groupings_stats(struct or1k_insn_info *insn_info,
void or1k_32_generate_groupings_stats(struct or1k_insn_info *insn_info,
                                      FILE * stream)
                                      FILE * stream)
{
{
  int n;
  int n;
  for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
  for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
    or1k_32_generate_ntuple_stats(n, insn_info, stream);
    or1k_32_generate_ntuple_stats(n, insn_info, stream);
 
 
}
}
 
 
 
// Entry point for statistics generation.    
void or1k_32_generate_stats(FILE * stream)
void or1k_32_generate_stats(FILE * stream)
{
{
 
#ifdef DISPLAY_STRING
  // Generate some useful things
  // Generate some useful things
  fprintf(stream, "Analysis output:\n");
  fprintf(stream, "Analysis output:\n");
 
#endif  
  // 
  // 
 
 
  // Print out all stats for every instruction we saw!
  // Print out all stats for every instruction we saw!
  int insn_index;
  int insn_index;
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
    {
    {
      if (or1k_32_insns[insn_index] != NULL)
      if (or1k_32_insns[insn_index] != NULL)
        {
        {
          or1k_32_insn_top_x(or1k_32_insns[insn_index],stream,10);
          or1k_32_insn_top_n(or1k_32_insns[insn_index],stream,10);
          or1k_32_generate_groupings_stats(or1k_32_insns[insn_index],stream);
          or1k_32_generate_groupings_stats(or1k_32_insns[insn_index],stream);
 
#ifdef DISPLAY_STRING
          fprintf(stream, "\t---\t---\t---\t---\n");
          fprintf(stream, "\t---\t---\t---\t---\n");
 
#endif
        }
        }
    }
    }
 
 
 
  // print out most frequent n-tuple
 
  int ntuple;
 
  for(ntuple=2;ntuple<5;ntuple++)
 
    or1k_32_most_freq_ntuple(ntuple, stream, 10);
 
 
  // Do most frequent instruction analysis -- note this trashes instruction
  // Do most frequent instruction analysis -- note this trashes instruction
  // frequency count - should be fixed
  // frequency count - should be fixed
 
#ifdef DISPLAY_STRING
  fprintf(stream, "Individual instruction frequency:\n");
  fprintf(stream, "Individual instruction frequency:\n");
 
#endif
  or1k_32_most_freq_insn(stream);
  or1k_32_most_freq_insn(stream);
 
 
}
}
 
 
 
 
 
 
 
 
// Free up all added instruction statistic tracking structs
// Free up all added instruction statistic tracking structs
void or1k_32_insn_lists_free(void)
void or1k_32_insn_lists_free(void)
{
{
  // Free all entries we m/calloc()'d
  // Free all entries we m/calloc()'d
  int insn_index;
  int insn_index;
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
    {
    {
      if (or1k_32_insns[insn_index] != NULL)
      if (or1k_32_insns[insn_index] != NULL)
        free(or1k_32_insns[insn_index]);
        free(or1k_32_insns[insn_index]);
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

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