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

Subversion Repositories or2k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 25 to Rev 26
    Reverse comparison

Rev 25 → Rev 26

/or2k/trunk/analysis-bin/insnanalysis/test.S
1,7 → 1,7
/* Assembly source, with one of every instruction for the or1k
instruction set */
 
l.j 0
l.j 0x1234
l.jal 0
l.bnf 0
l.bf 0
/or2k/trunk/analysis-bin/insnanalysis/or1k-32-insn.c
898,14 → 898,23
break;
case 0xd:
insn_props->insn_string="l.extws";
insn_props->insn_index=103;
switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
{
case 0x0:
insn_props->insn_string="l.extws";
insn_props->insn_index=103;
break;
case 0x1:
insn_props->insn_string="l.extwz";
insn_props->insn_index=104;
break;
}
insn_props->has_rB = 0;
break;
case 0xe:
insn_props->insn_string="l.cmov";
insn_props->insn_index=104;
insn_props->insn_index=105;
break;
 
case 0xf:
912,12 → 921,12
if (insn_or1k_opcode_0x38_get_op_hi_2bit(insn) & 0x1)
{
insn_props->insn_string="l.fl1";
insn_props->insn_index=105;
insn_props->insn_index=106;
}
else
{
insn_props->insn_string="l.ff1";
insn_props->insn_index=106;
insn_props->insn_index=107;
}
insn_props->has_rB = 0;
break;
937,43 → 946,43
{
case 0x0:
insn_props->insn_string="l.sfeq";
insn_props->insn_index=107;
insn_props->insn_index=108;
break;
case 0x1:
insn_props->insn_string="l.sfne";
insn_props->insn_index=108;
insn_props->insn_index=109;
break;
case 0x2:
insn_props->insn_string="l.sfgtu";
insn_props->insn_index=109;
insn_props->insn_index=110;
break;
case 0x3:
insn_props->insn_string="l.sfgeu";
insn_props->insn_index=110;
insn_props->insn_index=111;
break;
case 0x4:
insn_props->insn_string="l.sfltu";
insn_props->insn_index=111;
insn_props->insn_index=112;
break;
case 0x5:
insn_props->insn_string="l.sfleu";
insn_props->insn_index=112;
insn_props->insn_index=113;
break;
case 0xa:
insn_props->insn_string="l.sfgts";
insn_props->insn_index=113;
insn_props->insn_index=114;
break;
case 0xb:
insn_props->insn_string="l.sfges";
insn_props->insn_index=114;
insn_props->insn_index=115;
break;
case 0xc:
insn_props->insn_string="l.sflts";
insn_props->insn_index=115;
insn_props->insn_index=116;
break;
case 0xd:
insn_props->insn_string="l.sfles";
insn_props->insn_index=116;
insn_props->insn_index=117;
break;
default:
printf("Unknown opcode for l.sfxxx opcode (0x%x)",
1456,7 → 1465,7
"Insn: \"%s\" statistics (%d times (%f%%))\n",
#endif
#ifdef DISPLAY_CSV
"\"Instruction:\",\"%s\",\"occurrences:\",%d,%f\n",
"\"Instruction:\",\"%s\",\"occurrences:\",%d,%f%%\n",
#endif
insn_info->insn_string,
insn_info->count,
1473,10 → 1482,10
{
fprintf(stream,
#ifdef DISPLAY_STRING
"Branch values:\n"
"Branch immediates:\n"
#endif
#ifdef DISPLAY_CSV
"\"branch distance\",\"occurrences\"\n"
"\"branch imm\",\"occurrences\",\"frequency\"\n"
#endif
);
i = 0;
1491,13 → 1500,15
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"value:\t0x%x\tcount:\t%d\n",
"value:\t0x%x\tcount:\t%d,\tfreq:\t%f%%\n",
#endif
#ifdef DISPLAY_CSV
"0x%x,%d\n",
"0x%x,%d,%f\n",
#endif
insn_info->branch_info.values[largest_i][0],
insn_info->branch_info.values[largest_i][1]);
insn_info->branch_info.values[largest_i][1],
(float)(((float)insn_info->branch_info.values[largest_i][1])
/((float)((insn_info)->count)))*100.0f);
insn_info->branch_info.values[largest_i][1] = -1; // clear this one
i++;
}
1509,7 → 1520,7
"Immediate values:\n"
#endif
#ifdef DISPLAY_CSV
"\"immediate value\",\"count\"\n"
"\"immediate value\",\"count\",\"frequency\"\n"
#endif
);
i = 0;
1524,13 → 1535,15
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"value:\t0x%x\tcount:\t%d\n",
"value:\t0x%x\tcount:\t%d\tfreq:\t%f%%\n",
#endif
#ifdef DISPLAY_CSV
"0x%x,%d\n",
"0x%x,%d,%f\n",
#endif
insn_info->imm_info.values[largest_i][0],
insn_info->imm_info.values[largest_i][1]);
insn_info->imm_info.values[largest_i][1],
(float)(((float)insn_info->imm_info.values[largest_i][1])
/((float)((insn_info)->count)))*100.0f);
insn_info->imm_info.values[largest_i][1] = -1; // clear this one
i++;
}
1543,7 → 1556,7
"rD usage:\n"
#endif
#ifdef DISPLAY_CSV
"\"rD\",\"count\"\n"
"\"rD\",\"count\",\"frequency\"\n"
#endif
);
i = 0;
1562,13 → 1575,15
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"r%d\tcount:\t%d\n",
"r%d\tcount:\t%d\tfreq:\t%f%%\n",
#endif
#ifdef DISPLAY_CSV
"\"r%d\",%d\n",
"\"r%d\",%d,%f\n",
#endif
largest_i,
insn_info->rD_use_freq[largest_i]);
insn_info->rD_use_freq[largest_i],
(float)(((float)insn_info->rD_use_freq[largest_i])
/((float)((insn_info)->count)))*100.0f);
insn_info->rD_use_freq[largest_i] = -1; // clear this one
i++;
}
1581,7 → 1596,7
"rA usage:\n"
#endif
#ifdef DISPLAY_CSV
"\"rA\",\"count\"\n"
"\"rA\",\"count\",\"frequency\"\n"
#endif
);
i = 0;
1601,13 → 1616,15
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"r%d\tcount:\t%d\n",
"r%d\tcount:\t%d\tfreq:\t%f%%\n",
#endif
#ifdef DISPLAY_CSV
"\"r%d\",%d\n",
"\"r%d\",%d,%f\n",
#endif
largest_i,
insn_info->rA_use_freq[largest_i]);
insn_info->rA_use_freq[largest_i],
(float)(((float)insn_info->rA_use_freq[largest_i])
/((float)((insn_info)->count)))*100.0f);
insn_info->rA_use_freq[largest_i] = -1; // clear this one
i++;
}
1620,7 → 1637,7
"rB usage:\n"
#endif
#ifdef DISPLAY_CSV
"\"rB\",\"count\"\n"
"\"rB\",\"count\",\"frequency\"\n"
#endif
);
i = 0;
1640,13 → 1657,15
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"r%d\tcount:\t%d\n",
"r%d\tcount:\t%d\tfreq:\t%f%%\n",
#endif
#ifdef DISPLAY_CSV
"\"r%d\",%d\n",
"\"r%d\",%d,%f\n",
#endif
largest_i,
insn_info->rB_use_freq[largest_i]);
insn_info->rB_use_freq[largest_i],
(float)(((float)insn_info->rB_use_freq[largest_i])
/((float)((insn_info)->count)))*100.0f);
insn_info->rB_use_freq[largest_i] = -1; // clear this one
i++;
}
/or2k/trunk/analysis-bin/insnanalysis/or1k-32-insn.h
10,8 → 10,8
#define DEBUG_PRINT 0
 
// Choose the output format, uncomment only one
//#define DISPLAY_STRING
#define DISPLAY_CSV
#define DISPLAY_STRING
//#define DISPLAY_CSV
 
 
// Struct for information about the register to be confugred
99,7 → 99,7
 
// This number should correspond to the maximum insn_index we assign in the
// analyse function
#define OR1K_32_MAX_INSNS 117
#define OR1K_32_MAX_INSNS 118
extern struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
 
 
/or2k/trunk/analysis-bin/insnanalysis/README
3,11 → 3,21
This application reads in a binary list of instructions, and analyses it with a
set of functions looking at various parameters in each instruction.
 
It has been designed so a different instruction set support can be added.
 
Right now it's not so user friendly. Everything is hardcoded, and only support
for the OR1K instruction set exists.
 
It has been written in a way that should allow other instructinos to be added
easily. It remains to be seen how much would be reusable between the sets but
for now, at least it would be easy enough to take the OR1K instruction
analysis functions and drop in a different instruction set.
 
The types of information given for OR1K instruction analysis is instruction
frequency, immediate frequency for each instruction, branch distance value
frequency, and register usage frequency. For each instruction, the most common
n-tuple sets of instructions, finishing with that instruction, are presented,
for pairs, triples and quadruples. Additionally output is the most common
overall n-tuples.
 
Compile the program with:
 
$ make all
19,23 → 29,49
To run the program itself, just give it a binary blob of instructions (usually
the output of objcopy -O binary).
 
For instance the Linux kernel ELF can be prepared with the following command:
Static analysis:
 
For instance the Linux kernel ELF for OR1K can be prepared with the following
command:
 
$ or32-elf-objcopy -O binary -j .text -S vmlinux vmlinux.text.bin
 
Run it in the program with
It is passed to the program like so, and the output is captured by redirecting
stdout.
 
$ ./insnanalysis vmlinux.text.bin > vmlinux.insnanalysis
 
Currently the program will output all appropriate information for each
instruction (ie. only ones with rA, or immediate fields in the instructions will
have reports on those fields.)
Dynamic analysis with binary execution log from or1ksim:
 
As of revision 202 of the OpenRISC repository, or1ksim is capable of generating
an execution trace log in binary format, logging each instruction executed.
This log file can be given to insnanalysis.
 
In the or1ksim config file ensure the line "exe_bin_insn_log = 1" is in the
sim section. This will enable the binary instruction logging. The resulting
output file is then given to insnanalysis in the same manner as above.
 
Output:
 
Currently there are only two output formats, human readable string and CSV.
 
The output can be switched between human readable strings and CSV format (ready
to be imported into a spreadsheet application) by uncommenting one of the
"#define DISPLAY_" defines in the instruction set header. The program must be
recompiled if this is changed.
 
 
TODO:
o Collect and display information about l.j and l.jal instruction immediates
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 Add support for a list of binary files to be specified at the command line
o Allow statistics to be collated over different files - this would allow each
function to be broken out of a library, or application, and in that regard
the instruction sequence data would then be accurate for static analysis.
 
 
July 24, 2010 - Julius Baxter

powered by: WebSVN 2.1.0

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