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

Subversion Repositories or2k

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

Show entire file | Details | Blame | View Log

Rev 27 Rev 28
Line 776... Line 776...
                 insn_or1k_opcode_0x32_get_op_hi(insn));
                 insn_or1k_opcode_0x32_get_op_hi(insn));
          return 1;
          return 1;
          break;
          break;
        }
        }
      break;
      break;
 
      // The l.sx instructions'd rD is actually in the location rA is for 
 
      // every other instruction - so we specify has_rA, but really that's 
 
      // the rD, so it's l.sx imm(rA), rB
    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;
 
      insn_props->has_rA = 1;
 
      insn_props->has_rB = 1;
      break;
      break;
 
 
    case 0x35:
    case 0x35:
      insn_props->insn_string="l.sw";
      insn_props->insn_string="l.sw";
 
      insn_props->has_rA = 1;
 
      insn_props->has_rB = 1;
      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_rA = 1;
 
      insn_props->has_rB = 1;
      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_rA = 1;
 
      insn_props->has_rB = 1;
      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:
Line 999... Line 1009...
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
 
// Function to track entire instructions, regardless of architecture
 
// Storage list:
 
// Format: [0] - binary copy of instruction
 
//         [1] - occurrence count
 
uint32_t (*bin_insn_list)[2] = NULL;
 
int bin_insn_list_count = -1;
 
#define NUM_EXPECTED_UNIQUE_INSNS 50000
 
void record_bin_insn(uint32_t insn)
 
{
 
  // Check if the array has been initialised yet
 
  if (bin_insn_list_count == -1)
 
    {
 
      bin_insn_list = calloc((NUM_EXPECTED_UNIQUE_INSNS*2)*sizeof(uint32_t),1);
 
      bin_insn_list_count = 0;
 
    }
 
 
 
  int list_check_itr;
 
  // Go through the list, check if we've seen this one before
 
  for(list_check_itr=0;list_check_itr<bin_insn_list_count;list_check_itr++)
 
    if (bin_insn_list[list_check_itr][0] == insn)
 
      {
 
        // Seen it before, just increment count
 
        bin_insn_list[list_check_itr][1]++;
 
        return;
 
      }
 
 
 
 
 
  // If we're here, we've not seen this one before, it's new
 
 
 
  // No room left in list to add new ones
 
  if ( bin_insn_list_count == NUM_EXPECTED_UNIQUE_INSNS )
 
    return;
 
 
 
  // Add it to the list
 
  bin_insn_list[bin_insn_list_count][0] = insn;
 
  bin_insn_list[bin_insn_list_count][1] = 1;
 
 
 
  bin_insn_list_count++;
 
 
 
  // No room left in list to add new ones
 
  if ( bin_insn_list_count == NUM_EXPECTED_UNIQUE_INSNS )
 
    fprintf(stderr, "Warning: bin_insn_list[][] full (%d entries)\n",
 
            NUM_EXPECTED_UNIQUE_INSNS);
 
 
 
 
 
}
 
 
// Entry point for statistics collection.
// Entry point for statistics collection.
// Passed binary copy of instruction, and pointer to properties struct
// Passed binary copy of instruction, and pointer to properties struct
// Each function that can collect staistics is called.
// 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,
 
                           int record_bin_insns)
{
{
  // Add this instruction's occurrence to our data
  // Add this instruction's occurrence 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!  
Line 1018... Line 1075...
      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
  if (record_bin_insns)
 
    record_bin_insn(insn);
 
 
 
  // 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)
Line 1798... Line 1857...
  return;
  return;
 
 
}
}
 
 
 
 
 
// Print out the top n seen entire instructions
 
void print_top_bin_insn(FILE * stream, int n)
 
