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

Subversion Repositories or2k

[/] [or2k/] [trunk/] [analysis-bin/] [insnanalysis/] [or1k-32-insn.c] - Blame information for rev 28

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 julius
/*
2
  Or1K instruction set-specific decoding and analysis functions.
3
 
4
  Julius Baxter, julius.baxter@orsoc.se
5
 
6
*/
7
 
8
 
9 16 julius
#include "stdio.h"
10
#include "stdint.h"
11
#include "stdlib.h"
12
#include "string.h"
13 20 julius
#include "assert.h"
14 16 julius
#include "or1k-32-insn.h"
15
 
16 22 julius
// Define the appropriate instruction type, and instruction_properties type
17
// These should also be defined in insnanalysis.h
18 16 julius
typedef uint32_t instruction;
19
typedef struct or1k_32_instruction_properties instruction_properties ;
20
 
21
#include "insn-lists.h"
22
 
23 19 julius
// Variable to keep track of unique instructions we have
24
int num_setup_insns;
25
int num_seen_insns;
26
 
27
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
28
 
29
// Keep enough instructions required to do the maximum n-tuple set
30
// analysis.
31
int or1k_32_recent_insns[OR1K_MAX_GROUPINGS_ANALYSIS];
32
 
33 22 julius
// Function to take the raw binary instruction, and configure the insn_props
34
// struct with the appropriate settings for that instruction (string, attributes
35
// etc.)
36
// TODO: vector instructions aren't picked up - but compiler never generates
37
// them, so not a big issue.
38 16 julius
int or1k_32_analyse_insn(uint32_t insn,
39
                         struct or1k_32_instruction_properties  * insn_props)
