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

Subversion Repositories or2k

[/] [or2k/] [trunk/] [analysis-bin/] [opcodeanalysis/] [opcodeanalysis.c] - Blame information for rev 9

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 julius
/*
2
  Instruction opcode frequency analysis application
3
 
4
  Author:
5
  Julius Baxter - julius.baxter@orsoc.se
6
 
7
*/
8
 
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <string.h>
12
 
13
// Opcode space in OR1K is 32-bits, so maximum 64 opcodes
14
#define MAX_OR1K_32_OPCODES 64
15
// Array of opcode string pointers (we malloc space for actual strings)
16
char *opcode_strings[MAX_OR1K_32_OPCODES];
17
// Count for occurance of each opcode
18
int opcode_count[MAX_OR1K_32_OPCODES];
19
 
20
// Maximum number of pairs
21
#define MAX_OR1K_32_PAIRS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
22
// 2-dimensional array, long enough to hold all possible pairs, and the 2
23
// indexes corresponding to their opcode in the *opcode_strings[] array
24
// Ie. Each will be: [previous_opcode][current_opcode][count]
25
int opcode_pairs[MAX_OR1K_32_PAIRS][3];
26
 
27
// Maximum number of pairs
28
#define MAX_OR1K_32_TRIPLETS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
29
// 2-dimensional array, long enough to hold all possible pairs, and the 2
30
// indexes corresponding to their opcode in the *opcode_strings[] array
31
// Ie. Each will be: [second_previous_opcode][first_previous_opcode][current_opcode][count]
32
int opcode_triplets[MAX_OR1K_32_TRIPLETS][4];
33
 
34
// Maximum number of pairs
35
#define MAX_OR1K_32_QUADS (MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES*MAX_OR1K_32_OPCODES)
36
// 2-dimensional array, long enough to hold all possible pairs, and the 2
37
// indexes corresponding to their opcode in the *opcode_strings[] array
38
// Ie. Each will be: [second_previous_opcode][first_previous_opcode][current_opcode][count]
39
int opcode_quads[MAX_OR1K_32_QUADS][5];
40
 
41
// Strings shouldn't be more than 32 bytes long
42
#define OPCODE_STRING_SIZE 32
43
 
44
// Indicator for an opcode we haven't seen before
45
#define IS_UNIQUE -1
46
 
47
// Result type
48
#define SORTED_DESCENDING_DISPLAY
49
 
50
// Little function to strip newlines
51
inline void strip_newline(char* str)
52
{
53
  int len = strlen(str);
54
  if (str[len-1] == '\n')
55
    str[len-1] = '\0';
56
 
57
}
58
 
59
// Return the position in the index this instruction is at
60
// else -1 if it isn't
61
int check_opcode(char *opcode_to_check, int num_opcodes_so_far)
62
{
63
  // Get stringlength of current instruction
64
  int opcode_strlen = strlen(opcode_to_check);
65
 
66
  int i = 0;
67
  // Loop for all opcodes we have so far
68
  while (i < num_opcodes_so_far)
69
    {
70
      // Do we have a match?
71
      // Debugging output
72
      //printf("Comparing: %s (%d) == %s (%d) ?\n", 
73
      //             opcode_to_check, opcode_strlen,
74
      //             opcode_strings[i], strlen(opcode_strings[i]));
75
      if ((strncmp(opcode_to_check, opcode_strings[i], opcode_strlen) == 0)
76
          && (strlen(opcode_strings[i]) == opcode_strlen))
77
        // Found a match - return its index
78
        return i;
79
      // No match yet, go to next opcode
80
      i++;
81
    }
82
  // No opcodes found, indicate it's one we haven't seen before
83
  return IS_UNIQUE;
84
}
85
 
86
// Record an opcode in our list of known opcodes
87
void add_opcode(char *opcode_to_add, int num_opcodes_so_far)
88
{
89
  int opcode_strlen = strlen(opcode_to_add);
90
 
91
  // Malloc space to hold the new opcode string
92
  char *new_opcode;
93
  new_opcode = (char*) calloc(OPCODE_STRING_SIZE, 1);
94
 
95
  // Copy in opcode string
96
  strncpy(new_opcode, opcode_to_add, opcode_strlen);
97
 
98
  // Now store the pointer to this new opcode string
99
  opcode_strings[num_opcodes_so_far] = new_opcode;
100
 
101
  // Initialise count
102
  opcode_count[num_opcodes_so_far] = 1;
103
 
104
  return;
105
}
106
 
107
// Increment the count for this opcode
108
void count_opcode(int opcode_index)
109
{
110
  opcode_count[opcode_index]++;
111
 
112
  return;
113
}
114
 
