URL
https://opencores.org/ocsvn/or2k/or2k/trunk
Subversion Repositories or2k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or2k/trunk
- from Rev 19 to Rev 20
- ↔ Reverse comparison
Rev 19 → Rev 20
/analysis-bin/insnanalysis/or1k-32-insn.c
10,6 → 10,7
#include "stdint.h" |
#include "stdlib.h" |
#include "string.h" |
#include "assert.h" |
#include "or1k-32-insn.h" |
|
// These should also be in insnanalysis.h insnanalysis.h |
18,6 → 19,7
|
#include "insn-lists.h" |
|
#define DEBUG_PRINT 0 |
|
// Variable to keep track of unique instructions we have |
int num_setup_insns; |
87,6 → 89,7
case 0x0: |
insn_props->insn_string="l.sys"; |
insn_props->insn_index=7; |
insn_props->has_imm = 1; |
break; |
case 0x2: |
insn_props->insn_string="l.trap"; |
779,16 → 782,19
|
case 0x35: |
insn_props->insn_string="l.sw"; |
insn_props->has_split_imm = 1; |
insn_props->insn_index=82; |
break; |
|
case 0x36: |
insn_props->insn_string="l.sb"; |
insn_props->has_split_imm = 1; |
insn_props->insn_index=83; |
break; |
|
case 0x37: |
insn_props->insn_string="l.sh"; |
insn_props->has_split_imm = 1; |
insn_props->insn_index=84; |
break; |
|
1163,12 → 1169,24
|
// 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]; |
#if DEBUG_PRINT |
printf("%s\t:\t%d-tuple add - sets so far : %d\n",insn_info->insn_string, n, sets_for_ntuple); |
#endif |
|
int set_match_index; int tuple_set_itr, tuple_set_match; |
int set_match_index; |
int tuple_set_itr, tuple_set_match; |
|
tuple_set_match = 0; |
|
|
// 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[][][]. |
#if DEBUG_PRINT |
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++) |
printf("%s ", |
or1k_32_insns[(or1k_32_recent_insns[n - 1 - tuple_set_itr])]->insn_string); |
printf("\n"); |
#endif |
for (set_match_index=0; set_match_index<sets_for_ntuple; set_match_index++) |
{ |
// Check this set for a match with our existing trace |
1177,14 → 1195,22
// 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 |
// trace (same index as insn_props->insn_index) |
|
|
#if DEBUG_PRINT |
printf("Chk:\t"); |
for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++) |
printf("%s ", |
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]); |
#endif |
tuple_set_match = 1; |
// Presuppose a match, de-assert and break out of the loop as soon as we |
// detect a mismatch. |
tuple_set_match = 1; |
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] |
!= or1k_32_recent_insns[n-1 - tuple_set_itr]) |
!= or1k_32_recent_insns[n - 1 - tuple_set_itr]) |
{ |
tuple_set_match = 0; |
break; // No match, so break out of this for() loop |
1193,17 → 1219,29
|
if (!tuple_set_match) |
continue; // go again... |
else |
break; // Bail out, we've found our match |
} |
|
if (tuple_set_match) |
// Found a match - just increment the counter (set_match_index should |
// be pointing at the right set) |
(insn_info->groupings[n-1][set_match_index+1][n])++; |
{ |
// Found a match - just increment the counter (set_match_index should |
// be pointing at the right set) |
#if DEBUG_PRINT |
printf("Match!\n"); |
#endif |
|
(insn_info->groupings[n-1][set_match_index+1][n])++; |
} |
else |
{ |
// If we can record a new set |
if (sets_for_ntuple < OR1K_MAX_ENTRIES_PER_GROUP) |
{ |
#if DEBUG_PRINT |
printf("New entry\n"); |
#endif |
|
// Increment the number of sets we have for this n-tuple starting |
// on the current instruction |
sets_for_ntuple++; |
1210,13 → 1248,38
// Add new set to the end (all n instructions, copy in) |
for(tuple_set_itr=0;tuple_set_itr<n;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 |
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 |
(insn_info->groupings[n-1][0][0])++; |
insn_info->groupings[n-1][0][0] = sets_for_ntuple; |
} |
} |
} |
|
// Debugging : |
#if DEBUG_PRINT |
if (tuple_set_match) |
{ |
printf("%s\t:\tMatch for %d-tuple - set %d - cnt: %d - ", |
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++) |
printf("%s ", |
or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string); |
printf("\n"); |
} |
else |
{ |
printf("%s\t:\tNew %d-tuple - set %d - cnt: %d - ", |
insn_info->insn_string, n, sets_for_ntuple, |
insn_info->groupings[n-1][sets_for_ntuple][n]); |
for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++) |
printf("%s ", |
or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string); |
printf("\n"); |
} |
#endif |
|
} |
|
|
1265,7 → 1328,7
void or1k_32_insn_top_x(struct or1k_insn_info *insn_info, FILE * stream, |
int max_stats) |
{ |
int i, j, largest, largest_i; |
int i, j, largest_i; |
|
fprintf(stream, |
"Insn: \"%s\" statistics (%d times (%f%%)):\n", |
1403,34 → 1466,65
} |
} |
|
#define MAX_NTUPLE_LISTING 5 |
|
|
// 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, |
FILE * stream) |
{ |
|
// If n=2 (pairs) then groupings[1] is where our list is |
// Maximum number we'll print out |
#define MAX_NTUPLE_LISTING 5 |
|
|
int (*ntuplelist)[OR1K_MAX_GROUPINGS_ANALYSIS+1]; |
int *set; |
int set_count, set_count2; |
|
// 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 |
// of sets in [0][0] of that n-tuple data. |
int total_sets_for_ntuple = insn_info->groupings[n-1][0][0]; |
|
if (total_sets_for_ntuple == 0) |
return; |
|
fprintf(stream, "%d-tuple groupings ending with this instruction\n",n); |
fprintf(stream, "%d-tuple groupings finishing with %s (%d)\n",n, insn_info->insn_string, |
total_sets_for_ntuple); |
|
// Debug - dump out all of the info for the sets |
#if DEBUG_PRINT |
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]); |
|
for(set_count2=0;set_count2<n;set_count2++) |
fprintf(stream, "%s\t", |
or1k_32_insns[(insn_info->groupings[n-1][set_count+1][set_count2])]->insn_string); |
printf("\n"); |
} |
#endif |
|
// A pointer to the n-tuple sets |
// This is actually a pointer to a 2-dimensional integer array, looking like: |
// [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1;] |
int *ntuplelist = (int*)&(insn_info->groupings[n-1]); |
int *set; |
int set_count, set_count2; |
// [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1], so in 2-dimensional |
// array pointer fashion, we should provide the "column" sizing. |
ntuplelist = insn_info->groupings[n-1]; |
|
// 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]; |
|
|
assert(total_sets_for_ntuple <= OR1K_MAX_ENTRIES_PER_GROUP); |
|
// Go through the list, copy the counts for each |
for (set_count = 0;set_count <total_sets_for_ntuple;set_count++) |
{ |
set = (int*)ntuplelist[set_count+1]; |
set_count_copy[set_count+1]=set[n]; |
// Pointer to a set's data |
set = ntuplelist[set_count+1]; |
// 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]; |
//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 |
1447,7 → 1541,7
// 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 |
set = (int*)ntuplelist[largest_indx+1]; |
|
|
// Print out the sequence of prior isntructions |
fprintf(stream,"Seq:\t"); |
// Go through the indexes of the previous instructions, get their |
1456,7 → 1550,7
fprintf(stream, "%s\t", or1k_32_insns[(set[set_count2])]->insn_string); |
|
// now print out the occurances |
fprintf(stream, "%d\ttimes\n", set_count_copy[largest_indx + 1]); |
fprintf(stream, "\t%d\ttimes\n", set[n]); |
|
// done printing this one out.. let's clear its count |
set_count_copy[largest_indx + 1] = -1; |
1498,8 → 1592,6
} |
} |
|
|
|
// Do most frequent instruction analysis -- note this trashes instruction |
// frequency count - should be fixed |
or1k_32_most_freq_insn(stream); |
/analysis-bin/insnanalysis/or1k-32-insn.h
60,7 → 60,7
|
// Set maximum instructions in a row we'll keep track of, starting at pairs |
#define OR1K_MAX_GROUPINGS_ANALYSIS 4 |
#define OR1K_MAX_ENTRIES_PER_GROUP 1000 |
#define OR1K_MAX_ENTRIES_PER_GROUP 50 |
// Format of grouping data: |
// |
// 1st dimension: A list for each n-tuple group we're keeping track of |
/analysis-bin/insnanalysis/Makefile
23,4 → 23,4
or32-elf-as $< -o $@ |
|
clean: |
rm $(APP) *.o *.bin |
rm -f $(APP) *.o *.bin |
/analysis-bin/insnanalysis/README
34,10 → 34,8
|
|
TODO: |
o Add a more flexible way of indicating the instructions to dump |
o Add an easy way to switch between human readable and CSV output |
o Figure out how to tack this thing onto a simulator (or1ksim maybe) to give |
results of execution when that finishes executing, or just how to get the |
simulator to output a binary dump of executed instructions to be fed through |
this |
o Instruction group analysis (pairs, triplets, etc.) |