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

Subversion Repositories or2k

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

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

Rev 16 Rev 17
 
/*
 
  Or1K instruction set-specific decoding and analysis functions.
 
 
 
  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 "or1k-32-insn.h"
#include "or1k-32-insn.h"
 
 
// These should also be in insnanalysis.h insnanalysis.h
// These should also be in insnanalysis.h 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"
 
 
 
 
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->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->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->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->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";
      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";
      else
      else
        {
        {
          insn_props->insn_string="l.movhi";
          insn_props->insn_string="l.movhi";
          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";
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.trap";
          insn_props->insn_string="l.trap";
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.msync";
          insn_props->insn_string="l.msync";
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.psync";
          insn_props->insn_string="l.psync";
          break;
          break;
        case 0x6:
        case 0x6:
          insn_props->insn_string="l.csync";
          insn_props->insn_string="l.csync";
          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";
      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;
            }
            }
        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;
            }
            }
          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;
            }
            }
          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;
            }
            }
          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;
            }
            }
          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;
            }
            }
          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;
            }
            }
          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;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x11:
    case 0x11:
      insn_props->insn_string="l.jr";
      insn_props->insn_string="l.jr";
      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->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";
      break;
      break;
 
 
    case 0x1c:
    case 0x1c:
      insn_props->insn_string="l.cust1";
      insn_props->insn_string="l.cust1";
      break;
      break;
 
 
    case 0x1d:
    case 0x1d:
      insn_props->insn_string="l.cust2";
      insn_props->insn_string="l.cust2";
      break;
      break;
 
 
    case 0x1e:
    case 0x1e:
      insn_props->insn_string="l.cust3";
      insn_props->insn_string="l.cust3";
      break;
      break;
 
 
    case 0x1f:
    case 0x1f:
      insn_props->insn_string="l.cust4";
      insn_props->insn_string="l.cust4";
      break;
      break;
 
 
    case 0x20:
    case 0x20:
      insn_props->insn_string="l.ld";
      insn_props->insn_string="l.ld";
      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->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->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->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->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->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->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->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->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->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->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->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->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->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";
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.srli";
          insn_props->insn_string="l.srli";
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.srai";
          insn_props->insn_string="l.srai";
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.rori";
          insn_props->insn_string="l.rori";
          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;
          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";
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.sfnei";
          insn_props->insn_string="l.sfnei";
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.sfgtui";
          insn_props->insn_string="l.sfgtui";
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.sfgeui";
          insn_props->insn_string="l.sfgeui";
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.sfltui";
          insn_props->insn_string="l.sfltui";
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.sfleui";
          insn_props->insn_string="l.sfleui";
          break;
          break;
        case 0xa:
        case 0xa:
          insn_props->insn_string="l.sfgtsi";
          insn_props->insn_string="l.sfgtsi";
          break;
          break;
        case 0xb:
        case 0xb:
          insn_props->insn_string="l.sfgesi";
          insn_props->insn_string="l.sfgesi";
          break;
          break;
        case 0xc:
        case 0xc:
          insn_props->insn_string="l.sfltsi";
          insn_props->insn_string="l.sfltsi";
          break;
          break;
        case 0xd:
        case 0xd:
          insn_props->insn_string="l.sflesi";
          insn_props->insn_string="l.sflesi";
          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;
          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";
      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";
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.msb";
          insn_props->insn_string="l.msb";
          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;
        }
        }
      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";
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="lf.sub.s";
              insn_props->insn_string="lf.sub.s";
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="lf.mul.s";
              insn_props->insn_string="lf.mul.s";
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="lf.div.s";
              insn_props->insn_string="lf.div.s";
              break;
              break;
            case 0x4:
            case 0x4:
              insn_props->insn_string="lf.itof.s";
              insn_props->insn_string="lf.itof.s";
              break;
              break;
            case 0x5:
            case 0x5:
              insn_props->insn_string="lf.ftoi.s";
              insn_props->insn_string="lf.ftoi.s";
              break;
              break;
            case 0x6:
            case 0x6:
              insn_props->insn_string="lf.rem.s";
              insn_props->insn_string="lf.rem.s";
              break;
              break;
            case 0x7:
            case 0x7:
              insn_props->insn_string="lf.madd.s";
              insn_props->insn_string="lf.madd.s";
              break;
              break;
            case 0x8:
            case 0x8:
              insn_props->insn_string="lf.sfeq.s";
              insn_props->insn_string="lf.sfeq.s";
              break;
              break;
            case 0x9:
            case 0x9:
              insn_props->insn_string="lf.sfne.s";
              insn_props->insn_string="lf.sfne.s";
              break;
              break;
            case 0xa:
            case 0xa:
              insn_props->insn_string="lf.sfgt.s";
              insn_props->insn_string="lf.sfgt.s";
              break;
              break;
            case 0xb:
            case 0xb:
              insn_props->insn_string="lf.sfge.s";
              insn_props->insn_string="lf.sfge.s";
              break;
              break;
            case 0xc:
            case 0xc:
              insn_props->insn_string="lf.sflt.s";
              insn_props->insn_string="lf.sflt.s";
              break;
              break;
            case 0xd:
            case 0xd:
              insn_props->insn_string="lf.sfle.s";
              insn_props->insn_string="lf.sfle.s";
              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";
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="lf.sub.d";
              insn_props->insn_string="lf.sub.d";
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="lf.mul.d";
              insn_props->insn_string="lf.mul.d";
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="lf.div.d";
              insn_props->insn_string="lf.div.d";
              break;
              break;
            case 0x4:
            case 0x4:
              insn_props->insn_string="lf.itof.d";
              insn_props->insn_string="lf.itof.d";
              break;
              break;
            case 0x5:
            case 0x5:
              insn_props->insn_string="lf.ftoi.d";
              insn_props->insn_string="lf.ftoi.d";
              break;
              break;
            case 0x6:
            case 0x6:
              insn_props->insn_string="lf.rem.d";
              insn_props->insn_string="lf.rem.d";
              break;
              break;
            case 0x7:
            case 0x7:
              insn_props->insn_string="lf.madd.d";
              insn_props->insn_string="lf.madd.d";
              break;
              break;
            case 0x8:
            case 0x8:
              insn_props->insn_string="lf.sfeq.d";
              insn_props->insn_string="lf.sfeq.d";
              break;
              break;
            case 0x9:
            case 0x9:
              insn_props->insn_string="lf.sfne.d";
              insn_props->insn_string="lf.sfne.d";
              break;
              break;
            case 0xa:
            case 0xa:
              insn_props->insn_string="lf.sfgt.d";
              insn_props->insn_string="lf.sfgt.d";
              break;
              break;
            case 0xb:
            case 0xb:
              insn_props->insn_string="lf.sfge.d";
              insn_props->insn_string="lf.sfge.d";
              break;
              break;
            case 0xc:
            case 0xc:
              insn_props->insn_string="lf.sflt.d";
              insn_props->insn_string="lf.sflt.d";
              break;
              break;
            case 0xd:
            case 0xd:
              insn_props->insn_string="lf.sfle.d";
              insn_props->insn_string="lf.sfle.d";
              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";
          break;
          break;
 
 
        case 0xe:
        case 0xe:
          insn_props->insn_string="lf.cust1.d";
          insn_props->insn_string="lf.cust1.d";
          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;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x34:
    case 0x34:
      insn_props->insn_string="l.sd";
      insn_props->insn_string="l.sd";
      break;
      break;
 
 
    case 0x35:
    case 0x35:
      insn_props->insn_string="l.sw";
      insn_props->insn_string="l.sw";
      break;
      break;
 
 
    case 0x36:
    case 0x36:
      insn_props->insn_string="l.sb";
      insn_props->insn_string="l.sb";
      break;
      break;
 
 
    case 0x37:
    case 0x37:
      insn_props->insn_string="l.sh";
      insn_props->insn_string="l.sh";
      break;
      break;
 
 
    case 0x38:
    case 0x38:
      switch(insn_or1k_opcode_0x38_get_op_lo(insn))
 
        {
 
          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))
 
         {
        case 0x0:
        case 0x0:
          insn_props->insn_string="l.add";
          insn_props->insn_string="l.add";
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.addc";
          insn_props->insn_string="l.addc";
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.sub";
          insn_props->insn_string="l.sub";
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.and";
          insn_props->insn_string="l.and";
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.or";
          insn_props->insn_string="l.or";
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.xor";
          insn_props->insn_string="l.xor";
          break;
          break;
        case 0x6:
        case 0x6:
          insn_props->insn_string="l.mul";
          insn_props->insn_string="l.mul";
          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";
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="l.srl";
              insn_props->insn_string="l.srl";
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="l.sra";
              insn_props->insn_string="l.sra";
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="l.ror";
              insn_props->insn_string="l.ror";
              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;
              break;
              break;
            }
            }
          break;
          break;
        case 0x9:
        case 0x9:
          insn_props->insn_string="l.div";
          insn_props->insn_string="l.div";
          break;
          break;
        case 0xa:
        case 0xa:
          insn_props->insn_string="l.divu";
          insn_props->insn_string="l.divu";
          break;
          break;
        case 0xb:
        case 0xb:
          insn_props->insn_string="l.mulu";
          insn_props->insn_string="l.mulu";
          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";
              break;
              break;
            case 0x1:
            case 0x1:
              insn_props->insn_string="l.extbs";
              insn_props->insn_string="l.extbs";
              break;
              break;
            case 0x2:
            case 0x2:
              insn_props->insn_string="l.exthz";
              insn_props->insn_string="l.exthz";
              break;
              break;
            case 0x3:
            case 0x3:
              insn_props->insn_string="l.extbz";
              insn_props->insn_string="l.extbz";
              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->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";
          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";
          else
          else
            insn_props->insn_string="l.ff1";
            insn_props->insn_string="l.ff1";
          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;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case 0x39:
    case 0x39:
 
      insn_props->has_rA = 1;
 
      insn_props->has_rB = 1;
      switch (insn_or1k_opcode_0x39_get_op(insn))
      switch (insn_or1k_opcode_0x39_get_op(insn))
        {
        {
          insn_props->has_rA = 0;
 
          insn_props->has_rB = 0;
 
        case 0x0:
        case 0x0:
          insn_props->insn_string="l.sfeq";
          insn_props->insn_string="l.sfeq";
          break;
          break;
        case 0x1:
        case 0x1:
          insn_props->insn_string="l.sfne";
          insn_props->insn_string="l.sfne";
          break;
          break;
        case 0x2:
        case 0x2:
          insn_props->insn_string="l.sfgtu";
          insn_props->insn_string="l.sfgtu";
          break;
          break;
        case 0x3:
        case 0x3:
          insn_props->insn_string="l.sfgeu";
          insn_props->insn_string="l.sfgeu";
          break;
          break;
        case 0x4:
        case 0x4:
          insn_props->insn_string="l.sfltu";
          insn_props->insn_string="l.sfltu";
          break;
          break;
        case 0x5:
        case 0x5:
          insn_props->insn_string="l.sfleu";
          insn_props->insn_string="l.sfleu";
          break;
          break;
        case 0xa:
        case 0xa:
          insn_props->insn_string="l.sfgts";
          insn_props->insn_string="l.sfgts";
          break;
          break;
        case 0xb:
        case 0xb:
          insn_props->insn_string="l.sfges";
          insn_props->insn_string="l.sfges";
          break;
          break;
        case 0xc:
        case 0xc:
          insn_props->insn_string="l.sflts";
          insn_props->insn_string="l.sflts";
          break;
          break;
        case 0xd:
        case 0xd:
          insn_props->insn_string="l.sfles";
          insn_props->insn_string="l.sfles";
          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;
          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;
}
}
 
 
 
 
 
 
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)
{
{
  // First calculate frequency
  // First calculate frequency
  int index = insn_lists_check(insn, insn_props);
  int index = insn_lists_check(insn, insn_props);
 
 
  // Create new entry in list
  // Create new entry in list
  if (index == IS_UNIQUE)
  if (index == IS_UNIQUE)
    index = insn_lists_add_unique_insn(insn, insn_props);
    index = insn_lists_add_unique_insn(insn, insn_props);
 
 
  // Now count it
  // Now count it
  insn_lists_add(index, insn, insn_props);
  insn_lists_add(index, insn, insn_props);
 
 
}
}
 
 
 
 
 
 
struct or1k_value_list
struct or1k_value_list
{
{
 
 
#define OR1K_VALUE_MAX_ENTRIES 64
#define OR1K_VALUE_MAX_ENTRIES 64
  int count;
  int count;
  // [value][occurances_of_value]
  // [value][occurances_of_value]
  int values[OR1K_VALUE_MAX_ENTRIES][2];
  int32_t values[OR1K_VALUE_MAX_ENTRIES][2];
 
 
};
};
 
 
 
 
struct or1k_insn_info
struct or1k_insn_info
{
{
  char* insn_string;
  char* insn_string;
 
 
  int count;
  int count;
 
 
  int has_branchtarg;
  int has_branchtarg;
  struct or1k_value_list branch_info;
  struct or1k_value_list branch_info;
 
 
  int has_imm;
  int has_imm;
 
 
  struct or1k_value_list imm_info;
  struct or1k_value_list imm_info;
 
 
  int has_rD;
  int has_rD;
  int rD_use_freq[32];
  int rD_use_freq[32];
  int has_rA;
  int has_rA;
  int rA_use_freq[32];
  int rA_use_freq[32];
  int has_rB;
  int has_rB;
  int rB_use_freq[32];
  int rB_use_freq[32];
 
 
};
};
 
 
#define OR1K_32_MAX_INSNS 120
#define OR1K_32_MAX_INSNS 120
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
 
 
 
 
// List management/analysis functions - accessed through insn_lists() set of
// List management/analysis functions - accessed through insn_lists() set of
// functions
// functions
 
 
// Variable to keep track of unique instructions we have
// Variable to keep track of unique instructions we have
int num_unique_insns;
int num_unique_insns;
int num_seen_insns;
int num_seen_insns;
 
 
 
 
void or1k_32_insn_lists_init(void)
void or1k_32_insn_lists_init(void)
{
{
  num_unique_insns = 0;
  num_unique_insns = 0;
  num_seen_insns = 0;
  num_seen_insns = 0;
}
}
 
 
// List management/analysis functions
// List management/analysis functions
int or1k_32_insn_lists_check(uint32_t insn,
int or1k_32_insn_lists_check(uint32_t insn,
                             struct or1k_32_instruction_properties *insn_props)
                             struct or1k_32_instruction_properties *insn_props)
{
{
 
 
  int num_to_check = num_unique_insns;
  int num_to_check = num_unique_insns;
  int insn_strlen = strlen(insn_props->insn_string);
  int insn_strlen = strlen(insn_props->insn_string);
  while (num_to_check)
  while (num_to_check)
    {
    {
 
 
      --num_to_check;
      --num_to_check;
 
 
      if ((strncmp(insn_props->insn_string,
      if ((strncmp(insn_props->insn_string,
                   or1k_32_insns[num_to_check]->insn_string, insn_strlen) == 0)
                   or1k_32_insns[num_to_check]->insn_string, insn_strlen) == 0)
          && (insn_strlen == strlen(or1k_32_insns[num_to_check]->insn_string)))
          && (insn_strlen == strlen(or1k_32_insns[num_to_check]->insn_string)))
        {
        {
          // Found match by string
          // Found match by string
          return num_to_check;
          return num_to_check;
        }
        }
    }
    }
 
 
  return IS_UNIQUE;
  return IS_UNIQUE;
}
}
 
 
// Add a unique instruction
// Add a unique instruction
int or1k_32_insn_lists_add_unique_insn(uint32_t insn,
int or1k_32_insn_lists_add_unique_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);
 
 
  // Calloc() space for the string
  // Calloc() space for the string
  new_insn->insn_string = (char *) calloc(strlen(insn_props->insn_string), 1);
  new_insn->insn_string = (char *) calloc(strlen(insn_props->insn_string), 1);
 
 
  // Copy in the instruction string
  // Copy in the instruction string
  strncpy(new_insn->insn_string, insn_props->insn_string,
  strncpy(new_insn->insn_string, insn_props->insn_string,
          strlen(insn_props->insn_string));
          strlen(insn_props->insn_string));
 
 
  // Install the pointer for this new instruction in the list
  // Install the pointer for this new instruction in the list
  or1k_32_insns[num_unique_insns] = new_insn;;
  or1k_32_insns[num_unique_insns] = new_insn;;
 
 
  // Increment number of instructions we have
  // Increment number of instructions we have
  num_unique_insns++;
  num_unique_insns++;
 
 
 
  // Debugging:
 
  //printf("Adding %dth instruction - %s\n",
 
  //num_unique_insns, new_insn->insn_string);
 
 
  // Return index of newly created instruction
  // Return index of newly created instruction
  return (num_unique_insns - 1);
  return (num_unique_insns - 1);
 
 
}
}
 
 
// Add to, or increment incidences of, value in the value list
// Add to, or increment incidences of, value in the value list
void or1k_add_in_list(struct or1k_value_list * list, int 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)
 
    {
  // 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++;
 
    }
 
 
}
}
 
 
 
 
// Add stats for this instruction
// Add stats for this instruction
void or1k_32_insn_lists_add(int index, uint32_t insn,
void or1k_32_insn_lists_add(int index, uint32_t insn,
                            struct or1k_32_instruction_properties *insn_props)
                            struct or1k_32_instruction_properties *insn_props)
{
{
  // Add stats for this instruction
  // Add stats for this instruction
 
 
  // Increment count
  // Increment count
  ((or1k_32_insns[index])->count)++;
  ((or1k_32_insns[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[index])->has_branchtarg = 1;
      (or1k_32_insns[index])->has_branchtarg = 1;
      or1k_add_in_list(&((or1k_32_insns[index])->branch_info),
      or1k_add_in_list(&((or1k_32_insns[index])->branch_info),
                       (int)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[index])->has_imm = 1;
      (or1k_32_insns[index])->has_imm = 1;
      or1k_add_in_list(&((or1k_32_insns[index])->imm_info),
      or1k_add_in_list(&((or1k_32_insns[index])->imm_info),
                       (int)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[index])->has_imm = 1;
      (or1k_32_insns[index])->has_imm = 1;
      or1k_add_in_list(&((or1k_32_insns[index])->imm_info),
      or1k_add_in_list(&((or1k_32_insns[index])->imm_info),
                       (int)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[index])->has_rD = 1;
      (or1k_32_insns[index])->has_rD = 1;
      ((or1k_32_insns[index])->rD_use_freq[insn_or1k_32_rD(insn)])++;
      ((or1k_32_insns[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[index])->has_rA = 1;
      (or1k_32_insns[index])->has_rA = 1;
      ((or1k_32_insns[index])->rA_use_freq[insn_or1k_32_rA(insn)])++;
      ((or1k_32_insns[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[index])->has_rB = 1;
      (or1k_32_insns[index])->has_rB = 1;
      ((or1k_32_insns[index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
      ((or1k_32_insns[index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
    }
    }
 
 
  // Finished adding to stats for this instruction
  // Finished adding to stats for this instruction
 
 
  // Increment overall instructions "seen" counter
  // Increment overall instructions "seen" counter
  num_seen_insns++;
  num_seen_insns++;
 
 
}
}
 
 
 
 
// 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)
{
{
  while (num_unique_insns)
  while (num_unique_insns)
    {
    {
 
 
      num_unique_insns--;
      num_unique_insns--;
 
 
 
      free((or1k_32_insns[num_unique_insns]->insn_string));
      free(or1k_32_insns[num_unique_insns]);
      free(or1k_32_insns[num_unique_insns]);
 
 
    }
    }
}
}
 
 
 
 
 No newline at end of file
 No newline at end of file
 
#define DISPLAY_STRING
 
//#define DISPLAY_CSV
 
 
 
void or1k_32_most_freq_insn(FILE * stream)
 
{
 
  // Print out most frequent instruction
 
  int i, largest, largest_index;
 
  int instructions_to_print = num_unique_insns;
 
  while (instructions_to_print)
 
    {
 
      --instructions_to_print;
 
      largest=0;
 
      // Go through the list, find the largest, print it, eliminate it
 
      for(i=0;i<num_unique_insns;i++)
 
        if(((or1k_32_insns[i])->count) > largest)
 
          {
 
            largest = ((or1k_32_insns[i])->count);
 
            largest_index = i;
 
          }
 
 
 
      fprintf(stream,
 
#ifdef DISPLAY_STRING      
 
             "Insn:\t%s\t\tCount:\t\t%d\t(%f%%)\n",
 
#endif
 
#ifdef DISPLAY_CSV
 
             // CSV format - "opcode string",frequency,percentage
 
             "\"%s\",%d,%f\n",
 
#endif
 
             ((or1k_32_insns[largest_index])->insn_string),
 
             ((or1k_32_insns[largest_index])->count),
 
             (float)(((float)((or1k_32_insns[largest_index])->count))/
 
                     ((float)num_seen_insns))*100.f);
 
 
 
 
 
      ((or1k_32_insns[largest_index])->count) = -1; // Eliminate this one
 
 
 
    }
 
}
 
 
 
 
 
// Print out top x of each kept statistic for the requested instruction
 
void or1k_32_insn_top_x(char* insn_string, FILE * stream, int max_stats)
 
{
 
  int i, j, largest, largest_i;
 
 
 
  // Confect an instruction properties object to fish out the instruction
 
  struct or1k_32_instruction_properties temp_insn_props;
 
  // Struct we'll copy the info into
 
  struct or1k_insn_info insn_info;
 
 
 
  temp_insn_props.insn_string = insn_string;
 
 
 
  int insn_index = or1k_32_insn_lists_check(0, &temp_insn_props);
 
  if (insn_index == IS_UNIQUE)
 
    {
 
      fprintf(stream,"Insn: \"%s\" was not seen\n",insn_string);
 
      return;
 
    }
 
  else
 
    {
 
      fprintf(stream,"Insn: \"%s\" statistics (%d times (%f%%)):\n", insn_string,
 
              or1k_32_insns[insn_index]->count,
 
              (float)(((float)((or1k_32_insns[insn_index])->count))/
 
                      ((float)num_seen_insns))*100.f
 
              );
 
    }
 
 
 
  // We have the instruction's index, copy it out (to make code neater!)
 
  memcpy(&insn_info, or1k_32_insns[insn_index],
 
         sizeof(struct or1k_insn_info));
 
 
 
  // Print out top max_stats branch targets
 
 
 
  if (insn_info.has_branchtarg)
 
    {
 
      fprintf(stream,"Branch values:\n");
 
      i = 0;
 
      while(i<insn_info.branch_info.count && i < max_stats)
 
        {
 
          largest_i=0;
 
          for(j=0;j<insn_info.branch_info.count;j++)
 
            largest_i = (insn_info.branch_info.values[j][1] >
 
                         insn_info.branch_info.values[largest_i][1]) ?
 
              j : largest_i;
 
 
 
          // largest_i has index of most frequent value
 
          fprintf(stream,
 
                  "value:\t0x%x\tcount:\t%d\n",
 
                  insn_info.branch_info.values[largest_i][0],
 
                  insn_info.branch_info.values[largest_i][1]);
 
          insn_info.branch_info.values[largest_i][1] = -1; // clear this one
 
          i++;
 
        }
 
    }
 
  if (insn_info.has_imm)
 
    {
 
      fprintf(stream,"Immediate values:\n");
 
      i = 0;
 
      while(i<insn_info.imm_info.count && i < max_stats)
 
        {
 
          largest_i=0;
 
          for(j=0;j<insn_info.imm_info.count;j++)
 
            largest_i = (insn_info.imm_info.values[j][1] >
 
                         insn_info.imm_info.values[largest_i][1]) ?
 
              j : largest_i;
 
 
 
          // largest_i has index of most frequent value
 
          fprintf(stream,
 
                  "value:\t0x%x\tcount:\t%d\n",
 
                  insn_info.imm_info.values[largest_i][0],
 
                  insn_info.imm_info.values[largest_i][1]);
 
          insn_info.imm_info.values[largest_i][1] = -1; // clear this one
 
          i++;
 
        }
 
    }
 
  if (insn_info.has_rD)
 
    {
 
      fprintf(stream,"rD usage:\n");
 
      i = 0;
 
      while(i<32 && i < max_stats)
 
        {
 
          largest_i=0;
 
          for(j=0;j<32;j++)
 
            largest_i = (insn_info.rD_use_freq[j] >
 
                         insn_info.rD_use_freq[largest_i]) ?
 
              j : largest_i;
 
 
 
          // No more interesting numbers
 
          if (insn_info.rD_use_freq[largest_i] == 0)
 
            break;
 
 
 
          // largest_i has index of most frequent value
 
          fprintf(stream,
 
                  "r%d\tcount:\t%d\n",
 
                  largest_i,
 
                  insn_info.rD_use_freq[largest_i]);
 
          insn_info.rD_use_freq[largest_i] = -1; // clear this one
 
          i++;
 
        }
 
    }
 
 
 
  if (insn_info.has_rA)
 
    {
 
      fprintf(stream,"rA usage:\n");
 
      i = 0;
 
      while(i<32 && i < max_stats)
 
        {
 
          largest_i=0;
 
          for(j=0;j<32;j++)
 
            largest_i = (insn_info.rA_use_freq[j] >
 
                         insn_info.rA_use_freq[largest_i]) ?
 
              j : largest_i;
 
 
 
          // No more interesting numbers
 
          if (insn_info.rA_use_freq[largest_i] == 0)
 
            break;
 
 
 
 
 
          // largest_i has index of most frequent value
 
          fprintf(stream,
 
                  "r%d\tcount:\t%d\n",
 
                  largest_i,
 
                  insn_info.rA_use_freq[largest_i]);
 
          insn_info.rA_use_freq[largest_i] = -1; // clear this one
 
          i++;
 
        }
 
    }
 
 
 
  if (insn_info.has_rB)
 
    {
 
      fprintf(stream,"rB usage:\n");
 
      i = 0;
 
      while(i<32 && i < max_stats)
 
        {
 
          largest_i=0;
 
          for(j=0;j<32;j++)
 
            largest_i = (insn_info.rB_use_freq[j] >
 
                         insn_info.rB_use_freq[largest_i]) ?
 
              j : largest_i;
 
 
 
          // No more interesting numbers
 
          if (insn_info.rB_use_freq[largest_i] == 0)
 
            break;
 
 
 
 
 
          // largest_i has index of most frequent value
 
          fprintf(stream,
 
                  "r%d\tcount:\t%d\n",
 
                  largest_i,
 
                  insn_info.rB_use_freq[largest_i]);
 
          insn_info.rB_use_freq[largest_i] = -1; // clear this one
 
          i++;
 
        }
 
    }
 
}
 
 
 
void or1k_32_generate_stats(FILE * stream)
 
{
 
  // Generate some useful things
 
  fprintf(stream, "Analysis output:\n");
 
 
 
  // 
 
 
 
  // Print out all stats for every instruction we saw!
 
  int unique = num_unique_insns;
 
  while (unique)
 
    {
 
      --unique;
 
      or1k_32_insn_top_x(or1k_32_insns[unique]->insn_string,stream,10);
 
    }
 
 
 
 
 
  // Do most frequent instruction analysis -- note this trashes instruction
 
  // frequency count - should be fixed
 
  or1k_32_most_freq_insn(stream);
 
 
 
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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