115
 
116
 
117
void display_opcodes(int total_unique_opcodes)
118
{
119
#ifdef SIMPLE_DISPLAY  
120
  while (total_unique_opcodes)
121
    {
122
      --total_unique_opcodes;
123
      printf("Opcode:\t%s\tCount:\t%d\n",
124
             opcode_strings[total_unique_opcodes],
125
             opcode_count[total_unique_opcodes]);
126
    }
127
#endif
128
#ifdef SORTED_DESCENDING_DISPLAY
129
  int i, largest, largest_index;
130
  int initial_total = total_unique_opcodes;
131
  while (total_unique_opcodes)
132
    {
133
      --total_unique_opcodes;
134
      largest=0;
135
      // Go through the list, find the largest, print it, eliminate it
136
      for(i=0;i<initial_total;i++)
137
        if(opcode_count[i] > largest)
138
          {
139
            largest = opcode_count[i];
140
            largest_index = i;
141
          }
142
 
143
      printf("Opcode:\t%s\tCount:\t%d\n",
144
             opcode_strings[largest_index],
145
             opcode_count[largest_index]);
146
 
147
      opcode_count[largest_index] = -1; // Eliminate this one
148
 
149
    }
150
#endif
151
 
152
}
153
 
154
// Deal with opcode pair checking
155
int opcode_pair_check( int previous_opcode_index, int current_opcode_index,
156
                       int total_pairs )
157
{
158
  int i;
159
  // Check through for this pair's occurance before
160
  for (i=0;i<total_pairs;i++)
161
    {
162
      if ((opcode_pairs[i][0] == previous_opcode_index) &&
163
          (opcode_pairs[i][1] == current_opcode_index))
164
        // Found a match
165
        {
166
          opcode_pairs[i][2]++;
167
          return 0;
168
        }
169
    }
170
  // No match, let's create a new entry
171
  // Index for previous opcode
172
  opcode_pairs[total_pairs][0] = previous_opcode_index;
173
  // Index for current opcode
174
  opcode_pairs[total_pairs][1] = current_opcode_index;
175
  // Count for this pair
176
  opcode_pairs[total_pairs][2] = 1;
177
 
178
  return 1;
179
 
180
}
181
 
182
 
183
void opcode_pair_report(int total_opcode_pairs)
184
{
185
 
186
  int i, largest, largest_index;
187
  int initial_total = total_opcode_pairs;
188
 
189
  while (total_opcode_pairs)
190
    {
191
      --total_opcode_pairs;
192
      largest=0;
193
      // Go through the list, find the largest, print it, eliminate it
194
      for(i=0;i<initial_total;i++)
195
        if(opcode_pairs[i][2] > largest)
196
          {
197
            largest = opcode_pairs[i][2];
198
            largest_index = i;
199
          }
200
 
201
      printf("Opcode pair:\t%s\t%s\tCount:\t%d\n",
202
             opcode_strings[opcode_pairs[largest_index][0]],
203
             opcode_strings[opcode_pairs[largest_index][1]],
204
             opcode_pairs[largest_index][2]);
205
 
206
      opcode_pairs[largest_index][2] = -1; // Eliminate this one
207
 
208
    }
209
 
210
 
211
}
212
 
213
// Deal with opcode triplet checking
214
int opcode_triplet_check(int second_previous_opcode_index,
215
                         int previous_opcode_index,
216
                         int current_opcode_index,
217
                         int sets_so_far )
218
{
219
  int i;
220
  // Check through for this pair's occurance before
221
  for (i=0;i<sets_so_far;i++)
222
    {
223
      if ((opcode_triplets[i][0] == second_previous_opcode_index) &&
224
          (opcode_triplets[i][1] == previous_opcode_index) &&
225
          (opcode_triplets[i][2] == current_opcode_index))
226
 
227
        // Found a match
228
        {
229
          opcode_triplets[i][3]++;
230
          return 0;
231
        }
232
    }
233
  // No match, let's create a new entry
234
  opcode_triplets[sets_so_far][0] = second_previous_opcode_index;
235
  // Index for previous opcode
236
  opcode_triplets[sets_so_far][1] = previous_opcode_index;
237
  // Index for current opcode
238
  opcode_triplets[sets_so_far][2] = current_opcode_index;
239
  // Count for this pair
240
  opcode_triplets[sets_so_far][3] = 1;
241
 
242
  return 1;
243
 
244
}
245
 
246
void opcode_triplet_report(int total_opcode_sets)
247
{
248
 
249
  int i, largest, largest_index;
250
  int initial_total = total_opcode_sets;
251
 
252
  while (total_opcode_sets)
253
    {
254
      --total_opcode_sets;
255
      largest=0;
256
      // Go through the list, find the largest, print it, eliminate it
257
      for(i=0;i<initial_total;i++)
258
        if(opcode_triplets[i][3] > largest)
259
          {
260
            largest = opcode_triplets[i][3];
261
            largest_index = i;
262
          }
263
 
264
      printf("Opcode triplet:\t%s\t%s\t%s\tCount:\t%d\n",
265
             opcode_strings[opcode_triplets[largest_index][0]],
266
             opcode_strings[opcode_triplets[largest_index][1]],
267
             opcode_strings[opcode_triplets[largest_index][2]],
268
             opcode_triplets[largest_index][3]);
269
 
270
      opcode_triplets[largest_index][3] = -1; // Eliminate this one
271
 
272
    }
273
}
274
 
275
// Deal with opcode triplet checking
276
int opcode_quad_check(int third_previous_opcode_index,
277
                      int second_previous_opcode_index,
278
                      int previous_opcode_index,
279
                      int current_opcode_index,
280
                      int sets_so_far )
281
{
282
  int i;
283
  // Check through for this pair's occurance before
284
  for (i=0;i<sets_so_far;i++)
285
    {
286
      if ((opcode_quads[i][0] == third_previous_opcode_index) &&
287
          (opcode_quads[i][1] == second_previous_opcode_index) &&
288
          (opcode_quads[i][2] == previous_opcode_index) &&
289
          (opcode_quads[i][3] == current_opcode_index))
290
 
291
        // Found a match
292
        {
293
          opcode_quads[i][4]++;
294
          return 0;
295
        }
296
    }
297
  // No match, let's create a new entry
298
  opcode_quads[sets_so_far][0] = third_previous_opcode_index;
299
  opcode_quads[sets_so_far][1] = second_previous_opcode_index;
300
  // Index for previous opcode
301
  opcode_quads[sets_so_far][2] = previous_opcode_index;
302
  // Index for current opcode
303
  opcode_quads[sets_so_far][3] = current_opcode_index;
304
  // Count for this pair
305
  opcode_quads[sets_so_far][4] = 1;
306
 
307
  return 1;
308
 
309
}
310
 
311
void opcode_quad_report(int total_opcode_sets)
312
{
313
 
314
  int i, largest, largest_index;
315
  int initial_total = total_opcode_sets;
316
 
317
  while (total_opcode_sets)
318
    {
319
      --total_opcode_sets;
320
      largest=0;
321
      // Go through the list, find the largest, print it, eliminate it
322
      for(i=0;i<initial_total;i++)
323
        if(opcode_quads[i][4] > largest)
324
          {
325
            largest = opcode_quads[i][4];
326
            largest_index = i;
327
          }
328
 
329
      printf("Opcode triplet:\t%s\t%s\t%s\t%s\tCount:\t%d\n",
330
             opcode_strings[opcode_quads[largest_index][0]],
331
             opcode_strings[opcode_quads[largest_index][1]],
332
             opcode_strings[opcode_quads[largest_index][2]],
333
             opcode_strings[opcode_quads[largest_index][3]],
334
             opcode_quads[largest_index][4]);
335
 
336
      opcode_quads[largest_index][4] = -1; // Eliminate this one
337
 
338
    }
339
}
340
 
341
 
342
int main(int argc, char *argv[])
343
{
344
  FILE *fp;
345
 
346
  char current_opcode[OPCODE_STRING_SIZE];
347
 
348
  int num_unique_opcodes = 0;
349
 
350
  int opcode_index;
351
 
352
  int total_seen_opcodes = 0;
353
 
354
  int previous_opcode_indexes[16]; // keep last 16 opcode indexes
355
 
356
  int i;
357
 
358
  int num_opcode_pairs = 0;
359
 
360
  int num_opcode_triplets = 0;
361
  int num_opcode_quads = 0;
362
 
363
 
364
 
365
  if((fp = fopen(argv[ 1 ], "r"))==NULL) {
366
    printf("Cannot open file.\n");
367
    exit(1);
368
  }
369
 
370
  // Do initial instruction set analysis
371
  while(!feof(fp)) {
372
    if(fgets(current_opcode, OPCODE_STRING_SIZE, fp))
373
      {
374
 
375
        strip_newline(current_opcode);
376
        //printf("Checking for: %s \n", current_opcode);
377
 
378
        // Find if we have this opcode already, if so we'll get its index in
379
        // the list, else we'll get an indication that it's unique
380
        opcode_index = check_opcode(current_opcode, num_unique_opcodes);
381
 
382
        if (opcode_index == IS_UNIQUE)
383
          {
384
            // Add this opcode to our list so we know it now
385
            add_opcode(current_opcode, num_unique_opcodes);
386
            // Increment the number of known opcodes
387
            num_unique_opcodes++;
388
          }
389
        else
390
          // Is not unique, just increment the incidences of this opcode
391
          count_opcode(opcode_index);
392
 
393
        // Track the total number of opcodes we've looked at
394
        total_seen_opcodes++;
395
 
396
        // Error check - bail out early if we're doing something wrong and
397
        // there's too many unique opcodes (ISA is only so big...)
398
        if (num_unique_opcodes == MAX_OR1K_32_OPCODES)
399
          {
400
            printf("Error: Reached maximum opcodes\n");
401
            break;
402
          }
403
 
404
        //printf("So far: unique: %d total: %d\n", 
405
        //num_unique_opcodes, total_seen_opcodes);
406
 
407
      }
408
  }
409
 
410
 
411
  // Totals
412
  printf("Number of total opcodes: %d\n",total_seen_opcodes);
413
  printf("Number unique opcodes: %d\n", num_unique_opcodes);
414
 
415
  // Print some more detailed information
416
  display_opcodes(num_unique_opcodes);
417
 
418
  printf("Beginning groups analysis\n");
419
 
420
  // Now do groups analysis
421
  rewind(fp);
422
 
423
  // Reset total_seen_opcodes, we'll count through the list again
424
 
425
  total_seen_opcodes = 0;
426
 
427
  while(!feof(fp)) {
428
    if(fgets(current_opcode, OPCODE_STRING_SIZE, fp))
429
      {
430
 
431
        total_seen_opcodes++;
432
 
433
        strip_newline(current_opcode);
434
 
435
        // Find if we have this opcode already, if so we'll get its index in
436
        // the list, else we'll get an indication that it's unique
437
        opcode_index = check_opcode(current_opcode, num_unique_opcodes);
438
 
439
        if (opcode_index == IS_UNIQUE)
440
          {
441
            // Error! Should not have unique opcodes here...
442
            printf("Unique opcode detected during pair analysis.\n");
443
            break;
444
          }
445
 
446
        // Now pass this current pair to the function to check if we've seen
447
        // it before - if not we record it (and return 1) else we just increment
448
        // count of it (and return 0)
449
        if (total_seen_opcodes > 1)
450
          {
451
            if (opcode_pair_check(previous_opcode_indexes[0], opcode_index,
452
                                  num_opcode_pairs))
453
              num_opcode_pairs++;
454
          }
455
 
456
        if (total_seen_opcodes > 2)
457
          {
458
            if (opcode_triplet_check(previous_opcode_indexes[1],
459
                                     previous_opcode_indexes[0],
460
                                     opcode_index,
461
                                     num_opcode_triplets))
462
              num_opcode_triplets++;
463
          }
464
        if (total_seen_opcodes > 3)
465
          {
466
            if (opcode_quad_check(previous_opcode_indexes[2],
467
                                  previous_opcode_indexes[1],
468
                                  previous_opcode_indexes[0],
469
                                  opcode_index,
470
                                  num_opcode_quads))
471
              num_opcode_quads++;
472
          }
473
        // Shift along our list of previously seen opcodes
474
        for (i=16-1;i > 0; i--)
475
          previous_opcode_indexes[i] = previous_opcode_indexes[i-1];
476
 
477
        previous_opcode_indexes[0] = opcode_index;
478
 
479
      }
480
  }
481
 
482
 
483
  printf("Number of unique opcode pairs: %d\n", num_opcode_pairs);
484
 
485
  // Report opcode pairs (will be a lot, > 1000)
486
  opcode_pair_report(num_opcode_pairs);
487
 
488
 
489
  printf("Number of unique opcode triplets: %d\n", num_opcode_triplets);
490
 
491
  // Report opcode pairs (will be a lot, > 1000)
492
  opcode_triplet_report(num_opcode_pairs);
493
 
494
  printf("Number of opcode quads: %d\n", num_opcode_quads);
495
 
496
  // Report opcode pairs (will be a lot, > 1000)
497
  opcode_quad_report(num_opcode_quads);
498
 
499
 // Close file pointer, we're done with it
500
  fclose(fp);
501
 
502
 
503
  // Free all the strings we declared
504
  while(num_unique_opcodes)
505
    {
506
      --num_unique_opcodes;
507
      free(opcode_strings[num_unique_opcodes]);
508
    }
509
 
510
  //printf("freeing complete: %d\n", num_unique_opcodes);
511
 
512
  return 0;
513
}

powered by: WebSVN 2.1.0

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