40
{
41
 
42
  switch(insn_or1k_opcode(insn))
43
    {
44
    case 0x00:
45
      insn_props->insn_string="l.j";
46 18 julius
      insn_props->insn_index=0;
47 16 julius
      insn_props->has_jumptarg = 1;
48
      break;
49
 
50
    case 0x01:
51
      insn_props->insn_string="l.jal";
52 18 julius
      insn_props->insn_index=1;
53 16 julius
      insn_props->has_jumptarg = 1;
54
      break;
55
 
56
     case 0x03:
57
      insn_props->insn_string="l.bnf";
58 18 julius
      insn_props->insn_index=2;
59 16 julius
      insn_props->has_branchtarg = 1;
60
      break;
61
 
62
    case 0x04:
63
      insn_props->insn_string="l.bf";
64 18 julius
      insn_props->insn_index=3;
65 16 julius
      insn_props->has_branchtarg = 1;
66
      break;
67
 
68
    case 0x05:
69
      insn_props->insn_string="l.nop";
70 18 julius
      insn_props->insn_index=4;
71 16 julius
      break;
72
 
73
    case 0x06:
74
      if((insn_or1k_opcode_0x06_get_id(insn)))
75 18 julius
        {
76
          insn_props->insn_string="l.macrc";
77
          insn_props->insn_index=5;
78
        }
79 16 julius
      else
80
        {
81
          insn_props->insn_string="l.movhi";
82 18 julius
          insn_props->insn_index=6;
83 16 julius
          insn_props->has_rD = 1;
84
          insn_props->has_imm = 1;
85
        }
86
 
87
      break;
88
 
89
    case 0x08:
90
 
91
      switch(insn_or1k_opcode_0x08_get_id(insn))
92
        {
93
        case 0x0:
94
          insn_props->insn_string="l.sys";
95 18 julius
          insn_props->insn_index=7;
96 20 julius
          insn_props->has_imm = 1;
97 16 julius
          break;
98
        case 0x2:
99
          insn_props->insn_string="l.trap";
100 18 julius
          insn_props->insn_index=8;
101 16 julius
          break;
102
        case 0x4:
103
          insn_props->insn_string="l.msync";
104 18 julius
          insn_props->insn_index=9;
105 16 julius
          break;
106
        case 0x5:
107
          insn_props->insn_string="l.psync";
108 18 julius
          insn_props->insn_index=10;
109 16 julius
          break;
110
        case 0x6:
111
          insn_props->insn_string="l.csync";
112 18 julius
          insn_props->insn_index=11;
113 16 julius
          break;
114
        default:
115
          printf("Unknown id (0x%x) in opcode 0x8",
116
                 insn_or1k_opcode_0x08_get_id(insn) );
117
          return 1;
118
          break;
119
        }
120
      break;
121
 
122
    case 0x09:
123
      insn_props->insn_string="l.rfe";
124 18 julius
      insn_props->insn_index=12;
125 16 julius
      break;
126
 
127
    case 0x0a:
128
      switch(insn_or1k_opcode_0x0a_get_op_hi(insn))
129
        {
130
        case 0x1:
131
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
132
            {
133
            case 0x0:
134
              break;
135
            case 0x1:
136
              break;
137
            case 0x2:
138
              break;
139
            case 0x3:
140
              break;
141
            case 0x4:
142
              break;
143
            case 0x5:
144
              break;
145
            case 0x6:
146
              break;
147
            case 0x7:
148
              break;
149
            case 0x8:
150
              break;
151
            case 0x9:
152
              break;
153
            case 0xa:
154
              break;
155
            case 0xb:
156
              break;
157
            default:
158
              printf("Unknown lv.all_xx insn");
159 17 julius
              return 1;
160 16 julius
            }
161
        case 0x2:
162
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
163
            {
164
            case 0x0:
165
              break;
166
            case 0x1:
167
              break;
168
            case 0x2:
169
              break;
170
            case 0x3:
171
              break;
172
            case 0x4:
173
              break;
174
            case 0x5:
175
              break;
176
            case 0x6:
177
              break;
178
            case 0x7:
179
              break;
180
            case 0x8:
181
              break;
182
            case 0x9:
183
              break;
184
            case 0xa:
185
              break;
186
            case 0xb:
187
              break;
188
            default:
189
              printf("Unknown lv.any_xx insn");
190 17 julius
              return 1;
191 16 julius
            }
192
          break;
193
        case 0x3:
194
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
195
            {
196
            case 0x0:
197
              break;
198
            case 0x1:
199
              break;
200
            case 0x2:
201
              break;
202
            case 0x3:
203
              break;
204
            case 0x4:
205
              break;
206
            case 0x5:
207
              break;
208
            case 0x6:
209
              break;
210
            case 0x7:
211
              break;
212
            case 0x8:
213
              break;
214
            case 0x9:
215
              break;
216
            case 0xa:
217
              break;
218
            default:
219
              printf("Unknown lv.add/and/avg_xx insn");
220 17 julius
              return 1;
221 16 julius
            }
222
          break;
223
        case 0x4:
224
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
225
            {
226
            case 0x0:
227
              break;
228
            case 0x1:
229
              break;
230
            case 0x2:
231
              break;
232
            case 0x3:
233
              break;
234
            case 0x4:
235
              break;
236
            case 0x5:
237
              break;
238
            case 0x6:
239
              break;
240
            case 0x7:
241
              break;
242
            case 0x8:
243
              break;
244
            case 0x9:
245
              break;
246
            case 0xa:
247
              break;
248
            case 0xb:
249
              break;
250
            default:
251
              printf("Unknown lv.cmp_xx insn");
252 17 julius
              return 1;
253 16 julius
            }
254
          break;
255
        case 0x5:
256
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
257
            {
258
            case 0x4:
259
              break;
260
            case 0x5:
261
              break;
262
            case 0x6:
263
              break;
264
            case 0x7:
265
              break;
266
            case 0x8:
267
              break;
268
            case 0x9:
269
              break;
270
            case 0xa:
271
              break;
272
            case 0xb:
273
              break;
274
            case 0xc:
275
              break;
276
            case 0xd:
277
              break;
278
            case 0xe:
279
              break;
280
            case 0xf:
281
              break;
282
            default:
283
              printf("Unknown lv.alu_xx insn");
284 17 julius
              return 1;
285 16 julius
            }
286
          break;
287
        case 0x6:
288
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
289
            {
290
            case 0x0:
291
              break;
292
            case 0x1:
293
              break;
294
            case 0x2:
295
              break;
296
            case 0x3:
297
              break;
298
            case 0x4:
299
              break;
300
            case 0x5:
301
              break;
302
            case 0x6:
303
              break;
304
            case 0x7:
305
              break;
306
            case 0x8:
307
              break;
308
            case 0x9:
309
              break;
310
            case 0xa:
311
              break;
312
            case 0xb:
313
              break;
314
            case 0xc:
315
              break;
316
            case 0xd:
317
              break;
318
            case 0xe:
319
              break;
320
            case 0xf:
321
              break;
322
            default:
323
              printf("Unknown lv.pack_xx insn");
324 17 julius
              return 1;
325 16 julius
            }
326
          break;
327
        case 0x7:
328
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
329
            {
330
            case 0x0:
331
              break;
332
            case 0x1:
333
              break;
334
            case 0x2:
335
              break;
336
            case 0x3:
337
              break;
338
            case 0x4:
339
              break;
340
            case 0x5:
341
              break;
342
            case 0x6:
343
              break;
344
            case 0x7:
345
              break;
346
            case 0x8:
347
              break;
348
            case 0x9:
349
              break;
350
            case 0xa:
351
              break;
352
            case 0xb:
353
              break;
354
            default:
355
              printf("Unknown lv.sub/unpack/xor_xx insn");
356 17 julius
              return 1;
357 16 julius
            }
358
          break;
359
        case 0xc:
360
          break;
361
        case 0xd:
362
          break;
363
        case 0xe:
364
          break;
365
        case 0xf:
366
          break;
367
        default:
368
          printf("Unknown lv.xxx insn hi op");
369 17 julius
          return 1;
370 16 julius
          break;
371
        }
372
      break;
373
 
374
    case 0x11:
375
      insn_props->insn_string="l.jr";
376 18 julius
      insn_props->insn_index=13;
377 16 julius
      insn_props->has_rB = 1;
378
      break;
379
 
380
    case 0x12:
381
      insn_props->insn_string="l.jalr";
382 18 julius
      insn_props->insn_index=14;
383 16 julius
      insn_props->has_rB = 1;
384
      break;
385
 
386
    case 0x13:
387
      insn_props->insn_string="l.maci";
388 18 julius
      insn_props->insn_index=15;
389 16 julius
      break;
390
 
391
    case 0x1c:
392
      insn_props->insn_string="l.cust1";
393 18 julius
      insn_props->insn_index=16;
394 16 julius
      break;
395
 
396
    case 0x1d:
397
      insn_props->insn_string="l.cust2";
398 18 julius
      insn_props->insn_index=17;
399 16 julius
      break;
400
 
401
    case 0x1e:
402
      insn_props->insn_string="l.cust3";
403 18 julius
      insn_props->insn_index=18;
404 16 julius
      break;
405
 
406
    case 0x1f:
407
      insn_props->insn_string="l.cust4";
408 18 julius
      insn_props->insn_index=19;
409 16 julius
      break;
410
 
411
    case 0x20:
412
      insn_props->insn_string="l.ld";
413 18 julius
      insn_props->insn_index=20;
414 16 julius
      insn_props->has_rD = 1;
415
      insn_props->has_rA = 1;
416
      insn_props->has_imm = 1;
417
      break;
418
 
419
    case 0x21:
420
      insn_props->insn_string="l.lwz";
421 18 julius
      insn_props->insn_index=21;
422 16 julius
      insn_props->has_rD = 1;
423
      insn_props->has_rA = 1;
424
      insn_props->has_imm = 1;
425
      break;
426
 
427
    case 0x22:
428
      insn_props->insn_string="l.lws";
429 18 julius
      insn_props->insn_index=22;
430 16 julius
      insn_props->has_rD = 1;
431
      insn_props->has_rA = 1;
432
      insn_props->has_imm = 1;
433
      break;
434
 
435
    case 0x23:
436
      insn_props->insn_string="l.lbz";
437 18 julius
      insn_props->insn_index=23;
438 16 julius
      insn_props->has_rD = 1;
439
      insn_props->has_rA = 1;
440
      insn_props->has_imm = 1;
441
      break;
442
 
443
    case 0x24:
444
      insn_props->insn_string="l.lbs";
445 18 julius
      insn_props->insn_index=24;
446 16 julius
      insn_props->has_rD = 1;
447
      insn_props->has_rA = 1;
448
      insn_props->has_imm = 1;
449
      break;
450
 
451
    case 0x25:
452
      insn_props->insn_string="l.lhz";
453 18 julius
      insn_props->insn_index=25;
454 16 julius
      insn_props->has_rD = 1;
455
      insn_props->has_rA = 1;
456
      insn_props->has_imm = 1;
457
      break;
458
 
459
    case 0x26:
460
      insn_props->insn_string="l.lhs";
461 18 julius
      insn_props->insn_index=26;
462 16 julius
      insn_props->has_rD = 1;
463
      insn_props->has_rA = 1;
464
      insn_props->has_imm = 1;
465
      break;
466
 
467
 
468
    case 0x27:
469
      insn_props->insn_string="l.addi";
470 18 julius
      insn_props->insn_index=27;
471 16 julius
      insn_props->has_rD = 1;
472
      insn_props->has_rA = 1;
473
      insn_props->has_imm = 1;
474
      break;
475
 
476
    case 0x28:
477
      insn_props->insn_string="l.addic";
478 18 julius
      insn_props->insn_index=28;
479 16 julius
      insn_props->has_rD = 1;
480
      insn_props->has_rA = 1;
481
      insn_props->has_imm = 1;
482
      break;
483
 
484
    case 0x29:
485
      insn_props->insn_string="l.andi";
486 18 julius
      insn_props->insn_index=29;
487 16 julius
      insn_props->has_rD = 1;
488
      insn_props->has_rA = 1;
489
      insn_props->has_imm = 1;
490
      break;
491
 
492
    case 0x2a:
493
      insn_props->insn_string="l.ori";
494 18 julius
      insn_props->insn_index=30;
495 16 julius
      insn_props->has_rD = 1;
496
      insn_props->has_rA = 1;
497
      insn_props->has_imm = 1;
498
      break;
499
 
500
    case 0x2b:
501
      insn_props->insn_string="l.xori";
502 18 julius
      insn_props->insn_index=31;
503 16 julius
      insn_props->has_rD = 1;
504
      insn_props->has_rA = 1;
505
      insn_props->has_imm = 1;
506
      break;
507
 
508
    case 0x2c:
509
      insn_props->insn_string="l.muli";
510 18 julius
      insn_props->insn_index=32;
511 16 julius
      insn_props->has_rD = 1;
512
      insn_props->has_rA = 1;
513
      insn_props->has_imm = 1;
514
      break;
515
 
516
    case 0x2d:
517
      insn_props->insn_string="l.mfspr";
518 18 julius
      insn_props->insn_index=33;
519 16 julius
      insn_props->has_rD = 1;
520
      insn_props->has_rA = 1;
521
      insn_props->has_imm = 1;
522
      break;
523
 
524
    case 0x2e:
525
      switch(insn_or1k_opcode_0x2e_get_op(insn))
526
        {
527
        case 0x0:
528
          insn_props->insn_string="l.slli";
529 18 julius
          insn_props->insn_index=34;
530 16 julius
          break;
531
        case 0x1:
532
          insn_props->insn_string="l.srli";
533 18 julius
          insn_props->insn_index=35;
534 16 julius
          break;
535
        case 0x2:
536
          insn_props->insn_string="l.srai";
537 18 julius
          insn_props->insn_index=36;
538 16 julius
          break;
539
        case 0x3:
540
          insn_props->insn_string="l.rori";
541 18 julius
          insn_props->insn_index=37;
542 16 julius
          break;
543
        default:
544
          printf("Unknown shift op (0x%x)",
545
                 insn_or1k_opcode_0x2e_get_op(insn));
546 17 julius
          return 1;
547 16 julius
          break;
548
        }
549
      break;
550
 
551
    case 0x2f:
552
      switch(insn_or1k_opcode_0x2f_get_op(insn))
553
        {
554
        case 0x0:
555
          insn_props->insn_string="l.sfeqi";
556 18 julius
          insn_props->insn_index=38;
557 16 julius
          break;
558
        case 0x1:
559
          insn_props->insn_string="l.sfnei";
560 18 julius
          insn_props->insn_index=39;
561 16 julius
          break;
562
        case 0x2:
563
          insn_props->insn_string="l.sfgtui";
564 18 julius
          insn_props->insn_index=40;
565 16 julius
          break;
566
        case 0x3:
567
          insn_props->insn_string="l.sfgeui";
568 18 julius
          insn_props->insn_index=41;
569 16 julius
          break;
570
        case 0x4:
571
          insn_props->insn_string="l.sfltui";
572 18 julius
          insn_props->insn_index=42;
573 16 julius
          break;
574
        case 0x5:
575
          insn_props->insn_string="l.sfleui";
576 18 julius
          insn_props->insn_index=43;
577 16 julius
          break;
578
        case 0xa:
579
          insn_props->insn_string="l.sfgtsi";
580 18 julius
          insn_props->insn_index=44;
581 16 julius
          break;
582
        case 0xb:
583
          insn_props->insn_string="l.sfgesi";
584 18 julius
          insn_props->insn_index=45;
585 16 julius
          break;
586
        case 0xc:
587
          insn_props->insn_string="l.sfltsi";
588 18 julius
          insn_props->insn_index=46;
589 16 julius
          break;
590
        case 0xd:
591
          insn_props->insn_string="l.sflesi";
592 18 julius
          insn_props->insn_index=47;
593 16 julius
          break;
594
 
595
        default:
596
          printf("Unknown set flag op (0x%x)",
597
                 insn_or1k_opcode_0x2f_get_op(insn));
598 17 julius
          return 1;
599 16 julius
          break;
600
        }
601
      insn_props->has_rA = 1;
602
      insn_props->has_imm = 1;
603
      break;
604
 
605
 
606
    case 0x30:
607
      insn_props->insn_string="l.mtspr";
608 18 julius
      insn_props->insn_index=48;
609 16 julius
      break;
610
 
611
    case 0x31:
612
      switch (insn_or1k_opcode_0x31_get_op(insn))
613
        {
614
        case 0x1:
615
          insn_props->insn_string="l.mac";
616 18 julius
          insn_props->insn_index=49;
617 16 julius
          break;
618
        case 0x2:
619
          insn_props->insn_string="l.msb";
620 18 julius
          insn_props->insn_index=50;
621 16 julius
          break;
622
        default:
623
          printf("Unknown mac op (0x%x)",
624
                 insn_or1k_opcode_0x31_get_op(insn));
625 17 julius
          return 1;
626 16 julius
        }
627
      break;
628
 
629
    case 0x32:
630
      switch(insn_or1k_opcode_0x32_get_op_hi(insn))
631
        {
632
        case 0x0:
633
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
634
            {
635
            case 0x0:
636
              insn_props->insn_string="lf.add.s";
637 18 julius
              insn_props->insn_index=51;
638 16 julius
              break;
639
            case 0x1:
640
              insn_props->insn_string="lf.sub.s";
641 18 julius
              insn_props->insn_index=52;
642 16 julius
              break;
643
            case 0x2:
644
              insn_props->insn_string="lf.mul.s";
645 18 julius
              insn_props->insn_index=53;
646 16 julius
              break;
647
            case 0x3:
648
              insn_props->insn_string="lf.div.s";
649 18 julius
              insn_props->insn_index=54;
650 16 julius
              break;
651
            case 0x4:
652
              insn_props->insn_string="lf.itof.s";
653 18 julius
              insn_props->insn_index=55;
654 16 julius
              break;
655
            case 0x5:
656
              insn_props->insn_string="lf.ftoi.s";
657 18 julius
              insn_props->insn_index=56;
658 16 julius
              break;
659
            case 0x6:
660
              insn_props->insn_string="lf.rem.s";
661 18 julius
              insn_props->insn_index=57;
662 16 julius
              break;
663
            case 0x7:
664
              insn_props->insn_string="lf.madd.s";
665 18 julius
              insn_props->insn_index=58;
666 16 julius
              break;
667
            case 0x8:
668
              insn_props->insn_string="lf.sfeq.s";
669 18 julius
              insn_props->insn_index=59;
670 16 julius
              break;
671
            case 0x9:
672
              insn_props->insn_string="lf.sfne.s";
673 18 julius
              insn_props->insn_index=60;
674 16 julius
              break;
675
            case 0xa:
676
              insn_props->insn_string="lf.sfgt.s";
677 18 julius
              insn_props->insn_index=61;
678 16 julius
              break;
679
            case 0xb:
680
              insn_props->insn_string="lf.sfge.s";
681 18 julius
              insn_props->insn_index=62;
682 16 julius
              break;
683
            case 0xc:
684
              insn_props->insn_string="lf.sflt.s";
685 18 julius
              insn_props->insn_index=63;
686 16 julius
              break;
687
            case 0xd:
688
              insn_props->insn_string="lf.sfle.s";
689 18 julius
              insn_props->insn_index=64;
690 16 julius
              break;
691
            default:
692
              printf("Unknown lf.xxx.s op (0x%x)",
693
                     insn_or1k_opcode_0x32_get_op_lo(insn));
694
              break;
695
            }
696
          break;
697
 
698
        case 0x1:
699
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
700
            {
701
            case 0x0:
702
              insn_props->insn_string="lf.add.d";
703 18 julius
              insn_props->insn_index=65;
704 16 julius
              break;
705
            case 0x1:
706
              insn_props->insn_string="lf.sub.d";
707 18 julius
              insn_props->insn_index=66;
708 16 julius
              break;
709
            case 0x2:
710
              insn_props->insn_string="lf.mul.d";
711 18 julius
              insn_props->insn_index=67;
712 16 julius
              break;
713
            case 0x3:
714
              insn_props->insn_string="lf.div.d";
715 18 julius
              insn_props->insn_index=68;
716 16 julius
              break;
717
            case 0x4:
718
              insn_props->insn_string="lf.itof.d";
719 18 julius
              insn_props->insn_index=69;
720 16 julius
              break;
721
            case 0x5:
722
              insn_props->insn_string="lf.ftoi.d";
723 18 julius
              insn_props->insn_index=70;
724 16 julius
              break;
725
            case 0x6:
726
              insn_props->insn_string="lf.rem.d";
727 18 julius
              insn_props->insn_index=71;
728 16 julius
              break;
729
            case 0x7:
730
              insn_props->insn_string="lf.madd.d";
731 18 julius
              insn_props->insn_index=72;
732 16 julius
              break;
733
            case 0x8:
734
              insn_props->insn_string="lf.sfeq.d";
735 18 julius
              insn_props->insn_index=73;
736 16 julius
              break;
737
            case 0x9:
738
              insn_props->insn_string="lf.sfne.d";
739 18 julius
              insn_props->insn_index=74;
740 16 julius
              break;
741
            case 0xa:
742
              insn_props->insn_string="lf.sfgt.d";
743 18 julius
              insn_props->insn_index=75;
744 16 julius
              break;
745
            case 0xb:
746
              insn_props->insn_string="lf.sfge.d";
747 18 julius
              insn_props->insn_index=76;
748 16 julius
              break;
749
            case 0xc:
750
              insn_props->insn_string="lf.sflt.d";
751 18 julius
              insn_props->insn_index=77;
752 16 julius
              break;
753
            case 0xd:
754
              insn_props->insn_string="lf.sfle.d";
755 18 julius
              insn_props->insn_index=78;
756 16 julius
              break;
757
            default:
758
              printf("Unknown lf.xxx.d op (0x%x)",
759
                     insn_or1k_opcode_0x32_get_op_lo(insn));
760
              break;
761
            }
762
          break;
763
 
764
        case 0xd:
765
          insn_props->insn_string="lf.cust1.s";
766 18 julius
          insn_props->insn_index=79;
767 16 julius
          break;
768
 
769
        case 0xe:
770
          insn_props->insn_string="lf.cust1.d";
771 18 julius
          insn_props->insn_index=80;
772 16 julius
          break;
773
 
774
        default:
775
          printf("Unknown lf.xxx opcode hi (0x%x)",
776
                 insn_or1k_opcode_0x32_get_op_hi(insn));
777 17 julius
          return 1;
778 16 julius
          break;
779
        }
780
      break;
781 28 julius
      // The l.sx instructions'd rD is actually in the location rA is for 
782
      // every other instruction - so we specify has_rA, but really that's 
783
      // the rD, so it's l.sx imm(rA), rB
784 16 julius
    case 0x34:
785
      insn_props->insn_string="l.sd";
786 18 julius
      insn_props->insn_index=81;
787 28 julius
      insn_props->has_rA = 1;
788
      insn_props->has_rB = 1;
789 16 julius
      break;
790
 
791
    case 0x35:
792
      insn_props->insn_string="l.sw";
793 28 julius
      insn_props->has_rA = 1;
794
      insn_props->has_rB = 1;
795 20 julius
      insn_props->has_split_imm = 1;
796 18 julius
      insn_props->insn_index=82;
797 16 julius
      break;
798
 
799
    case 0x36:
800
      insn_props->insn_string="l.sb";
801 28 julius
      insn_props->has_rA = 1;
802
      insn_props->has_rB = 1;
803 20 julius
      insn_props->has_split_imm = 1;
804 18 julius
      insn_props->insn_index=83;
805 16 julius
      break;
806
 
807
    case 0x37:
808
      insn_props->insn_string="l.sh";
809 28 julius
      insn_props->has_rA = 1;
810
      insn_props->has_rB = 1;
811 20 julius
      insn_props->has_split_imm = 1;
812 18 julius
      insn_props->insn_index=84;
813 16 julius
      break;
814
 
815
    case 0x38:
816 17 julius
       insn_props->has_rD = 1;
817
       insn_props->has_rA = 1;
818
       insn_props->has_rB = 1;
819
       switch(insn_or1k_opcode_0x38_get_op_lo(insn))
820
         {
821
         case 0x0:
822 16 julius
          insn_props->insn_string="l.add";
823 18 julius
          insn_props->insn_index=85;
824 16 julius
          break;
825
        case 0x1:
826
          insn_props->insn_string="l.addc";
827 18 julius
          insn_props->insn_index=86;
828 16 julius
          break;
829
        case 0x2:
830
          insn_props->insn_string="l.sub";
831 18 julius
          insn_props->insn_index=87;
832 16 julius
          break;
833
        case 0x3:
834
          insn_props->insn_string="l.and";
835 18 julius
          insn_props->insn_index=88;
836 16 julius
          break;
837
        case 0x4:
838
          insn_props->insn_string="l.or";
839 18 julius
          insn_props->insn_index=89;
840 16 julius
          break;
841
        case 0x5:
842
          insn_props->insn_string="l.xor";
843 18 julius
          insn_props->insn_index=90;
844 16 julius
          break;
845
        case 0x6:
846
          insn_props->insn_string="l.mul";
847 18 julius
          insn_props->insn_index=91;
848 16 julius
          break;
849
        case 0x8:
850
          switch (insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
851
            {
852
            case 0x0:
853
              insn_props->insn_string="l.sll";
854 18 julius
              insn_props->insn_index=92;
855 16 julius
              break;
856
            case 0x1:
857
              insn_props->insn_string="l.srl";
858 18 julius
              insn_props->insn_index=93;
859 16 julius
              break;
860
            case 0x2:
861
              insn_props->insn_string="l.sra";
862 18 julius
              insn_props->insn_index=94;
863 16 julius
              break;
864
            case 0x3:
865
              insn_props->insn_string="l.ror";
866 18 julius
              insn_props->insn_index=95;
867 16 julius
              break;
868
            default:
869
              printf("Unknown ALU op 0x8 hi op (0x%x)",
870
                     insn_or1k_opcode_0x38_get_op_hi_4bit(insn));
871 17 julius
              return 1;
872 16 julius
              break;
873
            }
874
          break;
875
        case 0x9:
876
          insn_props->insn_string="l.div";
877 18 julius
          insn_props->insn_index=96;
878 16 julius
          break;
879
        case 0xa:
880
          insn_props->insn_string="l.divu";
881 18 julius
          insn_props->insn_index=97;
882 16 julius
          break;
883
        case 0xb:
884
          insn_props->insn_string="l.mulu";
885 18 julius
          insn_props->insn_index=98;
886 16 julius
          break;
887
        case 0xc:
888
          switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
889
            {
890
            case 0x0:
891
              insn_props->insn_string="l.exths";
892 18 julius
              insn_props->insn_index=99;
893 16 julius
              break;
894
            case 0x1:
895
              insn_props->insn_string="l.extbs";
896 18 julius
              insn_props->insn_index=100;
897 16 julius
              break;
898
            case 0x2:
899
              insn_props->insn_string="l.exthz";
900 18 julius
              insn_props->insn_index=101;
901 16 julius
              break;
902
            case 0x3:
903
              insn_props->insn_string="l.extbz";
904 18 julius
              insn_props->insn_index=102;
905 16 julius
              break;
906
            }
907
          insn_props->has_rB = 0;
908
          break;
909
 
910
        case 0xd:
911 26 julius
          switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
912
            {
913
            case 0x0:
914
              insn_props->insn_string="l.extws";
915
              insn_props->insn_index=103;
916
              break;
917
            case 0x1:
918
              insn_props->insn_string="l.extwz";
919
              insn_props->insn_index=104;
920
              break;
921
            }
922 16 julius
          insn_props->has_rB = 0;
923
          break;
924
 
925
        case 0xe:
926
          insn_props->insn_string="l.cmov";
927 26 julius
          insn_props->insn_index=105;
928 16 julius
          break;
929
 
930
        case 0xf:
931
          if (insn_or1k_opcode_0x38_get_op_hi_2bit(insn) & 0x1)
932 18 julius
            {
933
              insn_props->insn_string="l.fl1";
934 26 julius
              insn_props->insn_index=106;
935 18 julius
            }
936 16 julius
          else
937 18 julius
            {
938
              insn_props->insn_string="l.ff1";
939 26 julius
              insn_props->insn_index=107;
940 18 julius
            }
941 16 julius
          insn_props->has_rB = 0;
942
          break;
943
 
944
        default:
945
          printf("Unknown ALU lo op (0x%x)",
946
                 insn_or1k_opcode_0x38_get_op_lo(insn));
947 17 julius
          return 1;
948 16 julius
          break;
949
        }
950
      break;
951
 
952
    case 0x39:
953 17 julius
      insn_props->has_rA = 1;
954
      insn_props->has_rB = 1;
955 16 julius
      switch (insn_or1k_opcode_0x39_get_op(insn))
956
        {
957
        case 0x0:
958
          insn_props->insn_string="l.sfeq";
959 26 julius
          insn_props->insn_index=108;
960 16 julius
          break;
961
        case 0x1:
962
          insn_props->insn_string="l.sfne";
963 26 julius
          insn_props->insn_index=109;
964 16 julius
          break;
965
        case 0x2:
966
          insn_props->insn_string="l.sfgtu";
967 26 julius
          insn_props->insn_index=110;
968 16 julius
          break;
969
        case 0x3:
970
          insn_props->insn_string="l.sfgeu";
971 26 julius
          insn_props->insn_index=111;
972 16 julius
          break;
973
        case 0x4:
974
          insn_props->insn_string="l.sfltu";
975 26 julius
          insn_props->insn_index=112;
976 16 julius
          break;
977
        case 0x5:
978
          insn_props->insn_string="l.sfleu";
979 26 julius
          insn_props->insn_index=113;
980 16 julius
          break;
981
        case 0xa:
982
          insn_props->insn_string="l.sfgts";
983 26 julius
          insn_props->insn_index=114;
984 16 julius
          break;
985
        case 0xb:
986
          insn_props->insn_string="l.sfges";
987 26 julius
          insn_props->insn_index=115;
988 16 julius
          break;
989
        case 0xc:
990
          insn_props->insn_string="l.sflts";
991 26 julius
          insn_props->insn_index=116;
992 16 julius
          break;
993
        case 0xd:
994
          insn_props->insn_string="l.sfles";
995 26 julius
          insn_props->insn_index=117;
996 16 julius
          break;
997
        default:
998
          printf("Unknown opcode for l.sfxxx opcode (0x%x)",
999
                 insn_or1k_opcode_0x39_get_op(insn));
1000 17 julius
          return 1;
1001 16 julius
          break;
1002
        }
1003
      break;
1004
 
1005
    default:
1006
      printf("Unknown opcode 0x%x",insn_or1k_opcode(insn));
1007
      return 1;
1008
      break;
1009
    }
1010
 
1011
  return 0;
1012
}
1013
 
1014 28 julius
// Function to track entire instructions, regardless of architecture
1015
// Storage list:
1016
// Format: [0] - binary copy of instruction
1017
//         [1] - occurrence count
1018
uint32_t (*bin_insn_list)[2] = NULL;
1019
int bin_insn_list_count = -1;
1020
#define NUM_EXPECTED_UNIQUE_INSNS 50000
1021
void record_bin_insn(uint32_t insn)
1022
{
1023
  // Check if the array has been initialised yet
1024
  if (bin_insn_list_count == -1)
1025
    {
1026
      bin_insn_list = calloc((NUM_EXPECTED_UNIQUE_INSNS*2)*sizeof(uint32_t),1);
1027
      bin_insn_list_count = 0;
1028
    }
1029 16 julius
 
1030 28 julius
  int list_check_itr;
1031
  // Go through the list, check if we've seen this one before
1032
  for(list_check_itr=0;list_check_itr<bin_insn_list_count;list_check_itr++)
1033
    if (bin_insn_list[list_check_itr][0] == insn)
1034
      {
1035
        // Seen it before, just increment count
1036
        bin_insn_list[list_check_itr][1]++;
1037
        return;
1038
      }
1039
 
1040
 
1041
  // If we're here, we've not seen this one before, it's new
1042
 
1043
  // No room left in list to add new ones
1044
  if ( bin_insn_list_count == NUM_EXPECTED_UNIQUE_INSNS )
1045
    return;
1046
 
1047
  // Add it to the list
1048
  bin_insn_list[bin_insn_list_count][0] = insn;
1049
  bin_insn_list[bin_insn_list_count][1] = 1;
1050
 
1051
  bin_insn_list_count++;
1052
 
1053
  // No room left in list to add new ones
1054
  if ( bin_insn_list_count == NUM_EXPECTED_UNIQUE_INSNS )
1055
    fprintf(stderr, "Warning: bin_insn_list[][] full (%d entries)\n",
1056
            NUM_EXPECTED_UNIQUE_INSNS);
1057
 
1058
 
1059
}
1060
 
1061 22 julius
// Entry point for statistics collection.
1062
// Passed binary copy of instruction, and pointer to properties struct
1063
// Each function that can collect staistics is called.
1064 16 julius
void or1k_32_collect_stats(uint32_t insn,
1065 28 julius
                           struct or1k_32_instruction_properties  * insn_props,
1066
                           int record_bin_insns)
1067 16 julius
{
1068 25 julius
  // Add this instruction's occurrence to our data
1069 18 julius
  insn_lists_add(insn, insn_props);
1070 16 julius
 
1071 19 julius
  // n-tuple groupings stats recording here!  
1072
  // only if we've seen enough to do all the sequence analysis
1073
  if (num_seen_insns > OR1K_MAX_GROUPINGS_ANALYSIS+1)
1074
    {
1075
      int n;
1076
      for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
1077
        insn_lists_group_add(n, insn_props);
1078
    }
1079 28 julius
 
1080
  if (record_bin_insns)
1081
    record_bin_insn(insn);
1082
 
1083 19 julius
  // Finished adding to stats for this instruction
1084 16 julius
 
1085 19 julius
}
1086 16 julius
 
1087 18 julius
// Function to add entry to, or increment incidences of, value in the value list
1088
void or1k_add_in_list(struct or1k_value_list * list, int32_t value)
1089
{
1090
  int i;
1091
  // See if it's already in the list
1092
  i=list->count;
1093
 
1094
  while(i)
1095
    {
1096
      i--;
1097
      if(list->values[i][0] == value)
1098
        {
1099
          (list->values[i][1])++;
1100
          return;
1101
        }
1102
    }
1103
 
1104
  if (list->count < OR1K_VALUE_MAX_ENTRIES)
1105
    {
1106
      // Not found, add it to the list
1107
      list->values[(list->count)][0] = value;
1108
      list->values[(list->count)][1] = 1;
1109
      list->count++;
1110 19 julius
    }
1111 18 julius
}
1112
 
1113 16 julius
// List management/analysis functions - accessed through insn_lists() set of
1114
// functions
1115
 
1116 22 julius
// Clear the list structs
1117 16 julius
void or1k_32_insn_lists_init(void)
1118
{
1119 18 julius
  num_setup_insns = 0;
1120 16 julius
  num_seen_insns = 0;
1121 18 julius
  // Clear the pointer array so we can tell if things are used or not
1122
  memset(or1k_32_insns, '\0',
1123
         sizeof(struct or1k_insn_info *)*OR1K_32_MAX_INSNS);
1124 16 julius
}
1125
 
1126 18 julius
// Alloc struct and put it into the list
1127
void or1k_32_insn_lists_init_insn(uint32_t insn,
1128
                        struct or1k_32_instruction_properties *insn_props)
1129 16 julius
{
1130
  // Add an instruction in or1k_32_insns[num_unique_instructions];
1131
  // use calloc() so it clears it all first (hopefully!).. assumption!
1132
  struct or1k_insn_info * new_insn
1133
    = (struct or1k_insn_info *) calloc (sizeof(struct or1k_insn_info), 1);
1134
 
1135 18 julius
  // Copy the string pointer
1136
  new_insn->insn_string = insn_props->insn_string,
1137 16 julius
 
1138 18 julius
  // Install the pointer for this newly allocated struct in its corresponding
1139
  // index, as set when we decode the instruction
1140
  or1k_32_insns[insn_props->insn_index] = new_insn;
1141 16 julius
 
1142 19 julius
  // Clear the set statistics counters
1143
  int set_itr;
1144
  for(set_itr=0;set_itr<OR1K_MAX_GROUPINGS_ANALYSIS;set_itr++)
1145
    or1k_32_insns[insn_props->insn_index]->groupings[set_itr][0][0] = 0;
1146
 
1147 18 julius
  // Increment number of instructions we have set up
1148
  num_setup_insns++;
1149 17 julius
 
1150
  // Debugging:
1151
  //printf("Adding %dth instruction - %s\n",
1152 18 julius
  //num_setup_insns, new_insn->insn_string);
1153 16 julius
 
1154
}
1155
 
1156
 
1157 17 julius
 
1158 16 julius
// Add stats for this instruction
1159 18 julius
void or1k_32_insn_lists_add(uint32_t insn,
1160 16 julius
                            struct or1k_32_instruction_properties *insn_props)
1161
{
1162 18 julius
  // Check if the entry for this instruction has been setup yet
1163
  if (or1k_32_insns[insn_props->insn_index] == NULL)
1164
    {
1165
      // Here we allocate space for the instruction's stats
1166
      or1k_32_insn_lists_init_insn(insn, insn_props);
1167
    }
1168 16 julius
 
1169 25 julius
  // Increment occurrence count
1170 18 julius
  ((or1k_32_insns[insn_props->insn_index])->count)++;
1171 16 julius
 
1172
  // Add branch target value information, if instruction has it
1173
  if (insn_props->has_branchtarg)
1174
    {
1175 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_branchtarg = 1;
1176
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->branch_info),
1177 17 julius
                       (int32_t)insn_or1k_opcode_0x03_get_branchoff(insn));
1178 16 julius
    }
