URL
https://opencores.org/ocsvn/or2k/or2k/trunk
Subversion Repositories or2k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or2k
- from Rev 12 to Rev 13
- ↔ Reverse comparison
Rev 12 → Rev 13
/trunk/analysis-bin/opcodeanalysis/README
3,20 → 3,24
This program is designed to help look at the frequency of opcodes, and the |
occurance of groups of opcodes together. |
|
This can also be done on the command line, but it was felt, at the time a C |
program might be a quicker way. 3 hours later, it's not the author's intention |
to now try doing this with sed, awk and sort. |
It takes input from a file, and generates output to stdout via printf. |
|
The list of instructions/opcodes should be one per line, with a newline at the |
end. There is no capability to look at register numbers. An example of |
generating suitable input to the program is given below. |
|
Two output formats are possible - switchable by the #define DISPLAY options in |
the C source. |
1) Human readable output, enabled by uncommenting the DISPLAY_STRING define |
2) CSV output, enabled by uncommenting the DISPLAY_CSV define |
|
At the moment this program only analyses up to quadruples, and is not codeded |
in such a way that makes an arbitrary number of instruction groups easily |
testable. Fix this if you like. |
|
There are no options when running the program. It will simply spit out a list |
of individual opcodes, then list of pairs, triples and quadruples. |
of individual opcodes, then list of pairs, triples and quadruples, in one of |
the two formats described above. |
|
Compile the program with |
$ make all |
35,10 → 39,8
|
Things that might be good: |
* Actually verifying the pair/triple/quadruple results are correct/true |
* Limiting the output of set results to the first 5/10/20 |
* Provide an option to perform register analysis, also. |
* Generate CSV formatted output |
|
|
Julius Baxter |
14 July, 2010 |
15 July, 2010 |
/trunk/analysis-bin/opcodeanalysis/opcodeanalysis.c
17,7 → 17,7
// Count for occurance of each opcode |
int opcode_count[MAX_OR1K_32_OPCODES]; |
|
// Maximum number of pairs |
// Maximum number of pairs to keep track of |
#define MAX_OR1K_32_PAIRS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES) |
// 2-dimensional array, long enough to hold all possible pairs, and the 2 |
// indexes corresponding to their opcode in the *opcode_strings[] array |
24,18 → 24,20
// Ie. Each will be: [previous_opcode][current_opcode][count] |
int opcode_pairs[MAX_OR1K_32_PAIRS][3]; |
|
// Maximum number of pairs |
// Maximum number of triplets to kep track of |
#define MAX_OR1K_32_TRIPLETS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES) |
// 2-dimensional array, long enough to hold all possible pairs, and the 2 |
// indexes corresponding to their opcode in the *opcode_strings[] array |
// Ie. Each will be: [second_previous_opcode][first_previous_opcode][current_opcode][count] |
// Ie. Each will be: |
// [second_prev][first_prev][current_opcode][count] |
int opcode_triplets[MAX_OR1K_32_TRIPLETS][4]; |
|
// Maximum number of pairs |
// Maximum number of quadruples to keep track of |
#define MAX_OR1K_32_QUADS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES) |
// 2-dimensional array, long enough to hold all possible pairs, and the 2 |
// indexes corresponding to their opcode in the *opcode_strings[] array |
// Ie. Each will be: [second_previous_opcode][first_previous_opcode][current_opcode][count] |
// Ie. Each will be: |
// [third_prev][second_prev][first_prev][current_opcode][count] |
int opcode_quads[MAX_OR1K_32_QUADS][5]; |
|
// Strings shouldn't be more than 32 bytes long |
44,9 → 46,17
// Indicator for an opcode we haven't seen before |
#define IS_UNIQUE -1 |
|
// Result type |
// Result defines |
#define SORTED_DESCENDING_DISPLAY |
|
// Style of output - String or CSV |
// Uncomment only 1! |
#define DISPLAY_STRING |
//#define DISPLAY_CSV |
|
// Report only the 10 most common pairs/triples/quadruples, etc |
#define MAX_SETS_TO_REPORT 10 |
|
// Little function to strip newlines |
inline void strip_newline(char* str) |
{ |
114,8 → 124,18
|
|
|
void display_opcodes(int total_unique_opcodes) |
void display_opcodes(int total_unique_opcodes, int total_opcodes_counted) |
{ |
|
#ifdef DISPLAY_STRING |
// Totals |
printf("Number of total opcodes: %d\n",total_opcodes_counted); |
printf("Number unique opcodes: %d\n", total_unique_opcodes); |
#endif |
#ifdef DISPLAY_CSV |
printf("\"Opcode\",\"Occurances\",\"%%'age of total\",\"Total opcodes counted:\",%d\n",total_opcodes_counted); |
#endif |
|
#ifdef SIMPLE_DISPLAY |
while (total_unique_opcodes) |
{ |
139,15 → 159,26
largest = opcode_count[i]; |
largest_index = i; |
} |
|
printf( |
#ifdef DISPLAY_STRING |
"Opcode:\t%s\tCount:\t%d\t(%f%%)\n", |
#endif |
#ifdef DISPLAY_CSV |
// CSV format - "opcode string",frequency,percentage |
"\"%s\",%d,%f\n", |
#endif |
opcode_strings[largest_index], |
opcode_count[largest_index], |
(float)(((float)opcode_count[largest_index])/ |
((float)total_opcodes_counted))*100.f); |
|
printf("Opcode:\t%s\tCount:\t%d\n", |
opcode_strings[largest_index], |
opcode_count[largest_index]); |
|
opcode_count[largest_index] = -1; // Eliminate this one |
|
} |
#endif |
|
|
} |
|
180,15 → 211,23
} |
|
|
void opcode_pair_report(int total_opcode_pairs) |
void opcode_pair_report(int total_opcode_sets) |
{ |
|
int i, largest, largest_index; |
int initial_total = total_opcode_pairs; |
int initial_total = total_opcode_sets; |
|
while (total_opcode_pairs) |
#ifdef DISPLAY_STRING |
printf("Number of unique opcode pairs: %d\n", total_opcode_sets); |
#endif |
#ifdef DISPLAY_CSV |
printf("\"Opcode pair\",\"Occurances\",\"Total unique pairs:\",%d\n", |
total_opcode_sets); |
#endif |
|
while (total_opcode_sets) |
{ |
--total_opcode_pairs; |
--total_opcode_sets; |
largest=0; |
// Go through the list, find the largest, print it, eliminate it |
for(i=0;i<initial_total;i++) |
197,14 → 236,26
largest = opcode_pairs[i][2]; |
largest_index = i; |
} |
|
printf("Opcode pair:\t%s\t%s\tCount:\t%d\n", |
printf( |
#ifdef DISPLAY_STRING |
"Opcode pair:\t%s\t%s\tCount:\t%d\n", |
#endif |
#ifdef DISPLAY_CSV |
"\"%s %s\",%d\n", |
#endif |
|
opcode_strings[opcode_pairs[largest_index][0]], |
opcode_strings[opcode_pairs[largest_index][1]], |
opcode_pairs[largest_index][2]); |
|
|
opcode_pairs[largest_index][2] = -1; // Eliminate this one |
|
// If we've printed out the maximum we wanted then return |
if ((initial_total - total_opcode_sets) == MAX_SETS_TO_REPORT) |
return; |
|
|
} |
|
|
249,6 → 300,14
int i, largest, largest_index; |
int initial_total = total_opcode_sets; |
|
#ifdef DISPLAY_STRING |
printf("Number of unique opcode triplets: %d\n", total_opcode_sets); |
#endif |
#ifdef DISPLAY_CSV |
printf("\"Opcode triplet\",\"Occurances\",\"Total unique triplets:\",%d\n", |
total_opcode_sets); |
#endif |
|
while (total_opcode_sets) |
{ |
--total_opcode_sets; |
261,7 → 320,13
largest_index = i; |
} |
|
printf("Opcode triplet:\t%s\t%s\t%s\tCount:\t%d\n", |
printf( |
#ifdef DISPLAY_STRING |
"Opcode triplet:\t%s\t%s\t%s\tCount:\t%d\n", |
#endif |
#ifdef DISPLAY_CSV |
"\"%s %s %s\",%d\n", |
#endif |
opcode_strings[opcode_triplets[largest_index][0]], |
opcode_strings[opcode_triplets[largest_index][1]], |
opcode_strings[opcode_triplets[largest_index][2]], |
269,6 → 334,10
|
opcode_triplets[largest_index][3] = -1; // Eliminate this one |
|
// If we've printed out the maximum we wanted then return |
if ((initial_total - total_opcode_sets) == MAX_SETS_TO_REPORT) |
return; |
|
} |
} |
|
314,6 → 383,14
int i, largest, largest_index; |
int initial_total = total_opcode_sets; |
|
#ifdef DISPLAY_STRING |
printf("Number of unique opcode quads: %d\n", total_opcode_sets); |
#endif |
#ifdef DISPLAY_CSV |
printf("\"Opcode quad\",\"Occurances\",\"Total unique quadruples:\",%d\n", |
total_opcode_sets); |
#endif |
|
while (total_opcode_sets) |
{ |
--total_opcode_sets; |
326,7 → 403,13
largest_index = i; |
} |
|
printf("Opcode triplet:\t%s\t%s\t%s\t%s\tCount:\t%d\n", |
printf( |
#ifdef DISPLAY_STRING |
"Opcode triplet:\t%s\t%s\t%s\t%s\tCount:\t%d\n", |
#endif |
#ifdef DISPLAY_CSV |
"\"%s %s %s %s\",%d\n", |
#endif |
opcode_strings[opcode_quads[largest_index][0]], |
opcode_strings[opcode_quads[largest_index][1]], |
opcode_strings[opcode_quads[largest_index][2]], |
334,6 → 417,10
opcode_quads[largest_index][4]); |
|
opcode_quads[largest_index][4] = -1; // Eliminate this one |
|
// If we've printed out the maximum we wanted then return |
if ((initial_total - total_opcode_sets) == MAX_SETS_TO_REPORT) |
return; |
|
} |
} |
407,16 → 494,13
} |
} |
|
// Print some more detailed information |
display_opcodes(num_unique_opcodes, total_seen_opcodes); |
|
// Totals |
printf("Number of total opcodes: %d\n",total_seen_opcodes); |
printf("Number unique opcodes: %d\n", num_unique_opcodes); |
#ifdef DISPLAY_STRING |
fprintf(stdout,"Beginning groups analysis\n"); |
#endif |
|
// Print some more detailed information |
display_opcodes(num_unique_opcodes); |
|
printf("Beginning groups analysis\n"); |
|
// Now do groups analysis |
rewind(fp); |
|
478,28 → 562,16
|
} |
} |
|
|
printf("Number of unique opcode pairs: %d\n", num_opcode_pairs); |
|
// Report opcode pairs (will be a lot, > 1000) |
opcode_pair_report(num_opcode_pairs); |
|
|
printf("Number of unique opcode triplets: %d\n", num_opcode_triplets); |
|
// Report opcode pairs (will be a lot, > 1000) |
opcode_triplet_report(num_opcode_pairs); |
|
printf("Number of opcode quads: %d\n", num_opcode_quads); |
|
// Report opcode pairs (will be a lot, > 1000) |
opcode_quad_report(num_opcode_quads); |
|
// Close file pointer, we're done with it |
fclose(fp); |
// Close file pointer, we're done with it |
fclose(fp); |
|
|
// Free all the strings we declared |
while(num_unique_opcodes) |
{ |
/trunk/analysis-data/or1k-analysis.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream