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 17 to Rev 18
- ↔ Reverse comparison
Rev 17 → Rev 18
/analysis-bin/insnanalysis/insn-lists.c
14,27 → 14,13
{ |
or1k_32_insn_lists_init(); |
} |
|
int insn_lists_check(instruction insn, |
instruction_properties *insn_props) |
{ |
return or1k_32_insn_lists_check(insn, insn_props); |
} |
|
|
int insn_lists_add_unique_insn(instruction insn, |
void insn_lists_add(instruction insn, |
instruction_properties *insn_props) |
{ |
|
return or1k_32_insn_lists_add_unique_insn(insn, insn_props); |
or1k_32_insn_lists_add(insn, insn_props); |
} |
|
void insn_lists_add(int index, instruction insn, |
instruction_properties *insn_props) |
{ |
or1k_32_insn_lists_add(index, insn, insn_props); |
} |
|
void insn_lists_free(void) |
{ |
or1k_32_insn_lists_free(); |
/analysis-bin/insnanalysis/or1k-32-insn.c
27,34 → 27,43
{ |
case 0x00: |
insn_props->insn_string="l.j"; |
insn_props->insn_index=0; |
insn_props->has_jumptarg = 1; |
break; |
|
case 0x01: |
insn_props->insn_string="l.jal"; |
insn_props->insn_index=1; |
insn_props->has_jumptarg = 1; |
break; |
|
case 0x03: |
insn_props->insn_string="l.bnf"; |
insn_props->insn_index=2; |
insn_props->has_branchtarg = 1; |
break; |
|
case 0x04: |
insn_props->insn_string="l.bf"; |
insn_props->insn_index=3; |
insn_props->has_branchtarg = 1; |
break; |
|
case 0x05: |
insn_props->insn_string="l.nop"; |
insn_props->insn_index=4; |
break; |
|
case 0x06: |
if((insn_or1k_opcode_0x06_get_id(insn))) |
insn_props->insn_string="l.macrc"; |
{ |
insn_props->insn_string="l.macrc"; |
insn_props->insn_index=5; |
} |
else |
{ |
insn_props->insn_string="l.movhi"; |
insn_props->insn_index=6; |
insn_props->has_rD = 1; |
insn_props->has_imm = 1; |
} |
67,18 → 76,23
{ |
case 0x0: |
insn_props->insn_string="l.sys"; |
insn_props->insn_index=7; |
break; |
case 0x2: |
insn_props->insn_string="l.trap"; |
insn_props->insn_index=8; |
break; |
case 0x4: |
insn_props->insn_string="l.msync"; |
insn_props->insn_index=9; |
break; |
case 0x5: |
insn_props->insn_string="l.psync"; |
insn_props->insn_index=10; |
break; |
case 0x6: |
insn_props->insn_string="l.csync"; |
insn_props->insn_index=11; |
break; |
default: |
printf("Unknown id (0x%x) in opcode 0x8", |
90,6 → 104,7
|
case 0x09: |
insn_props->insn_string="l.rfe"; |
insn_props->insn_index=12; |
break; |
|
case 0x0a: |
341,36 → 356,44
|
case 0x11: |
insn_props->insn_string="l.jr"; |
insn_props->insn_index=13; |
insn_props->has_rB = 1; |
break; |
|
case 0x12: |
insn_props->insn_string="l.jalr"; |
insn_props->insn_index=14; |
insn_props->has_rB = 1; |
break; |
|
case 0x13: |
insn_props->insn_string="l.maci"; |
insn_props->insn_index=15; |
break; |
|
case 0x1c: |
insn_props->insn_string="l.cust1"; |
insn_props->insn_index=16; |
break; |
|
case 0x1d: |
insn_props->insn_string="l.cust2"; |
insn_props->insn_index=17; |
break; |
|
case 0x1e: |
insn_props->insn_string="l.cust3"; |
insn_props->insn_index=18; |
break; |
|
case 0x1f: |
insn_props->insn_string="l.cust4"; |
insn_props->insn_index=19; |
break; |
|
case 0x20: |
insn_props->insn_string="l.ld"; |
insn_props->insn_index=20; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
378,6 → 401,7
|
case 0x21: |
insn_props->insn_string="l.lwz"; |
insn_props->insn_index=21; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
385,6 → 409,7
|
case 0x22: |
insn_props->insn_string="l.lws"; |
insn_props->insn_index=22; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
392,6 → 417,7
|
case 0x23: |
insn_props->insn_string="l.lbz"; |
insn_props->insn_index=23; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
399,6 → 425,7
|
case 0x24: |
insn_props->insn_string="l.lbs"; |
insn_props->insn_index=24; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
406,6 → 433,7
|
case 0x25: |
insn_props->insn_string="l.lhz"; |
insn_props->insn_index=25; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
413,6 → 441,7
|
case 0x26: |
insn_props->insn_string="l.lhs"; |
insn_props->insn_index=26; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
421,6 → 450,7
|
case 0x27: |
insn_props->insn_string="l.addi"; |
insn_props->insn_index=27; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
428,6 → 458,7
|
case 0x28: |
insn_props->insn_string="l.addic"; |
insn_props->insn_index=28; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
435,6 → 466,7
|
case 0x29: |
insn_props->insn_string="l.andi"; |
insn_props->insn_index=29; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
442,6 → 474,7
|
case 0x2a: |
insn_props->insn_string="l.ori"; |
insn_props->insn_index=30; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
449,6 → 482,7
|
case 0x2b: |
insn_props->insn_string="l.xori"; |
insn_props->insn_index=31; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
456,6 → 490,7
|
case 0x2c: |
insn_props->insn_string="l.muli"; |
insn_props->insn_index=32; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
463,6 → 498,7
|
case 0x2d: |
insn_props->insn_string="l.mfspr"; |
insn_props->insn_index=33; |
insn_props->has_rD = 1; |
insn_props->has_rA = 1; |
insn_props->has_imm = 1; |
473,15 → 509,19
{ |
case 0x0: |
insn_props->insn_string="l.slli"; |
insn_props->insn_index=34; |
break; |
case 0x1: |
insn_props->insn_string="l.srli"; |
insn_props->insn_index=35; |
break; |
case 0x2: |
insn_props->insn_string="l.srai"; |
insn_props->insn_index=36; |
break; |
case 0x3: |
insn_props->insn_string="l.rori"; |
insn_props->insn_index=37; |
break; |
default: |
printf("Unknown shift op (0x%x)", |
496,33 → 536,43
{ |
case 0x0: |
insn_props->insn_string="l.sfeqi"; |
insn_props->insn_index=38; |
break; |
case 0x1: |
insn_props->insn_string="l.sfnei"; |
insn_props->insn_index=39; |
break; |
case 0x2: |
insn_props->insn_string="l.sfgtui"; |
insn_props->insn_index=40; |
break; |
case 0x3: |
insn_props->insn_string="l.sfgeui"; |
insn_props->insn_index=41; |
break; |
case 0x4: |
insn_props->insn_string="l.sfltui"; |
insn_props->insn_index=42; |
break; |
case 0x5: |
insn_props->insn_string="l.sfleui"; |
insn_props->insn_index=43; |
break; |
case 0xa: |
insn_props->insn_string="l.sfgtsi"; |
insn_props->insn_index=44; |
break; |
case 0xb: |
insn_props->insn_string="l.sfgesi"; |
insn_props->insn_index=45; |
break; |
case 0xc: |
insn_props->insn_string="l.sfltsi"; |
insn_props->insn_index=46; |
break; |
case 0xd: |
insn_props->insn_string="l.sflesi"; |
insn_props->insn_index=47; |
break; |
|
default: |
538,6 → 588,7
|
case 0x30: |
insn_props->insn_string="l.mtspr"; |
insn_props->insn_index=48; |
break; |
|
case 0x31: |
545,9 → 596,11
{ |
case 0x1: |
insn_props->insn_string="l.mac"; |
insn_props->insn_index=49; |
break; |
case 0x2: |
insn_props->insn_string="l.msb"; |
insn_props->insn_index=50; |
break; |
default: |
printf("Unknown mac op (0x%x)", |
564,45 → 617,59
{ |
case 0x0: |
insn_props->insn_string="lf.add.s"; |
insn_props->insn_index=51; |
break; |
case 0x1: |
insn_props->insn_string="lf.sub.s"; |
insn_props->insn_index=52; |
break; |
case 0x2: |
insn_props->insn_string="lf.mul.s"; |
insn_props->insn_index=53; |
break; |
case 0x3: |
insn_props->insn_string="lf.div.s"; |
insn_props->insn_index=54; |
break; |
case 0x4: |
insn_props->insn_string="lf.itof.s"; |
insn_props->insn_index=55; |
break; |
case 0x5: |
insn_props->insn_string="lf.ftoi.s"; |
insn_props->insn_index=56; |
break; |
case 0x6: |
insn_props->insn_string="lf.rem.s"; |
insn_props->insn_index=57; |
break; |
case 0x7: |
insn_props->insn_string="lf.madd.s"; |
insn_props->insn_index=58; |
break; |
case 0x8: |
insn_props->insn_string="lf.sfeq.s"; |
insn_props->insn_index=59; |
break; |
case 0x9: |
insn_props->insn_string="lf.sfne.s"; |
insn_props->insn_index=60; |
break; |
case 0xa: |
insn_props->insn_string="lf.sfgt.s"; |
insn_props->insn_index=61; |
break; |
case 0xb: |
insn_props->insn_string="lf.sfge.s"; |
insn_props->insn_index=62; |
break; |
case 0xc: |
insn_props->insn_string="lf.sflt.s"; |
insn_props->insn_index=63; |
break; |
case 0xd: |
insn_props->insn_string="lf.sfle.s"; |
insn_props->insn_index=64; |
break; |
default: |
printf("Unknown lf.xxx.s op (0x%x)", |
616,45 → 683,59
{ |
case 0x0: |
insn_props->insn_string="lf.add.d"; |
insn_props->insn_index=65; |
break; |
case 0x1: |
insn_props->insn_string="lf.sub.d"; |
insn_props->insn_index=66; |
break; |
case 0x2: |
insn_props->insn_string="lf.mul.d"; |
insn_props->insn_index=67; |
break; |
case 0x3: |
insn_props->insn_string="lf.div.d"; |
insn_props->insn_index=68; |
break; |
case 0x4: |
insn_props->insn_string="lf.itof.d"; |
insn_props->insn_index=69; |
break; |
case 0x5: |
insn_props->insn_string="lf.ftoi.d"; |
insn_props->insn_index=70; |
break; |
case 0x6: |
insn_props->insn_string="lf.rem.d"; |
insn_props->insn_index=71; |
break; |
case 0x7: |
insn_props->insn_string="lf.madd.d"; |
insn_props->insn_index=72; |
break; |
case 0x8: |
insn_props->insn_string="lf.sfeq.d"; |
insn_props->insn_index=73; |
break; |
case 0x9: |
insn_props->insn_string="lf.sfne.d"; |
insn_props->insn_index=74; |
break; |
case 0xa: |
insn_props->insn_string="lf.sfgt.d"; |
insn_props->insn_index=75; |
break; |
case 0xb: |
insn_props->insn_string="lf.sfge.d"; |
insn_props->insn_index=76; |
break; |
case 0xc: |
insn_props->insn_string="lf.sflt.d"; |
insn_props->insn_index=77; |
break; |
case 0xd: |
insn_props->insn_string="lf.sfle.d"; |
insn_props->insn_index=78; |
break; |
default: |
printf("Unknown lf.xxx.d op (0x%x)", |
665,10 → 746,12
|
case 0xd: |
insn_props->insn_string="lf.cust1.s"; |
insn_props->insn_index=79; |
break; |
|
case 0xe: |
insn_props->insn_string="lf.cust1.d"; |
insn_props->insn_index=80; |
break; |
|
default: |
681,18 → 764,22
|
case 0x34: |
insn_props->insn_string="l.sd"; |
insn_props->insn_index=81; |
break; |
|
case 0x35: |
insn_props->insn_string="l.sw"; |
insn_props->insn_index=82; |
break; |
|
case 0x36: |
insn_props->insn_string="l.sb"; |
insn_props->insn_index=83; |
break; |
|
case 0x37: |
insn_props->insn_string="l.sh"; |
insn_props->insn_index=84; |
break; |
|
case 0x38: |
703,24 → 790,31
{ |
case 0x0: |
insn_props->insn_string="l.add"; |
insn_props->insn_index=85; |
break; |
case 0x1: |
insn_props->insn_string="l.addc"; |
insn_props->insn_index=86; |
break; |
case 0x2: |
insn_props->insn_string="l.sub"; |
insn_props->insn_index=87; |
break; |
case 0x3: |
insn_props->insn_string="l.and"; |
insn_props->insn_index=88; |
break; |
case 0x4: |
insn_props->insn_string="l.or"; |
insn_props->insn_index=89; |
break; |
case 0x5: |
insn_props->insn_string="l.xor"; |
insn_props->insn_index=90; |
break; |
case 0x6: |
insn_props->insn_string="l.mul"; |
insn_props->insn_index=91; |
break; |
case 0x8: |
switch (insn_or1k_opcode_0x38_get_op_hi_4bit(insn)) |
727,15 → 821,19
{ |
case 0x0: |
insn_props->insn_string="l.sll"; |
insn_props->insn_index=92; |
break; |
case 0x1: |
insn_props->insn_string="l.srl"; |
insn_props->insn_index=93; |
break; |
case 0x2: |
insn_props->insn_string="l.sra"; |
insn_props->insn_index=94; |
break; |
case 0x3: |
insn_props->insn_string="l.ror"; |
insn_props->insn_index=95; |
break; |
default: |
printf("Unknown ALU op 0x8 hi op (0x%x)", |
746,12 → 844,15
break; |
case 0x9: |
insn_props->insn_string="l.div"; |
insn_props->insn_index=96; |
break; |
case 0xa: |
insn_props->insn_string="l.divu"; |
insn_props->insn_index=97; |
break; |
case 0xb: |
insn_props->insn_string="l.mulu"; |
insn_props->insn_index=98; |
break; |
case 0xc: |
switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn)) |
758,15 → 859,19
{ |
case 0x0: |
insn_props->insn_string="l.exths"; |
insn_props->insn_index=99; |
break; |
case 0x1: |
insn_props->insn_string="l.extbs"; |
insn_props->insn_index=100; |
break; |
case 0x2: |
insn_props->insn_string="l.exthz"; |
insn_props->insn_index=101; |
break; |
case 0x3: |
insn_props->insn_string="l.extbz"; |
insn_props->insn_index=102; |
break; |
} |
insn_props->has_rB = 0; |
774,18 → 879,26
|
case 0xd: |
insn_props->insn_string="l.extws"; |
insn_props->insn_index=103; |
insn_props->has_rB = 0; |
break; |
|
case 0xe: |
insn_props->insn_string="l.cmov"; |
insn_props->insn_index=104; |
break; |
|
case 0xf: |
if (insn_or1k_opcode_0x38_get_op_hi_2bit(insn) & 0x1) |
insn_props->insn_string="l.fl1"; |
{ |
insn_props->insn_string="l.fl1"; |
insn_props->insn_index=105; |
} |
else |
insn_props->insn_string="l.ff1"; |
{ |
insn_props->insn_string="l.ff1"; |
insn_props->insn_index=106; |
} |
insn_props->has_rB = 0; |
break; |
|
804,33 → 917,43
{ |
case 0x0: |
insn_props->insn_string="l.sfeq"; |
insn_props->insn_index=107; |
break; |
case 0x1: |
insn_props->insn_string="l.sfne"; |
insn_props->insn_index=108; |
break; |
case 0x2: |
insn_props->insn_string="l.sfgtu"; |
insn_props->insn_index=109; |
break; |
case 0x3: |
insn_props->insn_string="l.sfgeu"; |
insn_props->insn_index=110; |
break; |
case 0x4: |
insn_props->insn_string="l.sfltu"; |
insn_props->insn_index=111; |
break; |
case 0x5: |
insn_props->insn_string="l.sfleu"; |
insn_props->insn_index=112; |
break; |
case 0xa: |
insn_props->insn_string="l.sfgts"; |
insn_props->insn_index=113; |
break; |
case 0xb: |
insn_props->insn_string="l.sfges"; |
insn_props->insn_index=114; |
break; |
case 0xc: |
insn_props->insn_string="l.sflts"; |
insn_props->insn_index=115; |
break; |
case 0xd: |
insn_props->insn_string="l.sfles"; |
insn_props->insn_index=116; |
break; |
default: |
printf("Unknown opcode for l.sfxxx opcode (0x%x)", |
854,15 → 977,8
void or1k_32_collect_stats(uint32_t insn, |
struct or1k_32_instruction_properties * insn_props) |
{ |
// First calculate frequency |
int index = insn_lists_check(insn, insn_props); |
|
// Create new entry in list |
if (index == IS_UNIQUE) |
index = insn_lists_add_unique_insn(insn, insn_props); |
|
// Now count it |
insn_lists_add(index, insn, insn_props); |
// Add this instruction's occurance to our data |
insn_lists_add(insn, insn_props); |
|
} |
|
878,7 → 994,34
|
}; |
|
|
|
// 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) |
{ |
int i; |
// See if it's already in the list |
i=list->count; |
|
while(i) |
{ |
i--; |
if(list->values[i][0] == value) |
{ |
(list->values[i][1])++; |
return; |
} |
} |
|
if (list->count < OR1K_VALUE_MAX_ENTRIES) |
{ |
// Not found, add it to the list |
list->values[(list->count)][0] = value; |
list->values[(list->count)][1] = 1; |
list->count++; |
} |
|
} |
|
struct or1k_insn_info |
{ |
char* insn_string; |
889,7 → 1032,6
struct or1k_value_list branch_info; |
|
int has_imm; |
|
struct or1k_value_list imm_info; |
|
int has_rD; |
899,9 → 1041,40
int has_rB; |
int rB_use_freq[32]; |
|
// 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 |
// Format of grouping data: |
// |
// 1st dimension: A list for each n-tuple group we're keeping track of |
// (starting at pairs of instructions) |
// |
// 2nd dimension: Stores the list entries for the 1st dimension-tuple |
// grouping. The number in [x][0][0] is the number of entries in the list so |
// far, beginning at 0. The actual entries with data for grouping x start at |
// [x][1][], where that entry holds the 1st x+2-tuple grouping information |
// (eg. at x=0, [0][1][] is the first entry for/ pair instruction |
// information, x=1, is for triples, x=2 quadruples, etc) |
// |
// 3rd dimension: Store up to x+2 instruction indexes (where x is the first |
// dimension index, meaning this particular data is for a (x+2)-tuple set) |
// and then a frequency count for this set (in index (x+2) of the third |
// dimension array). Note we will have the index for the instruction this |
// struct corresponds to in [x][n][(x+2)-1], which seems redundant, but can |
// help processing later on. |
// |
// Note that we will have empty entries in the third dimension arrays for all |
// but the last in the list of n-tuples. This is to save doing tricky naming |
// defines and, in the future, if we would like to analyse sets that are |
// bigger or smaller, hopefully all we need to do is change a single define. |
// |
int groupings[OR1K_MAX_GROUPINGS_ANALYSIS][OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1]; |
|
}; |
|
#define OR1K_32_MAX_INSNS 120 |
// This number should correspond to the maximum insn_index we assign in the |
// analyse function |
#define OR1K_32_MAX_INSNS 117 |
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS]; |
|
|
909,113 → 1082,65
// functions |
|
// Variable to keep track of unique instructions we have |
int num_unique_insns; |
int num_setup_insns; |
int num_seen_insns; |
|
|
void or1k_32_insn_lists_init(void) |
{ |
num_unique_insns = 0; |
num_setup_insns = 0; |
num_seen_insns = 0; |
// Clear the pointer array so we can tell if things are used or not |
memset(or1k_32_insns, '\0', |
sizeof(struct or1k_insn_info *)*OR1K_32_MAX_INSNS); |
} |
|
// List management/analysis functions |
int or1k_32_insn_lists_check(uint32_t insn, |
struct or1k_32_instruction_properties *insn_props) |
// Alloc struct and put it into the list |
void or1k_32_insn_lists_init_insn(uint32_t insn, |
struct or1k_32_instruction_properties *insn_props) |
{ |
|
int num_to_check = num_unique_insns; |
int insn_strlen = strlen(insn_props->insn_string); |
while (num_to_check) |
{ |
|
--num_to_check; |
|
if ((strncmp(insn_props->insn_string, |
or1k_32_insns[num_to_check]->insn_string, insn_strlen) == 0) |
&& (insn_strlen == strlen(or1k_32_insns[num_to_check]->insn_string))) |
{ |
// Found match by string |
return num_to_check; |
} |
} |
|
return IS_UNIQUE; |
} |
|
// Add a unique instruction |
int or1k_32_insn_lists_add_unique_insn(uint32_t insn, |
struct or1k_32_instruction_properties *insn_props) |
{ |
// Add an instruction in or1k_32_insns[num_unique_instructions]; |
// use calloc() so it clears it all first (hopefully!).. assumption! |
struct or1k_insn_info * new_insn |
= (struct or1k_insn_info *) calloc (sizeof(struct or1k_insn_info), 1); |
|
// Calloc() space for the string |
new_insn->insn_string = (char *) calloc(strlen(insn_props->insn_string), 1); |
// Copy the string pointer |
new_insn->insn_string = insn_props->insn_string, |
|
// Copy in the instruction string |
strncpy(new_insn->insn_string, insn_props->insn_string, |
strlen(insn_props->insn_string)); |
// Install the pointer for this newly allocated struct in its corresponding |
// index, as set when we decode the instruction |
or1k_32_insns[insn_props->insn_index] = new_insn; |
|
// Install the pointer for this new instruction in the list |
or1k_32_insns[num_unique_insns] = new_insn;; |
|
// Increment number of instructions we have |
num_unique_insns++; |
// Increment number of instructions we have set up |
num_setup_insns++; |
|
// Debugging: |
//printf("Adding %dth instruction - %s\n", |
//num_unique_insns, new_insn->insn_string); |
|
// Return index of newly created instruction |
return (num_unique_insns - 1); |
//num_setup_insns, new_insn->insn_string); |
|
} |
|
// Add to, or increment incidences of, value in the value list |
void or1k_add_in_list(struct or1k_value_list * list, int32_t value) |
{ |
int i; |
// See if it's already in the list |
i=list->count; |
|
while(i) |
{ |
i--; |
if(list->values[i][0] == value) |
{ |
(list->values[i][1])++; |
return; |
} |
} |
|
if (list->count < OR1K_VALUE_MAX_ENTRIES) |
{ |
// Not found, add it to the list |
list->values[(list->count)][0] = value; |
list->values[(list->count)][1] = 1; |
list->count++; |
} |
|
} |
|
|
// Add stats for this instruction |
void or1k_32_insn_lists_add(int index, uint32_t insn, |
void or1k_32_insn_lists_add(uint32_t insn, |
struct or1k_32_instruction_properties *insn_props) |
{ |
// Add stats for this instruction |
// Check if the entry for this instruction has been setup yet |
if (or1k_32_insns[insn_props->insn_index] == NULL) |
{ |
// Here we allocate space for the instruction's stats |
or1k_32_insn_lists_init_insn(insn, insn_props); |
} |
|
// Increment count |
((or1k_32_insns[index])->count)++; |
// Increment occurance count |
((or1k_32_insns[insn_props->insn_index])->count)++; |
|
// Add branch target value information, if instruction has it |
if (insn_props->has_branchtarg) |
{ |
(or1k_32_insns[index])->has_branchtarg = 1; |
or1k_add_in_list(&((or1k_32_insns[index])->branch_info), |
(or1k_32_insns[insn_props->insn_index])->has_branchtarg = 1; |
or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->branch_info), |
(int32_t)insn_or1k_opcode_0x03_get_branchoff(insn)); |
} |
|
1022,8 → 1147,8
// Add immediate value if it's got one |
if (insn_props->has_imm) |
{ |
(or1k_32_insns[index])->has_imm = 1; |
or1k_add_in_list(&((or1k_32_insns[index])->imm_info), |
(or1k_32_insns[insn_props->insn_index])->has_imm = 1; |
or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info), |
(int32_t)insn_or1k_32_imm(insn)); |
} |
|
1030,8 → 1155,8
// Add split immediate value if it's got one |
if (insn_props->has_split_imm) |
{ |
(or1k_32_insns[index])->has_imm = 1; |
or1k_add_in_list(&((or1k_32_insns[index])->imm_info), |
(or1k_32_insns[insn_props->insn_index])->has_imm = 1; |
or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info), |
(int32_t)insn_or1k_32_split_imm(insn)); |
} |
|
1039,24 → 1164,27
// Increment count of use for particular rD |
if (insn_props->has_rD) |
{ |
(or1k_32_insns[index])->has_rD = 1; |
((or1k_32_insns[index])->rD_use_freq[insn_or1k_32_rD(insn)])++; |
(or1k_32_insns[insn_props->insn_index])->has_rD = 1; |
((or1k_32_insns[insn_props->insn_index])->rD_use_freq[insn_or1k_32_rD(insn)])++; |
} |
|
// Increment count of use for particular rA |
if (insn_props->has_rA) |
{ |
(or1k_32_insns[index])->has_rA = 1; |
((or1k_32_insns[index])->rA_use_freq[insn_or1k_32_rA(insn)])++; |
(or1k_32_insns[insn_props->insn_index])->has_rA = 1; |
((or1k_32_insns[insn_props->insn_index])->rA_use_freq[insn_or1k_32_rA(insn)])++; |
} |
|
// Increment count of use for particular rB |
if (insn_props->has_rB) |
{ |
(or1k_32_insns[index])->has_rB = 1; |
((or1k_32_insns[index])->rB_use_freq[insn_or1k_32_rB(insn)])++; |
(or1k_32_insns[insn_props->insn_index])->has_rB = 1; |
((or1k_32_insns[insn_props->insn_index])->rB_use_freq[insn_or1k_32_rB(insn)])++; |
} |
|
|
// TODO: n-tuple groupings stats recording here! |
|
// Finished adding to stats for this instruction |
|
// Increment overall instructions "seen" counter |
1068,14 → 1196,12
// Free up all added instruction statistic tracking structs |
void or1k_32_insn_lists_free(void) |
{ |
while (num_unique_insns) |
// Free all entries we m/calloc()'d |
int insn_index; |
for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++) |
{ |
|
num_unique_insns--; |
|
free((or1k_32_insns[num_unique_insns]->insn_string)); |
free(or1k_32_insns[num_unique_insns]); |
|
if (or1k_32_insns[insn_index] != NULL) |
free(or1k_32_insns[insn_index]); |
} |
} |
|
1087,19 → 1213,20
{ |
// Print out most frequent instruction |
int i, largest, largest_index; |
int instructions_to_print = num_unique_insns; |
int instructions_to_print = num_setup_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; |
} |
|
for(i=0;i<OR1K_32_MAX_INSNS;i++) |
if (or1k_32_insns[i]!=NULL){ |
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", |
1121,81 → 1248,67
|
|
// 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) |
void or1k_32_insn_top_x(struct or1k_insn_info *insn_info, 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; |
fprintf(stream, |
"Insn: \"%s\" statistics (%d times (%f%%)):\n", |
insn_info->insn_string, |
insn_info->count, |
(float)(((float)((insn_info)->count))/ |
((float)num_seen_insns))*100.f |
); |
|
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)); |
// Start dumping applicable stats |
|
// Print out top max_stats branch targets |
|
if (insn_info.has_branchtarg) |
if (insn_info->has_branchtarg) |
{ |
fprintf(stream,"Branch values:\n"); |
i = 0; |
while(i<insn_info.branch_info.count && i < max_stats) |
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]) ? |
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 |
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) |
if (insn_info->has_imm) |
{ |
fprintf(stream,"Immediate values:\n"); |
i = 0; |
while(i<insn_info.imm_info.count && i < max_stats) |
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]) ? |
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 |
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) |
if (insn_info->has_rD) |
{ |
fprintf(stream,"rD usage:\n"); |
i = 0; |
1203,12 → 1316,12
{ |
largest_i=0; |
for(j=0;j<32;j++) |
largest_i = (insn_info.rD_use_freq[j] > |
insn_info.rD_use_freq[largest_i]) ? |
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) |
if (insn_info->rD_use_freq[largest_i] == 0) |
break; |
|
// largest_i has index of most frequent value |
1215,13 → 1328,13
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 |
insn_info->rD_use_freq[largest_i]); |
insn_info->rD_use_freq[largest_i] = -1; // clear this one |
i++; |
} |
} |
|
if (insn_info.has_rA) |
if (insn_info->has_rA) |
{ |
fprintf(stream,"rA usage:\n"); |
i = 0; |
1229,12 → 1342,12
{ |
largest_i=0; |
for(j=0;j<32;j++) |
largest_i = (insn_info.rA_use_freq[j] > |
insn_info.rA_use_freq[largest_i]) ? |
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) |
if (insn_info->rA_use_freq[largest_i] == 0) |
break; |
|
|
1242,13 → 1355,13
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 |
insn_info->rA_use_freq[largest_i]); |
insn_info->rA_use_freq[largest_i] = -1; // clear this one |
i++; |
} |
} |
|
if (insn_info.has_rB) |
if (insn_info->has_rB) |
{ |
fprintf(stream,"rB usage:\n"); |
i = 0; |
1256,12 → 1369,12
{ |
largest_i=0; |
for(j=0;j<32;j++) |
largest_i = (insn_info.rB_use_freq[j] > |
insn_info.rB_use_freq[largest_i]) ? |
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) |
if (insn_info->rB_use_freq[largest_i] == 0) |
break; |
|
|
1269,8 → 1382,8
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 |
insn_info->rB_use_freq[largest_i]); |
insn_info->rB_use_freq[largest_i] = -1; // clear this one |
i++; |
} |
} |
1284,11 → 1397,11
// |
|
// Print out all stats for every instruction we saw! |
int unique = num_unique_insns; |
while (unique) |
int insn_index; |
for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++) |
{ |
--unique; |
or1k_32_insn_top_x(or1k_32_insns[unique]->insn_string,stream,10); |
if (or1k_32_insns[insn_index] != NULL) |
or1k_32_insn_top_x(or1k_32_insns[insn_index],stream,10); |
} |
|
|
/analysis-bin/insnanalysis/insn-lists.h
12,14 → 12,9
// |
// Reset the variables/counters |
void insn_lists_init(void); |
// Check if an instruction is in the list already |
int insn_lists_check(instruction insn, |
instruction_properties *insn_props); |
// Add a new instruction to the list, return its index |
int insn_lists_add_unique_insn(instruction insn, |
instruction_properties *insn_props); |
|
// Report a new incidence of an instruction |
void insn_lists_add(int index, instruction insn, |
void insn_lists_add(instruction insn, |
instruction_properties *insn_props); |
|
// Free, clean up, anything we need to |
/analysis-bin/insnanalysis/or1k-32-insn.h
22,6 → 22,7
int has_rB; |
|
char *insn_string; |
int insn_index; |
|
}; |
|
42,16 → 43,8
// Reset lists |
void or1k_32_insn_lists_init(void); |
|
// Check for an instruction |
int or1k_32_insn_lists_check(uint32_t insn, |
struct or1k_32_instruction_properties *insn_props); |
|
// Add a unique instruction |
int or1k_32_insn_lists_add_unique_insn(uint32_t insn, |
struct or1k_32_instruction_properties *insn_props); |
|
// Add the stats for this one |
void or1k_32_insn_lists_add(int index, uint32_t insn, |
void or1k_32_insn_lists_add(uint32_t insn, |
struct or1k_32_instruction_properties *insn_props); |
|
// Print out some useful information |