1179
 
1180
  // Add immediate value if it's got one
1181
  if (insn_props->has_imm)
1182
    {
1183 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
1184
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
1185 17 julius
                       (int32_t)insn_or1k_32_imm(insn));
1186 16 julius
    }
1187
 
1188
  // Add split immediate value if it's got one
1189
  if (insn_props->has_split_imm)
1190 17 julius
    {
1191 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
1192
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
1193 17 julius
                       (int32_t)insn_or1k_32_split_imm(insn));
1194 16 julius
    }
1195
 
1196
 
1197
  // Increment count of use for particular rD
1198
  if (insn_props->has_rD)
1199
    {
1200 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_rD = 1;
1201
      ((or1k_32_insns[insn_props->insn_index])->rD_use_freq[insn_or1k_32_rD(insn)])++;
1202 16 julius
    }
1203
 
1204
  // Increment count of use for particular rA
1205
  if (insn_props->has_rA)
1206
    {
1207 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_rA = 1;
1208
      ((or1k_32_insns[insn_props->insn_index])->rA_use_freq[insn_or1k_32_rA(insn)])++;
1209 16 julius
    }
1210
 
1211
  // Increment count of use for particular rB
1212
  if (insn_props->has_rB)
1213
    {
1214 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_rB = 1;
1215
      ((or1k_32_insns[insn_props->insn_index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
1216 16 julius
    }
1217
 
1218
  // Increment overall instructions "seen" counter
1219
  num_seen_insns++;
1220
 
1221 19 julius
  // Shift along the recently seen instructions
1222
  int i;
1223
  for(i=OR1K_MAX_GROUPINGS_ANALYSIS-1;i>0;i--)
1224
    or1k_32_recent_insns[i] = or1k_32_recent_insns[i-1];
1225
  or1k_32_recent_insns[0] = insn_props->insn_index;
1226
 
1227 16 julius
}
1228
 
1229
 
1230 19 julius
 
1231
 
1232 22 julius
// Do the n-tuple set checking for the current instruction
1233 19 julius
void or1k_32_ntuple_add(int n,
1234
                        struct or1k_32_instruction_properties *insn_props)
1235 16 julius
{
1236 19 julius
 
1237
  if (n<2)
1238 16 julius
    {
1239 19 julius
      fprintf(stderr,"or1k_32_ntuple_add: tuple number < 2 (%d)",n);
1240
      return;
1241 16 julius
    }
1242 19 julius
 
1243
  struct or1k_insn_info * insn_info = or1k_32_insns[insn_props->insn_index];
1244
 
1245
  // Get the number of sets for these n-tuple groups we've seen so far.
1246
  int sets_for_ntuple = insn_info->groupings[n-1][0][0];
1247 20 julius
#if DEBUG_PRINT
1248 22 julius
  printf("%s\t:\t%d-tuple add - sets so far : %d\n",
1249
         insn_info->insn_string, n, sets_for_ntuple);
1250 20 julius
#endif
1251 19 julius
 
1252 20 julius
  int set_match_index;
1253
  int tuple_set_itr, tuple_set_match;
1254
 
1255
  tuple_set_match = 0;
1256 19 julius
 
1257
  // now find if the current n instructions in or1k_32_recent_insns[] matches
1258
  // any set of n instructions we're keeping track of in groupings[][][].
1259 20 julius
#if DEBUG_PRINT
1260 22 julius
  printf("%s\tChecking\t%d\tsets for ntuple:\t",
1261
         insn_info->insn_string,sets_for_ntuple);
1262 20 julius
  for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1263
    printf("%s ",
1264
           or1k_32_insns[(or1k_32_recent_insns[n - 1 - tuple_set_itr])]->insn_string);
1265
  printf("\n");
1266
#endif  
1267 19 julius
  for (set_match_index=0; set_match_index<sets_for_ntuple; set_match_index++)
1268
    {
1269
      // Check this set for a match with our existing trace
1270
      // Example:
1271
      // In case of a triple (n=3), 1st set, [3][1][0] corresponds to the third
1272
      // instruction in the trace (or1k_32_recent_insns[2]), [3][1][1] should 
1273
      // be the second in the trace, and [3][1][2] should be the first in the 
1274
      // trace (same index as insn_props->insn_index)
1275 20 julius
 
1276
#if DEBUG_PRINT
1277
      printf("Chk:\t");
1278
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1279
        printf("%s ",
1280
               or1k_32_insns[(insn_info->groupings[n-1][set_match_index+1][tuple_set_itr])]->insn_string);
1281
      printf("\t(%d)\n", insn_info->groupings[n-1][set_match_index+1][n]);
1282
#endif      
1283
      tuple_set_match = 1;
1284 19 julius
      // Presuppose a match, de-assert and break out of the loop as soon as we
1285
      // detect a mismatch.
1286
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1287
        {
1288 20 julius
 
1289 19 julius
          if (insn_info->groupings[n-1][set_match_index+1][tuple_set_itr]
1290 20 julius
              != or1k_32_recent_insns[n - 1 - tuple_set_itr])
1291 19 julius
            {
1292
              tuple_set_match = 0;
1293
              break; // No match, so break out of this for() loop
1294
            }
1295
        }
1296
 
1297
      if (!tuple_set_match)
1298
        continue; // go again...
1299 20 julius
      else
1300
        break; // Bail out, we've found our match
1301 19 julius
    }
1302
 
1303
  if (tuple_set_match)
1304 20 julius
    {
1305
      // Found a match - just increment the counter (set_match_index should
1306
      // be pointing at the right set)            
1307
#if DEBUG_PRINT
1308
      printf("Match!\n");
1309
#endif
1310
 
1311
      (insn_info->groupings[n-1][set_match_index+1][n])++;
1312
    }
1313 19 julius
  else
1314
    {
1315
      // If we can record a new set
1316
      if (sets_for_ntuple < OR1K_MAX_ENTRIES_PER_GROUP)
1317
        {
1318 20 julius
#if DEBUG_PRINT
1319
          printf("New entry\n");
1320
#endif
1321
 
1322 19 julius
          // Increment the number of sets we have for this n-tuple starting
1323
          // on the current instruction  
1324
          sets_for_ntuple++;
1325
          // Add new set to the end (all n instructions, copy in)
1326
          for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1327
            insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr]
1328 20 julius
              = or1k_32_recent_insns[n - 1 - tuple_set_itr];
1329 19 julius
          // Set the count for this set to 1
1330 20 julius
          (insn_info->groupings[n-1][sets_for_ntuple][n]) = 1;
1331 19 julius
          // Increment the counter of these n-tuple sets
1332 20 julius
          insn_info->groupings[n-1][0][0] = sets_for_ntuple;
1333 19 julius
        }
1334 20 julius
    }
1335
 
1336
#if DEBUG_PRINT
1337 22 julius
  // Verbose announcement of found instruction
1338 20 julius
   if (tuple_set_match)
1339
  {
1340
     printf("%s\t:\tMatch for %d-tuple - set %d - cnt: %d - ",
1341
      insn_info->insn_string, n, set_match_index,
1342
             insn_info->groupings[n-1][set_match_index+1][n]);
1343
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1344
        printf("%s ",
1345
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
1346
    printf("\n");
1347
  }
1348
  else
1349
    {
1350
     printf("%s\t:\tNew %d-tuple - set %d - cnt: %d - ",
1351
             insn_info->insn_string, n, sets_for_ntuple,
1352
             insn_info->groupings[n-1][sets_for_ntuple][n]);
1353
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1354
        printf("%s ",
1355
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
1356
    printf("\n");
1357
  }
1358
#endif
1359
 
1360 16 julius
}
1361 17 julius
 
1362 22 julius
// Generate a list for the most-frequently seen instructions
1363 17 julius
void or1k_32_most_freq_insn(FILE * stream)
1364
{
1365
  // Print out most frequent instruction
1366
  int i, largest, largest_index;
1367 18 julius
  int instructions_to_print = num_setup_insns;
1368 22 julius
 
1369
#ifdef DISPLAY_CSV
1370
  fprintf(stream,"\"Most frequent instructions, descending\",\n");
1371 25 julius
  fprintf(stream,"\"Instruction\",\"Occurrences\",\"Frequency\",\n");
1372 22 julius
#endif
1373
 
1374 17 julius
  while (instructions_to_print)
1375
    {
1376
      --instructions_to_print;
1377
      largest=0;
1378
      // Go through the list, find the largest, print it, eliminate it
1379 18 julius
      for(i=0;i<OR1K_32_MAX_INSNS;i++)
1380
        if (or1k_32_insns[i]!=NULL){
1381
          if(((or1k_32_insns[i])->count) > largest)
1382
            {
1383
              largest = ((or1k_32_insns[i])->count);
1384
              largest_index = i;
1385
            }
1386
        }
1387 17 julius
      fprintf(stream,
1388
#ifdef DISPLAY_STRING      
1389
             "Insn:\t%s\t\tCount:\t\t%d\t(%f%%)\n",
1390
#endif
1391
#ifdef DISPLAY_CSV
1392
             // CSV format - "opcode string",frequency,percentage
1393
             "\"%s\",%d,%f\n",
1394
#endif
1395
             ((or1k_32_insns[largest_index])->insn_string),
1396
             ((or1k_32_insns[largest_index])->count),
1397
             (float)(((float)((or1k_32_insns[largest_index])->count))/
1398 27 julius
                     ((float)num_seen_insns)));
1399 17 julius
 
1400
 
1401
      ((or1k_32_insns[largest_index])->count) = -1; // Eliminate this one
1402
 
1403
    }
1404
}
1405
 
1406
 
1407 22 julius
// Generate a list for the most-frequently seen n-tuple set
1408
void or1k_32_most_freq_ntuple(int n, FILE * stream, int max_stats)
1409
{
1410
 
1411
  fprintf(stream,
1412
#ifdef DISPLAY_STRING
1413
          "Top %d %d-tuple groupings of instructions\n",
1414
#endif
1415
#ifdef DISPLAY_CSV
1416
          "\"Top %d %d-tuple groupings of instructions\",\n",
1417
#endif
1418
          max_stats, n);
1419
 
1420
  // First get a copy of all the n-tuple values for each applicable
1421
  // instruction.
1422
  int set_counts[OR1K_32_MAX_INSNS][OR1K_MAX_ENTRIES_PER_GROUP];
1423
  int insn_index;
1424
  int set_index;
1425
  int num_sets;
1426
  struct or1k_insn_info *insn_info;
1427
 
1428
  // Copy each instruction's set totals into our local array
1429
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
1430
    {
1431
      if (or1k_32_insns[insn_index] != NULL)
1432
        {
1433
          insn_info = or1k_32_insns[insn_index];
1434
          num_sets = insn_info->groupings[n-1][0][0];
1435
          for(set_index=0;set_index<num_sets;set_index++)
1436
            set_counts[insn_index][set_index] =
1437
              insn_info->groupings[n-1][set_index+1][n];
1438
        }
1439
    }
1440
 
1441
  // Go through the set numbers, look at the most frequent one, print it out
1442
  // clear its count and continue
1443
 
1444
 
1445
  int largest_insn_index, largest_set_index, largest_count;
1446
  int tuple_set_itr;
1447
 
1448
 
1449
#ifdef DISPLAY_CSV
1450
  for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1451
    fprintf(stream, "\"insn%d\",",n-1-tuple_set_itr);
1452
  fprintf(stream, "\"count\",\n");
1453
#endif
1454
 
1455
  while(max_stats--)
1456
    {
1457
      largest_count = 0;
1458
      // Go through each instruction we have
1459
      for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
1460
        {
1461
          if (or1k_32_insns[insn_index] != NULL)
1462
            {
1463
              insn_info = or1k_32_insns[insn_index];
1464
              // Get the total number of sets for the n-tup. of this instruction
1465
              num_sets = insn_info->groupings[n-1][0][0];
1466
              for(set_index=0;set_index<num_sets;set_index++)
1467
                {
1468
                  // Go through each set, check if it's largest
1469
                  if (set_counts[insn_index][set_index] >
1470
                      largest_count)
1471
                    {
1472
                      largest_insn_index = insn_index;
1473
                      largest_set_index = set_index;
1474
                      largest_count = set_counts[insn_index][set_index];
1475
                    }
1476
                }
1477
            }
1478
        }
1479 23 julius
 
1480
      // We now have indexes of the next largest n-tuple, print it out.
1481
 
1482 22 julius
      insn_info = or1k_32_insns[largest_insn_index];
1483 23 julius
 
1484 22 julius
#ifdef DISPLAY_STRING
1485
      fprintf(stream,"set :");
1486
#endif
1487 23 julius
 
1488 22 julius
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1489
        fprintf(stream,
1490
#ifdef DISPLAY_STRING
1491
                " %s",
1492
#endif
1493
#ifdef DISPLAY_CSV
1494
                "\"%s\",",
1495
#endif
1496 23 julius
                or1k_32_insns[(insn_info->groupings[n-1][largest_set_index+1][tuple_set_itr])]->insn_string);
1497 22 julius
 
1498
      fprintf(stream,
1499
#ifdef DISPLAY_STRING
1500
              "\tcount: %d\n",
1501
#endif
1502
#ifdef DISPLAY_CSV
1503
              "%d,\n",
1504
#endif
1505
              set_counts[largest_insn_index][largest_set_index]);
1506
 
1507
        // Remove this value from getting selected from largest again
1508
        set_counts[largest_insn_index][largest_set_index] = -1;
1509
    }
1510
 
1511
}
1512
 
1513
 
1514
 
1515
 
1516
// Print out top n of each kept statistic for the requested instruction
1517
void or1k_32_insn_top_n(struct or1k_insn_info *insn_info, FILE * stream,
1518 18 julius
                        int max_stats)
1519 17 julius
{
1520 20 julius
  int i, j, largest_i;
1521 17 julius
 
1522 18 julius
  fprintf(stream,
1523 22 julius
#ifdef DISPLAY_STRING
1524
          "Insn: \"%s\" statistics (%d times (%f%%))\n",
1525
#endif
1526
#ifdef DISPLAY_CSV
1527 26 julius
          "\"Instruction:\",\"%s\",\"occurrences:\",%d,%f%%\n",
1528 22 julius
#endif
1529 18 julius
          insn_info->insn_string,
1530
          insn_info->count,
1531
          (float)(((float)((insn_info)->count))/
1532 27 julius
                  ((float)num_seen_insns))
1533 18 julius
          );
1534 17 julius
 
1535
 
1536
 
1537 18 julius
  // Start dumping applicable stats
1538 17 julius
 
1539
  // Print out top max_stats branch targets
1540 18 julius
  if (insn_info->has_branchtarg)
1541 17 julius
    {
1542 22 julius
      fprintf(stream,
1543
#ifdef DISPLAY_STRING
1544 26 julius
              "Branch immediates:\n"
1545 22 julius
#endif
1546
#ifdef DISPLAY_CSV
1547 26 julius
              "\"branch imm\",\"occurrences\",\"frequency\"\n"
1548 22 julius
#endif
1549
              );
1550 17 julius
      i = 0;
1551 18 julius
      while(i<insn_info->branch_info.count && i < max_stats)
1552 17 julius
        {
1553
          largest_i=0;
1554 18 julius
          for(j=0;j<insn_info->branch_info.count;j++)
1555
            largest_i = (insn_info->branch_info.values[j][1] >
1556
                         insn_info->branch_info.values[largest_i][1]) ?
1557 17 julius
              j : largest_i;
1558
 
1559
          // largest_i has index of most frequent value
1560
          fprintf(stream,
1561 22 julius
#ifdef DISPLAY_STRING
1562 26 julius
                  "value:\t0x%x\tcount:\t%d,\tfreq:\t%f%%\n",
1563 22 julius
#endif
1564
#ifdef DISPLAY_CSV
1565 26 julius
                  "0x%x,%d,%f\n",
1566 22 julius
#endif
1567 18 julius
                  insn_info->branch_info.values[largest_i][0],
1568 26 julius
                  insn_info->branch_info.values[largest_i][1],
1569
                  (float)(((float)insn_info->branch_info.values[largest_i][1])
1570 27 julius
                          /((float)((insn_info)->count))));
1571 18 julius
          insn_info->branch_info.values[largest_i][1] = -1; // clear this one
1572 17 julius
          i++;
1573
        }
1574
    }
1575 18 julius
  if (insn_info->has_imm)
1576 17 julius
    {
1577 22 julius
      fprintf(stream,
1578
#ifdef DISPLAY_STRING
1579
              "Immediate values:\n"
1580
#endif
1581
#ifdef DISPLAY_CSV
1582 26 julius
              "\"immediate value\",\"count\",\"frequency\"\n"
1583 22 julius
#endif
1584
              );
1585 17 julius
      i = 0;
1586 18 julius
      while(i<insn_info->imm_info.count && i < max_stats)
1587 17 julius
        {
1588
          largest_i=0;
1589 18 julius
          for(j=0;j<insn_info->imm_info.count;j++)
1590
            largest_i = (insn_info->imm_info.values[j][1] >
1591
                         insn_info->imm_info.values[largest_i][1]) ?
1592 17 julius
              j : largest_i;
1593
 
1594
          // largest_i has index of most frequent value
1595
          fprintf(stream,
1596 22 julius
#ifdef DISPLAY_STRING
1597 26 julius
                  "value:\t0x%x\tcount:\t%d\tfreq:\t%f%%\n",
1598 22 julius
#endif
1599
#ifdef DISPLAY_CSV
1600 26 julius
                  "0x%x,%d,%f\n",
1601 22 julius
#endif
1602 18 julius
                  insn_info->imm_info.values[largest_i][0],
1603 26 julius
                  insn_info->imm_info.values[largest_i][1],
1604
                  (float)(((float)insn_info->imm_info.values[largest_i][1])
1605 27 julius
                          /((float)((insn_info)->count))));
1606 18 julius
          insn_info->imm_info.values[largest_i][1] = -1; // clear this one
1607 17 julius
          i++;
1608
        }
1609
    }
1610 22 julius
 
1611 18 julius
  if (insn_info->has_rD)
1612 17 julius
    {
1613 22 julius
      fprintf(stream,
1614
#ifdef DISPLAY_STRING
1615
              "rD usage:\n"
1616
#endif
1617
#ifdef DISPLAY_CSV
1618 26 julius
              "\"rD\",\"count\",\"frequency\"\n"
1619 22 julius
#endif
1620
              );
1621 17 julius
      i = 0;
1622
      while(i<32 && i < max_stats)
1623
        {
1624
          largest_i=0;
1625
          for(j=0;j<32;j++)
1626 18 julius
            largest_i = (insn_info->rD_use_freq[j] >
1627
                         insn_info->rD_use_freq[largest_i]) ?
1628 17 julius
              j : largest_i;
1629
 
1630
          // No more interesting numbers
1631 18 julius
          if (insn_info->rD_use_freq[largest_i] == 0)
1632 17 julius
            break;
1633
 
1634
          // largest_i has index of most frequent value
1635
          fprintf(stream,
1636 22 julius
#ifdef DISPLAY_STRING
1637 26 julius
                  "r%d\tcount:\t%d\tfreq:\t%f%%\n",
1638 22 julius
#endif
1639
#ifdef DISPLAY_CSV
1640 26 julius
                  "\"r%d\",%d,%f\n",
1641 22 julius
#endif
1642 17 julius
                  largest_i,
1643 26 julius
                  insn_info->rD_use_freq[largest_i],
1644
                  (float)(((float)insn_info->rD_use_freq[largest_i])
1645 27 julius
                          /((float)((insn_info)->count))));
1646 18 julius
          insn_info->rD_use_freq[largest_i] = -1; // clear this one
1647 17 julius
          i++;
1648
        }
1649
    }
1650
 
1651 18 julius
  if (insn_info->has_rA)
1652 17 julius
    {
1653 22 julius
      fprintf(stream,
1654
#ifdef DISPLAY_STRING
1655
              "rA usage:\n"
1656
#endif
1657
#ifdef DISPLAY_CSV
1658 26 julius
              "\"rA\",\"count\",\"frequency\"\n"
1659 22 julius
#endif
1660
              );
1661 17 julius
      i = 0;
1662
      while(i<32 && i < max_stats)
1663
        {
1664
          largest_i=0;
1665
          for(j=0;j<32;j++)
1666 18 julius
            largest_i = (insn_info->rA_use_freq[j] >
1667
                         insn_info->rA_use_freq[largest_i]) ?
1668 17 julius
              j : largest_i;
1669
 
1670
          // No more interesting numbers
1671 18 julius
          if (insn_info->rA_use_freq[largest_i] == 0)
1672 17 julius
            break;
1673
 
1674
 
1675
          // largest_i has index of most frequent value
1676
          fprintf(stream,
1677 22 julius
#ifdef DISPLAY_STRING
1678 26 julius
                  "r%d\tcount:\t%d\tfreq:\t%f%%\n",
1679 22 julius
#endif
1680
#ifdef DISPLAY_CSV
1681 26 julius
                  "\"r%d\",%d,%f\n",
1682 22 julius
#endif
1683 17 julius
                  largest_i,
1684 26 julius
                  insn_info->rA_use_freq[largest_i],
1685
                  (float)(((float)insn_info->rA_use_freq[largest_i])
1686 27 julius
                          /((float)((insn_info)->count))));
1687 18 julius
          insn_info->rA_use_freq[largest_i] = -1; // clear this one
1688 17 julius
          i++;
1689
        }
1690
    }
1691
 
1692 18 julius
  if (insn_info->has_rB)
1693 17 julius
    {
1694 22 julius
      fprintf(stream,
1695
#ifdef DISPLAY_STRING
1696
              "rB usage:\n"
1697
#endif
1698
#ifdef DISPLAY_CSV
1699 26 julius
              "\"rB\",\"count\",\"frequency\"\n"
1700 22 julius
#endif
1701
              );
1702 17 julius
      i = 0;
1703
      while(i<32 && i < max_stats)
1704
        {
1705
          largest_i=0;
1706
          for(j=0;j<32;j++)
1707 18 julius
            largest_i = (insn_info->rB_use_freq[j] >
1708
                         insn_info->rB_use_freq[largest_i]) ?
1709 17 julius
              j : largest_i;
1710
 
1711
          // No more interesting numbers
1712 18 julius
          if (insn_info->rB_use_freq[largest_i] == 0)
1713 17 julius
            break;
1714
 
1715
 
1716
          // largest_i has index of most frequent value
1717
          fprintf(stream,
1718 22 julius
#ifdef DISPLAY_STRING
1719 26 julius
                  "r%d\tcount:\t%d\tfreq:\t%f%%\n",
1720 22 julius
#endif
1721
#ifdef DISPLAY_CSV
1722 26 julius
                  "\"r%d\",%d,%f\n",
1723 22 julius
#endif
1724 17 julius
                  largest_i,
1725 26 julius
                  insn_info->rB_use_freq[largest_i],
1726
                  (float)(((float)insn_info->rB_use_freq[largest_i])
1727 27 julius
                          /((float)((insn_info)->count))));
1728 18 julius
          insn_info->rB_use_freq[largest_i] = -1; // clear this one
1729 17 julius
          i++;
1730
        }
1731
    }
1732
}
1733 19 julius
 
1734 20 julius
 
1735
 
1736 19 julius
// Print out the most common n-tuple groupings for an instruction
1737
void or1k_32_generate_ntuple_stats(int n, struct or1k_insn_info *insn_info,
1738
                                   FILE * stream)
1739
{
1740 20 julius
  // Maximum number we'll print out
1741
#define MAX_NTUPLE_LISTING 5
1742
 
1743
  int (*ntuplelist)[OR1K_MAX_GROUPINGS_ANALYSIS+1];
1744
  int *set;
1745
  int set_count, set_count2;
1746
 
1747
  // Get total number of sets for this n-tuple, eg:
1748 22 julius
  // if n=2 (pairs) then groupings[1] is where our list is, and we store the 
1749
  // number of sets in [0][0] of that n-tuple data.
1750 19 julius
  int total_sets_for_ntuple =  insn_info->groupings[n-1][0][0];
1751
 
1752
  if (total_sets_for_ntuple == 0)
1753
    return;
1754
 
1755 22 julius
  fprintf(stream,
1756
#ifdef DISPLAY_STRING     
1757
          "%d-tuple groupings finishing with %s (%d)\n",
1758
#endif
1759
#ifdef DISPLAY_CSV
1760
          "\"%d-tuple groupings\",\n",
1761
#endif     
1762
          n, insn_info->insn_string, total_sets_for_ntuple);
1763 19 julius
 
1764 22 julius
 
1765 20 julius
  // Debug - dump out all of the info for the sets
1766
#if DEBUG_PRINT
1767
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
1768
    {
1769
 
1770 22 julius
      printf("set: %d - count %d - set: ", set_count,
1771
             insn_info->groupings[n-1][set_count+1][n]);
1772 20 julius
 
1773
      for(set_count2=0;set_count2<n;set_count2++)
1774
        fprintf(stream, "%s\t",
1775
                or1k_32_insns[(insn_info->groupings[n-1][set_count+1][set_count2])]->insn_string);
1776
      printf("\n");
1777
    }
1778
#endif
1779
 
1780
  // A pointer to the n-tuple sets
1781 19 julius
  // This is actually a pointer to a 2-dimensional integer array, looking like:
1782 22 julius
  // [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1], so in 
1783
  // 2-dimensional array pointer fashion, we should provide the "column" sizing.
1784 20 julius
      ntuplelist = insn_info->groupings[n-1];
1785 19 julius
 
1786
  // Let's make a copy of the counts for each... so we don't trash them
1787
  int set_count_copy[OR1K_MAX_ENTRIES_PER_GROUP+1];
1788 20 julius
 
1789
  assert(total_sets_for_ntuple <= OR1K_MAX_ENTRIES_PER_GROUP);
1790
 
1791 19 julius
  // Go through the list, copy the counts for each
1792
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
1793
    {
1794 20 julius
      // Pointer to a set's data
1795
      set = ntuplelist[set_count+1];
1796 22 julius
      // Fish out the copy (0 to n-1 will be the instruction index, n will be 
1797
      // the count)
1798 20 julius
      set_count_copy[set_count+1] = set[n];
1799 19 julius
    }
1800 24 julius
 
1801
 
1802
#ifdef DISPLAY_CSV
1803
      for(set_count2=0;set_count2<n;set_count2++)
1804
        fprintf(stream, "\"insn%d\",",n-1-set_count2);
1805
      fprintf(stream, "\"count\",\n");
1806
#endif
1807
 
1808 19 julius
 
1809
  // Now go through, finding the most frequent n-tuple of instructions and
1810
  // print it out
1811
  int largest_indx = 0;
1812
  set_count=0;
1813
  while(set_count < total_sets_for_ntuple && set_count < MAX_NTUPLE_LISTING)
1814
    {
1815
      largest_indx = 0;
1816
      for(set_count2=0;set_count2<total_sets_for_ntuple;set_count2++)
1817
        largest_indx = (set_count_copy[set_count2 + 1] >
1818
                        set_count_copy[largest_indx + 1]) ?
1819
          set_count2 : largest_indx;
1820 25 julius
      // largest_indx is the index of the set with the highest occurrence, so
1821 19 julius
      // let's print it out, but first get a pointer to the set's data
1822
      set = (int*)ntuplelist[largest_indx+1];
1823 20 julius
 
1824 19 julius
      // Print out the sequence of prior isntructions
1825 22 julius
#ifdef DISPLAY_STRING
1826 19 julius
      fprintf(stream,"Seq:\t");
1827 22 julius
#endif
1828 19 julius
      // Go through the indexes of the previous instructions, get their
1829
      // strings, and print them out
1830
      for(set_count2=0;set_count2<n;set_count2++)
1831 22 julius
        fprintf(stream,
1832
#ifdef DISPLAY_STRING
1833
                "%s\t",
1834
#endif
1835
#ifdef DISPLAY_CSV
1836
                "\"%s\",",
1837
#endif
1838
                or1k_32_insns[(set[set_count2])]->insn_string);
1839 19 julius
 
1840 25 julius
      // now print out the occurrences
1841 22 julius
      fprintf(stream,
1842
#ifdef DISPLAY_STRING
1843
              "\t%d\ttimes (%f%%)\n",
1844
#endif
1845
#ifdef DISPLAY_CSV
1846
              "%d,\n",
1847
#endif
1848
              set[n],
1849 27 julius
              (float)((float)set[n]/(float)insn_info->count));
1850 21 julius
 
1851 19 julius
      // done printing this one out.. let's clear its count
1852
      set_count_copy[largest_indx + 1] = -1;
1853
 
1854
      set_count++;
1855
    }
1856
 
1857
  return;
1858
 
1859
}
1860
 
1861
 
1862 28 julius
// Print out the top n seen entire instructions
1863
void print_top_bin_insn(FILE * stream, int n)
1864
{
1865
  int largest_indx = 0;
1866
  int bin_insn_list_itr;
1867
 
1868
  // Copy the counts, so we can trash them as needed
1869
  int bin_insn_counts[NUM_EXPECTED_UNIQUE_INSNS];
1870
 
1871
  // An instruction properties object
1872
  struct or1k_32_instruction_properties insn_props;
1873
 
1874
  for(bin_insn_list_itr=0;bin_insn_list_itr<bin_insn_list_count;
1875
      bin_insn_list_itr++)
1876
    bin_insn_counts[bin_insn_list_itr] = bin_insn_list[bin_insn_list_itr][1];
1877
 
1878
#ifdef DISPLAY_STRING
1879
  fprintf(stream, "Top %d seen instructions\n", n);
1880
  fprintf(stream, "Saw %d unique instructions\n", bin_insn_list_count);
1881
#endif
1882
#ifdef DISPLAY_CSV
1883
  fprintf(stream, ",\n");
1884
  fprintf(stream,"\"Top %d instructions\",\n\"Total unique instructions\",%d\n",
1885
          n, bin_insn_list_count);
1886
  fprintf(stream,
1887
          "\"Instruction (bin)\",\"Dissassembly\",\"Occurrences\",\"Freq\"\n");
1888
#endif
1889
 
1890
  while (n--)
1891
    {
1892
      // Search for the largest count
1893
      for(bin_insn_list_itr=0;bin_insn_list_itr<bin_insn_list_count;
1894
          bin_insn_list_itr++)
1895
        largest_indx = (bin_insn_counts[bin_insn_list_itr] >
1896
                        bin_insn_counts[largest_indx]) ?
1897
          bin_insn_list_itr : largest_indx;
1898
 
1899
      // Gone through list, largest_indx is the biggest index
1900
 
1901
      // Clear the instruction properties struct
1902
      memset(&insn_props, 0, sizeof(struct or1k_32_instruction_properties));
1903
 
1904
      // Get the string for this instruction
1905
      or1k_32_analyse_insn(bin_insn_list[largest_indx][0], &insn_props);
1906
 
1907
      // Print out the instruction
1908
#ifdef DISPLAY_STRING
1909
      fprintf(stream, "Insn:\t0x%.8x\t%s",bin_insn_list[largest_indx][0],
1910
              insn_props.insn_string);
1911
#endif
1912
#ifdef DISPLAY_CSV
1913
      fprintf(stream, "\"0x%.8x\",\"%s",bin_insn_list[largest_indx][0],
1914
              insn_props.insn_string);
1915
#endif
1916
 
1917
      if (insn_props.has_jumptarg || insn_props.has_branchtarg)
1918
#ifdef DISPLAY_STRING
1919
        fprintf(stream, " 0x%x", (bin_insn_list[largest_indx][0] & JUMPTARG_MASK) << 2 );
1920
#endif
1921
#ifdef DISPLAY_CSV
1922
        fprintf(stream, " 0x%x",  (bin_insn_list[largest_indx][0] & JUMPTARG_MASK) << 2 );
1923
#endif
1924
 
1925
 
1926
      if (insn_props.has_rD)
1927
#ifdef DISPLAY_STRING
1928
        fprintf(stream, " r%d",
1929
                insn_or1k_32_rD(bin_insn_list[largest_indx][0]));
1930
#endif
1931
#ifdef DISPLAY_CSV
1932
        fprintf(stream, " r%d",
1933
                insn_or1k_32_rD(bin_insn_list[largest_indx][0]));
1934
#endif
1935
 
1936
      if (insn_props.has_rA)
1937
#ifdef DISPLAY_STRING
1938
        fprintf(stream, " r%d",
1939
                insn_or1k_32_rA(bin_insn_list[largest_indx][0]));
1940
#endif
1941
#ifdef DISPLAY_CSV
1942
        fprintf(stream, " r%d",
1943
                insn_or1k_32_rA(bin_insn_list[largest_indx][0]));
1944
#endif
1945
 
1946
      if (insn_props.has_rB)
1947
#ifdef DISPLAY_STRING
1948
        fprintf(stream, " r%d",
1949
                insn_or1k_32_rB(bin_insn_list[largest_indx][0]));
1950
#endif
1951
#ifdef DISPLAY_CSV
1952
        fprintf(stream, " r%d",
1953
                insn_or1k_32_rB(bin_insn_list[largest_indx][0]));
1954
#endif
1955
 
1956
 
1957
      if (insn_props.has_imm)
1958
#ifdef DISPLAY_STRING
1959
        fprintf(stream, " 0x%x",
1960
                insn_or1k_32_imm(bin_insn_list[largest_indx][0]));
1961
#endif
1962
#ifdef DISPLAY_CSV
1963
        fprintf(stream, " 0x%x",
1964
                insn_or1k_32_imm(bin_insn_list[largest_indx][0]));
1965
#endif
1966
 
1967
      if (insn_props.has_split_imm)
1968
#ifdef DISPLAY_STRING
1969
        fprintf(stream, " 0x%x",
1970
                insn_or1k_32_split_imm(bin_insn_list[largest_indx][0]));
1971
#endif
1972
#ifdef DISPLAY_CSV
1973
        fprintf(stream, " 0x%x",
1974
                insn_or1k_32_split_imm(bin_insn_list[largest_indx][0]));
1975
#endif
1976
 
1977
#ifdef DISPLAY_STRING
1978
        fprintf(stream, "\tcount:\t%d (%f%%)\n",bin_insn_list[largest_indx][1],
1979
                (float)((float)bin_insn_list[largest_indx][1])/
1980
                ((float)num_seen_insns));
1981
#endif
1982
#ifdef DISPLAY_CSV
1983
        fprintf(stream, "\",%d,%f\n",bin_insn_list[largest_indx][1],
1984
                (float)((float)bin_insn_list[largest_indx][1])/
1985
                ((float)num_seen_insns));
1986
#endif
1987
 
1988
        // Finished printing out its instruction
1989
        bin_insn_counts[largest_indx] = -1;
1990
 
1991
    }
1992
}
1993
 
1994
 
1995 19 julius
// Print out the stats relating to the sequences of instructions most
1996
// common before seeing this instruction
1997
void or1k_32_generate_groupings_stats(struct or1k_insn_info *insn_info,
1998
                                      FILE * stream)
1999
{
2000
  int n;
2001
  for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
2002
    or1k_32_generate_ntuple_stats(n, insn_info, stream);
2003
 
2004
}
2005 22 julius
 
2006
// Entry point for statistics generation.    
2007 17 julius
void or1k_32_generate_stats(FILE * stream)
2008
{
2009 22 julius
#ifdef DISPLAY_STRING
2010 17 julius
  // Generate some useful things
2011
  fprintf(stream, "Analysis output:\n");
2012 22 julius
#endif  
2013 17 julius
  // 
2014
 
2015
  // Print out all stats for every instruction we saw!
2016 18 julius
  int insn_index;
2017
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
2018 17 julius
    {
2019 18 julius
      if (or1k_32_insns[insn_index] != NULL)
2020 19 julius
        {
2021 22 julius
#ifdef DISPLAY_STRING
2022 21 julius
          fprintf(stream, "\t---\t---\t---\t---\n");
2023 22 julius
#endif
2024 25 julius
#ifdef DISPLAY_CSV
2025
          fprintf(stream, ",\n");
2026
#endif
2027
          or1k_32_insn_top_n(or1k_32_insns[insn_index],stream,10);
2028
          or1k_32_generate_groupings_stats(or1k_32_insns[insn_index],stream);
2029
 
2030 19 julius
        }
2031 17 julius
    }
2032
 
2033 25 julius
#ifdef DISPLAY_STRING
2034
          fprintf(stream, "\t---\t---\t---\t---\n");
2035
#endif
2036
#ifdef DISPLAY_CSV
2037
          fprintf(stream, ",\n");
2038
#endif
2039
 
2040
 
2041 22 julius
  // print out most frequent n-tuple
2042
  int ntuple;
2043
  for(ntuple=2;ntuple<5;ntuple++)
2044
    or1k_32_most_freq_ntuple(ntuple, stream, 10);
2045 25 julius
 
2046
 
2047
#ifdef DISPLAY_STRING
2048
          fprintf(stream, "\t---\t---\t---\t---\n");
2049
#endif
2050
#ifdef DISPLAY_CSV
2051
          fprintf(stream, ",\n");
2052
#endif
2053
 
2054 22 julius
 
2055 17 julius
  // Do most frequent instruction analysis -- note this trashes instruction
2056
  // frequency count - should be fixed
2057 22 julius
#ifdef DISPLAY_STRING
2058 21 julius
  fprintf(stream, "Individual instruction frequency:\n");
2059 22 julius
#endif
2060 17 julius
  or1k_32_most_freq_insn(stream);
2061 28 julius
 
2062
  // If we did the binary instruction frequency counting, print it out
2063
  if (bin_insn_list_count != -1)
2064
    print_top_bin_insn(stream, 20);
2065 17 julius
 
2066
}
2067 19 julius
 
2068
 
2069
 
2070
// Free up all added instruction statistic tracking structs
2071
void or1k_32_insn_lists_free(void)
2072
{
2073
  // Free all entries we m/calloc()'d
2074
  int insn_index;
2075
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
2076
    {
2077
      if (or1k_32_insns[insn_index] != NULL)
2078
        free(or1k_32_insns[insn_index]);
2079
    }
2080 28 julius
 
2081
  if (bin_insn_list_count != -1)
2082
    free(bin_insn_list);
2083 19 julius
}

powered by: WebSVN 2.1.0

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