{
 
  int largest_indx = 0;
 
  int bin_insn_list_itr;
 
 
 
  // Copy the counts, so we can trash them as needed
 
  int bin_insn_counts[NUM_EXPECTED_UNIQUE_INSNS];
 
 
 
  // An instruction properties object
 
  struct or1k_32_instruction_properties insn_props;
 
 
 
  for(bin_insn_list_itr=0;bin_insn_list_itr<bin_insn_list_count;
 
      bin_insn_list_itr++)
 
    bin_insn_counts[bin_insn_list_itr] = bin_insn_list[bin_insn_list_itr][1];
 
 
 
#ifdef DISPLAY_STRING
 
  fprintf(stream, "Top %d seen instructions\n", n);
 
  fprintf(stream, "Saw %d unique instructions\n", bin_insn_list_count);
 
#endif
 
#ifdef DISPLAY_CSV
 
  fprintf(stream, ",\n");
 
  fprintf(stream,"\"Top %d instructions\",\n\"Total unique instructions\",%d\n",
 
          n, bin_insn_list_count);
 
  fprintf(stream,
 
          "\"Instruction (bin)\",\"Dissassembly\",\"Occurrences\",\"Freq\"\n");
 
#endif
 
 
 
  while (n--)
 
    {
 
      // Search for the largest count
 
      for(bin_insn_list_itr=0;bin_insn_list_itr<bin_insn_list_count;
 
          bin_insn_list_itr++)
 
        largest_indx = (bin_insn_counts[bin_insn_list_itr] >
 
                        bin_insn_counts[largest_indx]) ?
 
          bin_insn_list_itr : largest_indx;
 
 
 
      // Gone through list, largest_indx is the biggest index
 
 
 
      // Clear the instruction properties struct
 
      memset(&insn_props, 0, sizeof(struct or1k_32_instruction_properties));
 
 
 
      // Get the string for this instruction
 
      or1k_32_analyse_insn(bin_insn_list[largest_indx][0], &insn_props);
 
 
 
      // Print out the instruction
 
#ifdef DISPLAY_STRING
 
      fprintf(stream, "Insn:\t0x%.8x\t%s",bin_insn_list[largest_indx][0],
 
              insn_props.insn_string);
 
#endif
 
#ifdef DISPLAY_CSV
 
      fprintf(stream, "\"0x%.8x\",\"%s",bin_insn_list[largest_indx][0],
 
              insn_props.insn_string);
 
#endif
 
 
 
      if (insn_props.has_jumptarg || insn_props.has_branchtarg)
 
#ifdef DISPLAY_STRING
 
        fprintf(stream, " 0x%x", (bin_insn_list[largest_indx][0] & JUMPTARG_MASK) << 2 );
 
#endif
 
#ifdef DISPLAY_CSV
 
        fprintf(stream, " 0x%x",  (bin_insn_list[largest_indx][0] & JUMPTARG_MASK) << 2 );
 
#endif
 
 
 
 
 
      if (insn_props.has_rD)
 
#ifdef DISPLAY_STRING
 
        fprintf(stream, " r%d",
 
                insn_or1k_32_rD(bin_insn_list[largest_indx][0]));
 
#endif
 
#ifdef DISPLAY_CSV
 
        fprintf(stream, " r%d",
 
                insn_or1k_32_rD(bin_insn_list[largest_indx][0]));
 
#endif
 
 
 
      if (insn_props.has_rA)
 
#ifdef DISPLAY_STRING
 
        fprintf(stream, " r%d",
 
                insn_or1k_32_rA(bin_insn_list[largest_indx][0]));
 
#endif
 
#ifdef DISPLAY_CSV
 
        fprintf(stream, " r%d",
 
                insn_or1k_32_rA(bin_insn_list[largest_indx][0]));
 
#endif
 
 
 
      if (insn_props.has_rB)
 
#ifdef DISPLAY_STRING
 
        fprintf(stream, " r%d",
 
                insn_or1k_32_rB(bin_insn_list[largest_indx][0]));
 
#endif
 
#ifdef DISPLAY_CSV
 
        fprintf(stream, " r%d",
 
                insn_or1k_32_rB(bin_insn_list[largest_indx][0]));
 
#endif
 
 
 
 
 
      if (insn_props.has_imm)
 
#ifdef DISPLAY_STRING
 
        fprintf(stream, " 0x%x",
 
                insn_or1k_32_imm(bin_insn_list[largest_indx][0]));
 
#endif
 
#ifdef DISPLAY_CSV
 
        fprintf(stream, " 0x%x",
 
                insn_or1k_32_imm(bin_insn_list[largest_indx][0]));
 
#endif
 
 
 
      if (insn_props.has_split_imm)
 
#ifdef DISPLAY_STRING
 
        fprintf(stream, " 0x%x",
 
                insn_or1k_32_split_imm(bin_insn_list[largest_indx][0]));
 
#endif
 
#ifdef DISPLAY_CSV
 
        fprintf(stream, " 0x%x",
 
                insn_or1k_32_split_imm(bin_insn_list[largest_indx][0]));
 
#endif
 
 
 
#ifdef DISPLAY_STRING
 
        fprintf(stream, "\tcount:\t%d (%f%%)\n",bin_insn_list[largest_indx][1],
 
                (float)((float)bin_insn_list[largest_indx][1])/
 
                ((float)num_seen_insns));
 
#endif
 
#ifdef DISPLAY_CSV
 
        fprintf(stream, "\",%d,%f\n",bin_insn_list[largest_indx][1],
 
                (float)((float)bin_insn_list[largest_indx][1])/
 
                ((float)num_seen_insns));
 
#endif
 
 
 
        // Finished printing out its instruction
 
        bin_insn_counts[largest_indx] = -1;
 
 
 
    }
 
}
 
 
 
 
// 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)
{
{
Line 1865... Line 2057...
#ifdef DISPLAY_STRING
#ifdef DISPLAY_STRING
  fprintf(stream, "Individual instruction frequency:\n");
  fprintf(stream, "Individual instruction frequency:\n");
#endif
#endif
  or1k_32_most_freq_insn(stream);
  or1k_32_most_freq_insn(stream);
 
 
}
  // If we did the binary instruction frequency counting, print it out
 
  if (bin_insn_list_count != -1)
 
    print_top_bin_insn(stream, 20);
 
 
 
}
 
 
 
 
 
 
// 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)
Line 1880... Line 2075...
  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]);
    }
    }
 
 
 
  if (bin_insn_list_count != -1)
 
    free(bin_insn_list);
}
}
 
 
 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.