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 21

Go to most recent revision | 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
// These should also be in insnanalysis.h insnanalysis.h
17
typedef uint32_t instruction;
18
typedef struct or1k_32_instruction_properties instruction_properties ;
19
 
20
#include "insn-lists.h"
21
 
22 20 julius
#define DEBUG_PRINT 0
23 16 julius
 
24 19 julius
// Variable to keep track of unique instructions we have
25
int num_setup_insns;
26
int num_seen_insns;
27
 
28
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
29
 
30
// Keep enough instructions required to do the maximum n-tuple set
31
// analysis.
32
int or1k_32_recent_insns[OR1K_MAX_GROUPINGS_ANALYSIS];
33
 
34 16 julius
int or1k_32_analyse_insn(uint32_t insn,
35
                         struct or1k_32_instruction_properties  * insn_props)
36
{
37
 
38
  switch(insn_or1k_opcode(insn))
39
    {
40
    case 0x00:
41
      insn_props->insn_string="l.j";
42 18 julius
      insn_props->insn_index=0;
43 16 julius
      insn_props->has_jumptarg = 1;
44
      break;
45
 
46
    case 0x01:
47
      insn_props->insn_string="l.jal";
48 18 julius
      insn_props->insn_index=1;
49 16 julius
      insn_props->has_jumptarg = 1;
50
      break;
51
 
52
     case 0x03:
53
      insn_props->insn_string="l.bnf";
54 18 julius
      insn_props->insn_index=2;
55 16 julius
      insn_props->has_branchtarg = 1;
56
      break;
57
 
58
    case 0x04:
59
      insn_props->insn_string="l.bf";
60 18 julius
      insn_props->insn_index=3;
61 16 julius
      insn_props->has_branchtarg = 1;
62
      break;
63
 
64
    case 0x05:
65
      insn_props->insn_string="l.nop";
66 18 julius
      insn_props->insn_index=4;
67 16 julius
      break;
68
 
69
    case 0x06:
70
      if((insn_or1k_opcode_0x06_get_id(insn)))
71 18 julius
        {
72
          insn_props->insn_string="l.macrc";
73
          insn_props->insn_index=5;
74
        }
75 16 julius
      else
76
        {
77
          insn_props->insn_string="l.movhi";
78 18 julius
          insn_props->insn_index=6;
79 16 julius
          insn_props->has_rD = 1;
80
          insn_props->has_imm = 1;
81
        }
82
 
83
      break;
84
 
85
    case 0x08:
86
 
87
      switch(insn_or1k_opcode_0x08_get_id(insn))
88
        {
89
        case 0x0:
90
          insn_props->insn_string="l.sys";
91 18 julius
          insn_props->insn_index=7;
92 20 julius
          insn_props->has_imm = 1;
93 16 julius
          break;
94
        case 0x2:
95
          insn_props->insn_string="l.trap";
96 18 julius
          insn_props->insn_index=8;
97 16 julius
          break;
98
        case 0x4:
99
          insn_props->insn_string="l.msync";
100 18 julius
          insn_props->insn_index=9;
101 16 julius
          break;
102
        case 0x5:
103
          insn_props->insn_string="l.psync";
104 18 julius
          insn_props->insn_index=10;
105 16 julius
          break;
106
        case 0x6:
107
          insn_props->insn_string="l.csync";
108 18 julius
          insn_props->insn_index=11;
109 16 julius
          break;
110
        default:
111
          printf("Unknown id (0x%x) in opcode 0x8",
112
                 insn_or1k_opcode_0x08_get_id(insn) );
113
          return 1;
114
          break;
115
        }
116
      break;
117
 
118
    case 0x09:
119
      insn_props->insn_string="l.rfe";
120 18 julius
      insn_props->insn_index=12;
121 16 julius
      break;
122
 
123
    case 0x0a:
124
      switch(insn_or1k_opcode_0x0a_get_op_hi(insn))
125
        {
126
        case 0x1:
127
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
128
            {
129
            case 0x0:
130
              break;
131
            case 0x1:
132
              break;
133
            case 0x2:
134
              break;
135
            case 0x3:
136
              break;
137
            case 0x4:
138
              break;
139
            case 0x5:
140
              break;
141
            case 0x6:
142
              break;
143
            case 0x7:
144
              break;
145
            case 0x8:
146
              break;
147
            case 0x9:
148
              break;
149
            case 0xa:
150
              break;
151
            case 0xb:
152
              break;
153
            default:
154
              printf("Unknown lv.all_xx insn");
155 17 julius
              return 1;
156 16 julius
            }
157
        case 0x2:
158
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
159
            {
160
            case 0x0:
161
              break;
162
            case 0x1:
163
              break;
164
            case 0x2:
165
              break;
166
            case 0x3:
167
              break;
168
            case 0x4:
169
              break;
170
            case 0x5:
171
              break;
172
            case 0x6:
173
              break;
174
            case 0x7:
175
              break;
176
            case 0x8:
177
              break;
178
            case 0x9:
179
              break;
180
            case 0xa:
181
              break;
182
            case 0xb:
183
              break;
184
            default:
185
              printf("Unknown lv.any_xx insn");
186 17 julius
              return 1;
187 16 julius
            }
188
          break;
189
        case 0x3:
190
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
191
            {
192
            case 0x0:
193
              break;
194
            case 0x1:
195
              break;
196
            case 0x2:
197
              break;
198
            case 0x3:
199
              break;
200
            case 0x4:
201
              break;
202
            case 0x5:
203
              break;
204
            case 0x6:
205
              break;
206
            case 0x7:
207
              break;
208
            case 0x8:
209
              break;
210
            case 0x9:
211
              break;
212
            case 0xa:
213
              break;
214
            default:
215
              printf("Unknown lv.add/and/avg_xx insn");
216 17 julius
              return 1;
217 16 julius
            }
218
          break;
219
        case 0x4:
220
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
221
            {
222
            case 0x0:
223
              break;
224
            case 0x1:
225
              break;
226
            case 0x2:
227
              break;
228
            case 0x3:
229
              break;
230
            case 0x4:
231
              break;
232
            case 0x5:
233
              break;
234
            case 0x6:
235
              break;
236
            case 0x7:
237
              break;
238
            case 0x8:
239
              break;
240
            case 0x9:
241
              break;
242
            case 0xa:
243
              break;
244
            case 0xb:
245
              break;
246
            default:
247
              printf("Unknown lv.cmp_xx insn");
248 17 julius
              return 1;
249 16 julius
            }
250
          break;
251
        case 0x5:
252
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
253
            {
254
            case 0x4:
255
              break;
256
            case 0x5:
257
              break;
258
            case 0x6:
259
              break;
260
            case 0x7:
261
              break;
262
            case 0x8:
263
              break;
264
            case 0x9:
265
              break;
266
            case 0xa:
267
              break;
268
            case 0xb:
269
              break;
270
            case 0xc:
271
              break;
272
            case 0xd:
273
              break;
274
            case 0xe:
275
              break;
276
            case 0xf:
277
              break;
278
            default:
279
              printf("Unknown lv.alu_xx insn");
280 17 julius
              return 1;
281 16 julius
            }
282
          break;
283
        case 0x6:
284
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
285
            {
286
            case 0x0:
287
              break;
288
            case 0x1:
289
              break;
290
            case 0x2:
291
              break;
292
            case 0x3:
293
              break;
294
            case 0x4:
295
              break;
296
            case 0x5:
297
              break;
298
            case 0x6:
299
              break;
300
            case 0x7:
301
              break;
302
            case 0x8:
303
              break;
304
            case 0x9:
305
              break;
306
            case 0xa:
307
              break;
308
            case 0xb:
309
              break;
310
            case 0xc:
311
              break;
312
            case 0xd:
313
              break;
314
            case 0xe:
315
              break;
316
            case 0xf:
317
              break;
318
            default:
319
              printf("Unknown lv.pack_xx insn");
320 17 julius
              return 1;
321 16 julius
            }
322
          break;
323
        case 0x7:
324
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
325
            {
326
            case 0x0:
327
              break;
328
            case 0x1:
329
              break;
330
            case 0x2:
331
              break;
332
            case 0x3:
333
              break;
334
            case 0x4:
335
              break;
336
            case 0x5:
337
              break;
338
            case 0x6:
339
              break;
340
            case 0x7:
341
              break;
342
            case 0x8:
343
              break;
344
            case 0x9:
345
              break;
346
            case 0xa:
347
              break;
348
            case 0xb:
349
              break;
350
            default:
351
              printf("Unknown lv.sub/unpack/xor_xx insn");
352 17 julius
              return 1;
353 16 julius
            }
354
          break;
355
        case 0xc:
356
          break;
357
        case 0xd:
358
          break;
359
        case 0xe:
360
          break;
361
        case 0xf:
362
          break;
363
        default:
364
          printf("Unknown lv.xxx insn hi op");
365 17 julius
          return 1;
366 16 julius
          break;
367
        }
368
      break;
369
 
370
    case 0x11:
371
      insn_props->insn_string="l.jr";
372 18 julius
      insn_props->insn_index=13;
373 16 julius
      insn_props->has_rB = 1;
374
      break;
375
 
376
    case 0x12:
377
      insn_props->insn_string="l.jalr";
378 18 julius
      insn_props->insn_index=14;
379 16 julius
      insn_props->has_rB = 1;
380
      break;
381
 
382
    case 0x13:
383
      insn_props->insn_string="l.maci";
384 18 julius
      insn_props->insn_index=15;
385 16 julius
      break;
386
 
387
    case 0x1c:
388
      insn_props->insn_string="l.cust1";
389 18 julius
      insn_props->insn_index=16;
390 16 julius
      break;
391
 
392
    case 0x1d:
393
      insn_props->insn_string="l.cust2";
394 18 julius
      insn_props->insn_index=17;
395 16 julius
      break;
396
 
397
    case 0x1e:
398
      insn_props->insn_string="l.cust3";
399 18 julius
      insn_props->insn_index=18;
400 16 julius
      break;
401
 
402
    case 0x1f:
403
      insn_props->insn_string="l.cust4";
404 18 julius
      insn_props->insn_index=19;
405 16 julius
      break;
406
 
407
    case 0x20:
408
      insn_props->insn_string="l.ld";
409 18 julius
      insn_props->insn_index=20;
410 16 julius
      insn_props->has_rD = 1;
411
      insn_props->has_rA = 1;
412
      insn_props->has_imm = 1;
413
      break;
414
 
415
    case 0x21:
416
      insn_props->insn_string="l.lwz";
417 18 julius
      insn_props->insn_index=21;
418 16 julius
      insn_props->has_rD = 1;
419
      insn_props->has_rA = 1;
420
      insn_props->has_imm = 1;
421
      break;
422
 
423
    case 0x22:
424
      insn_props->insn_string="l.lws";
425 18 julius
      insn_props->insn_index=22;
426 16 julius
      insn_props->has_rD = 1;
427
      insn_props->has_rA = 1;
428
      insn_props->has_imm = 1;
429
      break;
430
 
431
    case 0x23:
432
      insn_props->insn_string="l.lbz";
433 18 julius
      insn_props->insn_index=23;
434 16 julius
      insn_props->has_rD = 1;
435
      insn_props->has_rA = 1;
436
      insn_props->has_imm = 1;
437
      break;
438
 
439
    case 0x24:
440
      insn_props->insn_string="l.lbs";
441 18 julius
      insn_props->insn_index=24;
442 16 julius
      insn_props->has_rD = 1;
443
      insn_props->has_rA = 1;
444
      insn_props->has_imm = 1;
445
      break;
446
 
447
    case 0x25:
448
      insn_props->insn_string="l.lhz";
449 18 julius
      insn_props->insn_index=25;
450 16 julius
      insn_props->has_rD = 1;
451
      insn_props->has_rA = 1;
452
      insn_props->has_imm = 1;
453
      break;
454
 
455
    case 0x26:
456
      insn_props->insn_string="l.lhs";
457 18 julius
      insn_props->insn_index=26;
458 16 julius
      insn_props->has_rD = 1;
459
      insn_props->has_rA = 1;
460
      insn_props->has_imm = 1;
461
      break;
462
 
463
 
464
    case 0x27:
465
      insn_props->insn_string="l.addi";
466 18 julius
      insn_props->insn_index=27;
467 16 julius
      insn_props->has_rD = 1;
468
      insn_props->has_rA = 1;
469
      insn_props->has_imm = 1;
470
      break;
471
 
472
    case 0x28:
473
      insn_props->insn_string="l.addic";
474 18 julius
      insn_props->insn_index=28;
475 16 julius
      insn_props->has_rD = 1;
476
      insn_props->has_rA = 1;
477
      insn_props->has_imm = 1;
478
      break;
479
 
480
    case 0x29:
481
      insn_props->insn_string="l.andi";
482 18 julius
      insn_props->insn_index=29;
483 16 julius
      insn_props->has_rD = 1;
484
      insn_props->has_rA = 1;
485
      insn_props->has_imm = 1;
486
      break;
487
 
488
    case 0x2a:
489
      insn_props->insn_string="l.ori";
490 18 julius
      insn_props->insn_index=30;
491 16 julius
      insn_props->has_rD = 1;
492
      insn_props->has_rA = 1;
493
      insn_props->has_imm = 1;
494
      break;
495
 
496
    case 0x2b:
497
      insn_props->insn_string="l.xori";
498 18 julius
      insn_props->insn_index=31;
499 16 julius
      insn_props->has_rD = 1;
500
      insn_props->has_rA = 1;
501
      insn_props->has_imm = 1;
502
      break;
503
 
504
    case 0x2c:
505
      insn_props->insn_string="l.muli";
506 18 julius
      insn_props->insn_index=32;
507 16 julius
      insn_props->has_rD = 1;
508
      insn_props->has_rA = 1;
509
      insn_props->has_imm = 1;
510
      break;
511
 
512
    case 0x2d:
513
      insn_props->insn_string="l.mfspr";
514 18 julius
      insn_props->insn_index=33;
515 16 julius
      insn_props->has_rD = 1;
516
      insn_props->has_rA = 1;
517
      insn_props->has_imm = 1;
518
      break;
519
 
520
    case 0x2e:
521
      switch(insn_or1k_opcode_0x2e_get_op(insn))
522
        {
523
        case 0x0:
524
          insn_props->insn_string="l.slli";
525 18 julius
          insn_props->insn_index=34;
526 16 julius
          break;
527
        case 0x1:
528
          insn_props->insn_string="l.srli";
529 18 julius
          insn_props->insn_index=35;
530 16 julius
          break;
531
        case 0x2:
532
          insn_props->insn_string="l.srai";
533 18 julius
          insn_props->insn_index=36;
534 16 julius
          break;
535
        case 0x3:
536
          insn_props->insn_string="l.rori";
537 18 julius
          insn_props->insn_index=37;
538 16 julius
          break;
539
        default:
540
          printf("Unknown shift op (0x%x)",
541
                 insn_or1k_opcode_0x2e_get_op(insn));
542 17 julius
          return 1;
543 16 julius
          break;
544
        }
545
      break;
546
 
547
    case 0x2f:
548
      switch(insn_or1k_opcode_0x2f_get_op(insn))
549
        {
550
        case 0x0:
551
          insn_props->insn_string="l.sfeqi";
552 18 julius
          insn_props->insn_index=38;
553 16 julius
          break;
554
        case 0x1:
555
          insn_props->insn_string="l.sfnei";
556 18 julius
          insn_props->insn_index=39;
557 16 julius
          break;
558
        case 0x2:
559
          insn_props->insn_string="l.sfgtui";
560 18 julius
          insn_props->insn_index=40;
561 16 julius
          break;
562
        case 0x3:
563
          insn_props->insn_string="l.sfgeui";
564 18 julius
          insn_props->insn_index=41;
565 16 julius
          break;
566
        case 0x4:
567
          insn_props->insn_string="l.sfltui";
568 18 julius
          insn_props->insn_index=42;
569 16 julius
          break;
570
        case 0x5:
571
          insn_props->insn_string="l.sfleui";
572 18 julius
          insn_props->insn_index=43;
573 16 julius
          break;
574
        case 0xa:
575
          insn_props->insn_string="l.sfgtsi";
576 18 julius
          insn_props->insn_index=44;
577 16 julius
          break;
578
        case 0xb:
579
          insn_props->insn_string="l.sfgesi";
580 18 julius
          insn_props->insn_index=45;
581 16 julius
          break;
582
        case 0xc:
583
          insn_props->insn_string="l.sfltsi";
584 18 julius
          insn_props->insn_index=46;
585 16 julius
          break;
586
        case 0xd:
587
          insn_props->insn_string="l.sflesi";
588 18 julius
          insn_props->insn_index=47;
589 16 julius
          break;
590
 
591
        default:
592
          printf("Unknown set flag op (0x%x)",
593
                 insn_or1k_opcode_0x2f_get_op(insn));
594 17 julius
          return 1;
595 16 julius
          break;
596
        }
597
      insn_props->has_rA = 1;
598
      insn_props->has_imm = 1;
599
      break;
600
 
601
 
602
    case 0x30:
603
      insn_props->insn_string="l.mtspr";
604 18 julius
      insn_props->insn_index=48;
605 16 julius
      break;
606
 
607
    case 0x31:
608
      switch (insn_or1k_opcode_0x31_get_op(insn))
609
        {
610
        case 0x1:
611
          insn_props->insn_string="l.mac";
612 18 julius
          insn_props->insn_index=49;
613 16 julius
          break;
614
        case 0x2:
615
          insn_props->insn_string="l.msb";
616 18 julius
          insn_props->insn_index=50;
617 16 julius
          break;
618
        default:
619
          printf("Unknown mac op (0x%x)",
620
                 insn_or1k_opcode_0x31_get_op(insn));
621 17 julius
          return 1;
622 16 julius
        }
623
      break;
624
 
625
    case 0x32:
626
      switch(insn_or1k_opcode_0x32_get_op_hi(insn))
627
        {
628
        case 0x0:
629
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
630
            {
631
            case 0x0:
632
              insn_props->insn_string="lf.add.s";
633 18 julius
              insn_props->insn_index=51;
634 16 julius
              break;
635
            case 0x1:
636
              insn_props->insn_string="lf.sub.s";
637 18 julius
              insn_props->insn_index=52;
638 16 julius
              break;
639
            case 0x2:
640
              insn_props->insn_string="lf.mul.s";
641 18 julius
              insn_props->insn_index=53;
642 16 julius
              break;
643
            case 0x3:
644
              insn_props->insn_string="lf.div.s";
645 18 julius
              insn_props->insn_index=54;
646 16 julius
              break;
647
            case 0x4:
648
              insn_props->insn_string="lf.itof.s";
649 18 julius
              insn_props->insn_index=55;
650 16 julius
              break;
651
            case 0x5:
652
              insn_props->insn_string="lf.ftoi.s";
653 18 julius
              insn_props->insn_index=56;
654 16 julius
              break;
655
            case 0x6:
656
              insn_props->insn_string="lf.rem.s";
657 18 julius
              insn_props->insn_index=57;
658 16 julius
              break;
659
            case 0x7:
660
              insn_props->insn_string="lf.madd.s";
661 18 julius
              insn_props->insn_index=58;
662 16 julius
              break;
663
            case 0x8:
664
              insn_props->insn_string="lf.sfeq.s";
665 18 julius
              insn_props->insn_index=59;
666 16 julius
              break;
667
            case 0x9:
668
              insn_props->insn_string="lf.sfne.s";
669 18 julius
              insn_props->insn_index=60;
670 16 julius
              break;
671
            case 0xa:
672
              insn_props->insn_string="lf.sfgt.s";
673 18 julius
              insn_props->insn_index=61;
674 16 julius
              break;
675
            case 0xb:
676
              insn_props->insn_string="lf.sfge.s";
677 18 julius
              insn_props->insn_index=62;
678 16 julius
              break;
679
            case 0xc:
680
              insn_props->insn_string="lf.sflt.s";
681 18 julius
              insn_props->insn_index=63;
682 16 julius
              break;
683
            case 0xd:
684
              insn_props->insn_string="lf.sfle.s";
685 18 julius
              insn_props->insn_index=64;
686 16 julius
              break;
687
            default:
688
              printf("Unknown lf.xxx.s op (0x%x)",
689
                     insn_or1k_opcode_0x32_get_op_lo(insn));
690
              break;
691
            }
692
          break;
693
 
694
        case 0x1:
695
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
696
            {
697
            case 0x0:
698
              insn_props->insn_string="lf.add.d";
699 18 julius
              insn_props->insn_index=65;
700 16 julius
              break;
701
            case 0x1:
702
              insn_props->insn_string="lf.sub.d";
703 18 julius
              insn_props->insn_index=66;
704 16 julius
              break;
705
            case 0x2:
706
              insn_props->insn_string="lf.mul.d";
707 18 julius
              insn_props->insn_index=67;
708 16 julius
              break;
709
            case 0x3:
710
              insn_props->insn_string="lf.div.d";
711 18 julius
              insn_props->insn_index=68;
712 16 julius
              break;
713
            case 0x4:
714
              insn_props->insn_string="lf.itof.d";
715 18 julius
              insn_props->insn_index=69;
716 16 julius
              break;
717
            case 0x5:
718
              insn_props->insn_string="lf.ftoi.d";
719 18 julius
              insn_props->insn_index=70;
720 16 julius
              break;
721
            case 0x6:
722
              insn_props->insn_string="lf.rem.d";
723 18 julius
              insn_props->insn_index=71;
724 16 julius
              break;
725
            case 0x7:
726
              insn_props->insn_string="lf.madd.d";
727 18 julius
              insn_props->insn_index=72;
728 16 julius
              break;
729
            case 0x8:
730
              insn_props->insn_string="lf.sfeq.d";
731 18 julius
              insn_props->insn_index=73;
732 16 julius
              break;
733
            case 0x9:
734
              insn_props->insn_string="lf.sfne.d";
735 18 julius
              insn_props->insn_index=74;
736 16 julius
              break;
737
            case 0xa:
738
              insn_props->insn_string="lf.sfgt.d";
739 18 julius
              insn_props->insn_index=75;
740 16 julius
              break;
741
            case 0xb:
742
              insn_props->insn_string="lf.sfge.d";
743 18 julius
              insn_props->insn_index=76;
744 16 julius
              break;
745
            case 0xc:
746
              insn_props->insn_string="lf.sflt.d";
747 18 julius
              insn_props->insn_index=77;
748 16 julius
              break;
749
            case 0xd:
750
              insn_props->insn_string="lf.sfle.d";
751 18 julius
              insn_props->insn_index=78;
752 16 julius
              break;
753
            default:
754
              printf("Unknown lf.xxx.d op (0x%x)",
755
                     insn_or1k_opcode_0x32_get_op_lo(insn));
756
              break;
757
            }
758
          break;
759
 
760
        case 0xd:
761
          insn_props->insn_string="lf.cust1.s";
762 18 julius
          insn_props->insn_index=79;
763 16 julius
          break;
764
 
765
        case 0xe:
766
          insn_props->insn_string="lf.cust1.d";
767 18 julius
          insn_props->insn_index=80;
768 16 julius
          break;
769
 
770
        default:
771
          printf("Unknown lf.xxx opcode hi (0x%x)",
772
                 insn_or1k_opcode_0x32_get_op_hi(insn));
773 17 julius
          return 1;
774 16 julius
          break;
775
        }
776
      break;
777
 
778
    case 0x34:
779
      insn_props->insn_string="l.sd";
780 18 julius
      insn_props->insn_index=81;
781 16 julius
      break;
782
 
783
    case 0x35:
784
      insn_props->insn_string="l.sw";
785 20 julius
      insn_props->has_split_imm = 1;
786 18 julius
      insn_props->insn_index=82;
787 16 julius
      break;
788
 
789
    case 0x36:
790
      insn_props->insn_string="l.sb";
791 20 julius
      insn_props->has_split_imm = 1;
792 18 julius
      insn_props->insn_index=83;
793 16 julius
      break;
794
 
795
    case 0x37:
796
      insn_props->insn_string="l.sh";
797 20 julius
      insn_props->has_split_imm = 1;
798 18 julius
      insn_props->insn_index=84;
799 16 julius
      break;
800
 
801
    case 0x38:
802 17 julius
       insn_props->has_rD = 1;
803
       insn_props->has_rA = 1;
804
       insn_props->has_rB = 1;
805
       switch(insn_or1k_opcode_0x38_get_op_lo(insn))
806
         {
807
         case 0x0:
808 16 julius
          insn_props->insn_string="l.add";
809 18 julius
          insn_props->insn_index=85;
810 16 julius
          break;
811
        case 0x1:
812
          insn_props->insn_string="l.addc";
813 18 julius
          insn_props->insn_index=86;
814 16 julius
          break;
815
        case 0x2:
816
          insn_props->insn_string="l.sub";
817 18 julius
          insn_props->insn_index=87;
818 16 julius
          break;
819
        case 0x3:
820
          insn_props->insn_string="l.and";
821 18 julius
          insn_props->insn_index=88;
822 16 julius
          break;
823
        case 0x4:
824
          insn_props->insn_string="l.or";
825 18 julius
          insn_props->insn_index=89;
826 16 julius
          break;
827
        case 0x5:
828
          insn_props->insn_string="l.xor";
829 18 julius
          insn_props->insn_index=90;
830 16 julius
          break;
831
        case 0x6:
832
          insn_props->insn_string="l.mul";
833 18 julius
          insn_props->insn_index=91;
834 16 julius
          break;
835
        case 0x8:
836
          switch (insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
837
            {
838
            case 0x0:
839
              insn_props->insn_string="l.sll";
840 18 julius
              insn_props->insn_index=92;
841 16 julius
              break;
842
            case 0x1:
843
              insn_props->insn_string="l.srl";
844 18 julius
              insn_props->insn_index=93;
845 16 julius
              break;
846
            case 0x2:
847
              insn_props->insn_string="l.sra";
848 18 julius
              insn_props->insn_index=94;
849 16 julius
              break;
850
            case 0x3:
851
              insn_props->insn_string="l.ror";
852 18 julius
              insn_props->insn_index=95;
853 16 julius
              break;
854
            default:
855
              printf("Unknown ALU op 0x8 hi op (0x%x)",
856
                     insn_or1k_opcode_0x38_get_op_hi_4bit(insn));
857 17 julius
              return 1;
858 16 julius
              break;
859
            }
860
          break;
861
        case 0x9:
862
          insn_props->insn_string="l.div";
863 18 julius
          insn_props->insn_index=96;
864 16 julius
          break;
865
        case 0xa:
866
          insn_props->insn_string="l.divu";
867 18 julius
          insn_props->insn_index=97;
868 16 julius
          break;
869
        case 0xb:
870
          insn_props->insn_string="l.mulu";
871 18 julius
          insn_props->insn_index=98;
872 16 julius
          break;
873
        case 0xc:
874
          switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
875
            {
876
            case 0x0:
877
              insn_props->insn_string="l.exths";
878 18 julius
              insn_props->insn_index=99;
879 16 julius
              break;
880
            case 0x1:
881
              insn_props->insn_string="l.extbs";
882 18 julius
              insn_props->insn_index=100;
883 16 julius
              break;
884
            case 0x2:
885
              insn_props->insn_string="l.exthz";
886 18 julius
              insn_props->insn_index=101;
887 16 julius
              break;
888
            case 0x3:
889
              insn_props->insn_string="l.extbz";
890 18 julius
              insn_props->insn_index=102;
891 16 julius
              break;
892
            }
893
          insn_props->has_rB = 0;
894
          break;
895
 
896
        case 0xd:
897
          insn_props->insn_string="l.extws";
898 18 julius
          insn_props->insn_index=103;
899 16 julius
          insn_props->has_rB = 0;
900
          break;
901
 
902
        case 0xe:
903
          insn_props->insn_string="l.cmov";
904 18 julius
          insn_props->insn_index=104;
905 16 julius
          break;
906
 
907
        case 0xf:
908
          if (insn_or1k_opcode_0x38_get_op_hi_2bit(insn) & 0x1)
909 18 julius
            {
910
              insn_props->insn_string="l.fl1";
911
              insn_props->insn_index=105;
912
            }
913 16 julius
          else
914 18 julius
            {
915
              insn_props->insn_string="l.ff1";
916
              insn_props->insn_index=106;
917
            }
918 16 julius
          insn_props->has_rB = 0;
919
          break;
920
 
921
        default:
922
          printf("Unknown ALU lo op (0x%x)",
923
                 insn_or1k_opcode_0x38_get_op_lo(insn));
924 17 julius
          return 1;
925 16 julius
          break;
926
        }
927
      break;
928
 
929
    case 0x39:
930 17 julius
      insn_props->has_rA = 1;
931
      insn_props->has_rB = 1;
932 16 julius
      switch (insn_or1k_opcode_0x39_get_op(insn))
933
        {
934
        case 0x0:
935
          insn_props->insn_string="l.sfeq";
936 18 julius
          insn_props->insn_index=107;
937 16 julius
          break;
938
        case 0x1:
939
          insn_props->insn_string="l.sfne";
940 18 julius
          insn_props->insn_index=108;
941 16 julius
          break;
942
        case 0x2:
943
          insn_props->insn_string="l.sfgtu";
944 18 julius
          insn_props->insn_index=109;
945 16 julius
          break;
946
        case 0x3:
947
          insn_props->insn_string="l.sfgeu";
948 18 julius
          insn_props->insn_index=110;
949 16 julius
          break;
950
        case 0x4:
951
          insn_props->insn_string="l.sfltu";
952 18 julius
          insn_props->insn_index=111;
953 16 julius
          break;
954
        case 0x5:
955
          insn_props->insn_string="l.sfleu";
956 18 julius
          insn_props->insn_index=112;
957 16 julius
          break;
958
        case 0xa:
959
          insn_props->insn_string="l.sfgts";
960 18 julius
          insn_props->insn_index=113;
961 16 julius
          break;
962
        case 0xb:
963
          insn_props->insn_string="l.sfges";
964 18 julius
          insn_props->insn_index=114;
965 16 julius
          break;
966
        case 0xc:
967
          insn_props->insn_string="l.sflts";
968 18 julius
          insn_props->insn_index=115;
969 16 julius
          break;
970
        case 0xd:
971
          insn_props->insn_string="l.sfles";
972 18 julius
          insn_props->insn_index=116;
973 16 julius
          break;
974
        default:
975
          printf("Unknown opcode for l.sfxxx opcode (0x%x)",
976
                 insn_or1k_opcode_0x39_get_op(insn));
977 17 julius
          return 1;
978 16 julius
          break;
979
        }
980
      break;
981
 
982
    default:
983
      printf("Unknown opcode 0x%x",insn_or1k_opcode(insn));
984
      return 1;
985
      break;
986
    }
987
 
988
  return 0;
989
}
990
 
991
 
992
 
993
void or1k_32_collect_stats(uint32_t insn,
994
                         struct or1k_32_instruction_properties  * insn_props)
995
{
996 18 julius
  // Add this instruction's occurance to our data
997
  insn_lists_add(insn, insn_props);
998 16 julius
 
999 19 julius
  // n-tuple groupings stats recording here!  
1000
  // only if we've seen enough to do all the sequence analysis
1001
  if (num_seen_insns > OR1K_MAX_GROUPINGS_ANALYSIS+1)
1002
    {
1003
      int n;
1004
      for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
1005
        insn_lists_group_add(n, insn_props);
1006
    }
1007
 
1008
  // Finished adding to stats for this instruction
1009 16 julius
 
1010
 
1011 19 julius
}
1012 16 julius
 
1013 18 julius
// Function to add entry to, or increment incidences of, value in the value list
1014
void or1k_add_in_list(struct or1k_value_list * list, int32_t value)
1015
{
1016
  int i;
1017
  // See if it's already in the list
1018
  i=list->count;
1019
 
1020
  while(i)
1021
    {
1022
      i--;
1023
      if(list->values[i][0] == value)
1024
        {
1025
          (list->values[i][1])++;
1026
          return;
1027
        }
1028
    }
1029
 
1030
  if (list->count < OR1K_VALUE_MAX_ENTRIES)
1031
    {
1032
      // Not found, add it to the list
1033
      list->values[(list->count)][0] = value;
1034
      list->values[(list->count)][1] = 1;
1035
      list->count++;
1036 19 julius
    }
1037 18 julius
}
1038
 
1039 16 julius
// List management/analysis functions - accessed through insn_lists() set of
1040
// functions
1041
 
1042
void or1k_32_insn_lists_init(void)
1043
{
1044 18 julius
  num_setup_insns = 0;
1045 16 julius
  num_seen_insns = 0;
1046 18 julius
  // Clear the pointer array so we can tell if things are used or not
1047
  memset(or1k_32_insns, '\0',
1048
         sizeof(struct or1k_insn_info *)*OR1K_32_MAX_INSNS);
1049 16 julius
}
1050
 
1051 18 julius
// Alloc struct and put it into the list
1052
void or1k_32_insn_lists_init_insn(uint32_t insn,
1053
                        struct or1k_32_instruction_properties *insn_props)
1054 16 julius
{
1055
  // Add an instruction in or1k_32_insns[num_unique_instructions];
1056
  // use calloc() so it clears it all first (hopefully!).. assumption!
1057
  struct or1k_insn_info * new_insn
1058
    = (struct or1k_insn_info *) calloc (sizeof(struct or1k_insn_info), 1);
1059
 
1060 18 julius
  // Copy the string pointer
1061
  new_insn->insn_string = insn_props->insn_string,
1062 16 julius
 
1063 18 julius
  // Install the pointer for this newly allocated struct in its corresponding
1064
  // index, as set when we decode the instruction
1065
  or1k_32_insns[insn_props->insn_index] = new_insn;
1066 16 julius
 
1067 19 julius
  // Clear the set statistics counters
1068
  int set_itr;
1069
  for(set_itr=0;set_itr<OR1K_MAX_GROUPINGS_ANALYSIS;set_itr++)
1070
    or1k_32_insns[insn_props->insn_index]->groupings[set_itr][0][0] = 0;
1071
 
1072 18 julius
  // Increment number of instructions we have set up
1073
  num_setup_insns++;
1074 17 julius
 
1075
  // Debugging:
1076
  //printf("Adding %dth instruction - %s\n",
1077 18 julius
  //num_setup_insns, new_insn->insn_string);
1078 16 julius
 
1079
}
1080
 
1081
 
1082 17 julius
 
1083 16 julius
// Add stats for this instruction
1084 18 julius
void or1k_32_insn_lists_add(uint32_t insn,
1085 16 julius
                            struct or1k_32_instruction_properties *insn_props)
1086
{
1087 18 julius
  // Check if the entry for this instruction has been setup yet
1088
  if (or1k_32_insns[insn_props->insn_index] == NULL)
1089
    {
1090
      // Here we allocate space for the instruction's stats
1091
      or1k_32_insn_lists_init_insn(insn, insn_props);
1092
    }
1093 16 julius
 
1094 18 julius
  // Increment occurance count
1095
  ((or1k_32_insns[insn_props->insn_index])->count)++;
1096 16 julius
 
1097
  // Add branch target value information, if instruction has it
1098
  if (insn_props->has_branchtarg)
1099
    {
1100 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_branchtarg = 1;
1101
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->branch_info),
1102 17 julius
                       (int32_t)insn_or1k_opcode_0x03_get_branchoff(insn));
1103 16 julius
    }
1104
 
1105
  // Add immediate value if it's got one
1106
  if (insn_props->has_imm)
1107
    {
1108 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
1109
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
1110 17 julius
                       (int32_t)insn_or1k_32_imm(insn));
1111 16 julius
    }
1112
 
1113
  // Add split immediate value if it's got one
1114
  if (insn_props->has_split_imm)
1115 17 julius
    {
1116 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_imm = 1;
1117
      or1k_add_in_list(&((or1k_32_insns[insn_props->insn_index])->imm_info),
1118 17 julius
                       (int32_t)insn_or1k_32_split_imm(insn));
1119 16 julius
    }
1120
 
1121
 
1122
  // Increment count of use for particular rD
1123
  if (insn_props->has_rD)
1124
    {
1125 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_rD = 1;
1126
      ((or1k_32_insns[insn_props->insn_index])->rD_use_freq[insn_or1k_32_rD(insn)])++;
1127 16 julius
    }
1128
 
1129
  // Increment count of use for particular rA
1130
  if (insn_props->has_rA)
1131
    {
1132 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_rA = 1;
1133
      ((or1k_32_insns[insn_props->insn_index])->rA_use_freq[insn_or1k_32_rA(insn)])++;
1134 16 julius
    }
1135
 
1136
  // Increment count of use for particular rB
1137
  if (insn_props->has_rB)
1138
    {
1139 18 julius
      (or1k_32_insns[insn_props->insn_index])->has_rB = 1;
1140
      ((or1k_32_insns[insn_props->insn_index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
1141 16 julius
    }
1142
 
1143
  // Increment overall instructions "seen" counter
1144
  num_seen_insns++;
1145
 
1146 19 julius
  // Shift along the recently seen instructions
1147
  int i;
1148
  for(i=OR1K_MAX_GROUPINGS_ANALYSIS-1;i>0;i--)
1149
    or1k_32_recent_insns[i] = or1k_32_recent_insns[i-1];
1150
  or1k_32_recent_insns[0] = insn_props->insn_index;
1151
 
1152 16 julius
}
1153
 
1154
 
1155 19 julius
 
1156
 
1157
// Do the n-tuple set analysis for the most recently added instruction
1158
void or1k_32_ntuple_add(int n,
1159
                        struct or1k_32_instruction_properties *insn_props)
1160 16 julius
{
1161 19 julius
 
1162
  if (n<2)
1163 16 julius
    {
1164 19 julius
      fprintf(stderr,"or1k_32_ntuple_add: tuple number < 2 (%d)",n);
1165
      return;
1166 16 julius
    }
1167 19 julius
 
1168
  struct or1k_insn_info * insn_info = or1k_32_insns[insn_props->insn_index];
1169
 
1170
  // Get the number of sets for these n-tuple groups we've seen so far.
1171
  int sets_for_ntuple = insn_info->groupings[n-1][0][0];
1172 20 julius
#if DEBUG_PRINT
1173
  printf("%s\t:\t%d-tuple add - sets so far : %d\n",insn_info->insn_string, n, sets_for_ntuple);
1174
#endif
1175 19 julius
 
1176 20 julius
  int set_match_index;
1177
  int tuple_set_itr, tuple_set_match;
1178
 
1179
  tuple_set_match = 0;
1180 19 julius
 
1181
  // now find if the current n instructions in or1k_32_recent_insns[] matches
1182
  // any set of n instructions we're keeping track of in groupings[][][].
1183 20 julius
#if DEBUG_PRINT
1184
  printf("%s\tChecking\t%d\tsets for ntuple:\t",insn_info->insn_string,sets_for_ntuple);
1185
  for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1186
    printf("%s ",
1187
           or1k_32_insns[(or1k_32_recent_insns[n - 1 - tuple_set_itr])]->insn_string);
1188
  printf("\n");
1189
#endif  
1190 19 julius
  for (set_match_index=0; set_match_index<sets_for_ntuple; set_match_index++)
1191
    {
1192
      // Check this set for a match with our existing trace
1193
      // Example:
1194
      // In case of a triple (n=3), 1st set, [3][1][0] corresponds to the third
1195
      // instruction in the trace (or1k_32_recent_insns[2]), [3][1][1] should 
1196
      // be the second in the trace, and [3][1][2] should be the first in the 
1197
      // trace (same index as insn_props->insn_index)
1198 20 julius
 
1199
#if DEBUG_PRINT
1200
      printf("Chk:\t");
1201
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1202
        printf("%s ",
1203
               or1k_32_insns[(insn_info->groupings[n-1][set_match_index+1][tuple_set_itr])]->insn_string);
1204
      printf("\t(%d)\n", insn_info->groupings[n-1][set_match_index+1][n]);
1205
#endif      
1206
      tuple_set_match = 1;
1207 19 julius
      // Presuppose a match, de-assert and break out of the loop as soon as we
1208
      // detect a mismatch.
1209
      for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1210
        {
1211 20 julius
 
1212 19 julius
          if (insn_info->groupings[n-1][set_match_index+1][tuple_set_itr]
1213 20 julius
              != or1k_32_recent_insns[n - 1 - tuple_set_itr])
1214 19 julius
            {
1215
              tuple_set_match = 0;
1216
              break; // No match, so break out of this for() loop
1217
            }
1218
        }
1219
 
1220
      if (!tuple_set_match)
1221
        continue; // go again...
1222 20 julius
      else
1223
        break; // Bail out, we've found our match
1224 19 julius
    }
1225
 
1226
  if (tuple_set_match)
1227 20 julius
    {
1228
      // Found a match - just increment the counter (set_match_index should
1229
      // be pointing at the right set)            
1230
#if DEBUG_PRINT
1231
      printf("Match!\n");
1232
#endif
1233
 
1234
      (insn_info->groupings[n-1][set_match_index+1][n])++;
1235
    }
1236 19 julius
  else
1237
    {
1238
      // If we can record a new set
1239
      if (sets_for_ntuple < OR1K_MAX_ENTRIES_PER_GROUP)
1240
        {
1241 20 julius
#if DEBUG_PRINT
1242
          printf("New entry\n");
1243
#endif
1244
 
1245 19 julius
          // Increment the number of sets we have for this n-tuple starting
1246
          // on the current instruction  
1247
          sets_for_ntuple++;
1248
          // Add new set to the end (all n instructions, copy in)
1249
          for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1250
            insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr]
1251 20 julius
              = or1k_32_recent_insns[n - 1 - tuple_set_itr];
1252 19 julius
          // Set the count for this set to 1
1253 20 julius
          (insn_info->groupings[n-1][sets_for_ntuple][n]) = 1;
1254 19 julius
          // Increment the counter of these n-tuple sets
1255 20 julius
          insn_info->groupings[n-1][0][0] = sets_for_ntuple;
1256 19 julius
        }
1257 20 julius
    }
1258
 
1259
  // Debugging :
1260
#if DEBUG_PRINT
1261
   if (tuple_set_match)
1262
  {
1263
     printf("%s\t:\tMatch for %d-tuple - set %d - cnt: %d - ",
1264
      insn_info->insn_string, n, set_match_index,
1265
             insn_info->groupings[n-1][set_match_index+1][n]);
1266
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1267
        printf("%s ",
1268
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
1269
    printf("\n");
1270
  }
1271
  else
1272
    {
1273
     printf("%s\t:\tNew %d-tuple - set %d - cnt: %d - ",
1274
             insn_info->insn_string, n, sets_for_ntuple,
1275
             insn_info->groupings[n-1][sets_for_ntuple][n]);
1276
    for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
1277
        printf("%s ",
1278
               or1k_32_insns[(insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr])]->insn_string);
1279
    printf("\n");
1280
  }
1281
#endif
1282
 
1283 16 julius
}
1284 17 julius
 
1285
 
1286
#define DISPLAY_STRING
1287
//#define DISPLAY_CSV
1288
 
1289
void or1k_32_most_freq_insn(FILE * stream)
1290
{
1291
  // Print out most frequent instruction
1292
  int i, largest, largest_index;
1293 18 julius
  int instructions_to_print = num_setup_insns;
1294 17 julius
  while (instructions_to_print)
1295
    {
1296
      --instructions_to_print;
1297
      largest=0;
1298
      // Go through the list, find the largest, print it, eliminate it
1299 18 julius
      for(i=0;i<OR1K_32_MAX_INSNS;i++)
1300
        if (or1k_32_insns[i]!=NULL){
1301
          if(((or1k_32_insns[i])->count) > largest)
1302
            {
1303
              largest = ((or1k_32_insns[i])->count);
1304
              largest_index = i;
1305
            }
1306
        }
1307 17 julius
      fprintf(stream,
1308
#ifdef DISPLAY_STRING      
1309
             "Insn:\t%s\t\tCount:\t\t%d\t(%f%%)\n",
1310
#endif
1311
#ifdef DISPLAY_CSV
1312
             // CSV format - "opcode string",frequency,percentage
1313
             "\"%s\",%d,%f\n",
1314
#endif
1315
             ((or1k_32_insns[largest_index])->insn_string),
1316
             ((or1k_32_insns[largest_index])->count),
1317
             (float)(((float)((or1k_32_insns[largest_index])->count))/
1318
                     ((float)num_seen_insns))*100.f);
1319
 
1320
 
1321
      ((or1k_32_insns[largest_index])->count) = -1; // Eliminate this one
1322
 
1323
    }
1324
}
1325
 
1326
 
1327
// Print out top x of each kept statistic for the requested instruction
1328 18 julius
void or1k_32_insn_top_x(struct or1k_insn_info *insn_info, FILE * stream,
1329
                        int max_stats)
1330 17 julius
{
1331 20 julius
  int i, j, largest_i;
1332 17 julius
 
1333 18 julius
  fprintf(stream,
1334
          "Insn: \"%s\" statistics (%d times (%f%%)):\n",
1335
          insn_info->insn_string,
1336
          insn_info->count,
1337
          (float)(((float)((insn_info)->count))/
1338
                  ((float)num_seen_insns))*100.f
1339
          );
1340 17 julius
 
1341
 
1342
 
1343 18 julius
  // Start dumping applicable stats
1344 17 julius
 
1345
  // Print out top max_stats branch targets
1346 18 julius
  if (insn_info->has_branchtarg)
1347 17 julius
    {
1348
      fprintf(stream,"Branch values:\n");
1349
      i = 0;
1350 18 julius
      while(i<insn_info->branch_info.count && i < max_stats)
1351 17 julius
        {
1352
          largest_i=0;
1353 18 julius
          for(j=0;j<insn_info->branch_info.count;j++)
1354
            largest_i = (insn_info->branch_info.values[j][1] >
1355
                         insn_info->branch_info.values[largest_i][1]) ?
1356 17 julius
              j : largest_i;
1357
 
1358
          // largest_i has index of most frequent value
1359
          fprintf(stream,
1360
                  "value:\t0x%x\tcount:\t%d\n",
1361 18 julius
                  insn_info->branch_info.values[largest_i][0],
1362
                  insn_info->branch_info.values[largest_i][1]);
1363
          insn_info->branch_info.values[largest_i][1] = -1; // clear this one
1364 17 julius
          i++;
1365
        }
1366
    }
1367 18 julius
  if (insn_info->has_imm)
1368 17 julius
    {
1369
      fprintf(stream,"Immediate values:\n");
1370
      i = 0;
1371 18 julius
      while(i<insn_info->imm_info.count && i < max_stats)
1372 17 julius
        {
1373
          largest_i=0;
1374 18 julius
          for(j=0;j<insn_info->imm_info.count;j++)
1375
            largest_i = (insn_info->imm_info.values[j][1] >
1376
                         insn_info->imm_info.values[largest_i][1]) ?
1377 17 julius
              j : largest_i;
1378
 
1379
          // largest_i has index of most frequent value
1380
          fprintf(stream,
1381
                  "value:\t0x%x\tcount:\t%d\n",
1382 18 julius
                  insn_info->imm_info.values[largest_i][0],
1383
                  insn_info->imm_info.values[largest_i][1]);
1384
          insn_info->imm_info.values[largest_i][1] = -1; // clear this one
1385 17 julius
          i++;
1386
        }
1387
    }
1388 18 julius
  if (insn_info->has_rD)
1389 17 julius
    {
1390
      fprintf(stream,"rD usage:\n");
1391
      i = 0;
1392
      while(i<32 && i < max_stats)
1393
        {
1394
          largest_i=0;
1395
          for(j=0;j<32;j++)
1396 18 julius
            largest_i = (insn_info->rD_use_freq[j] >
1397
                         insn_info->rD_use_freq[largest_i]) ?
1398 17 julius
              j : largest_i;
1399
 
1400
          // No more interesting numbers
1401 18 julius
          if (insn_info->rD_use_freq[largest_i] == 0)
1402 17 julius
            break;
1403
 
1404
          // largest_i has index of most frequent value
1405
          fprintf(stream,
1406
                  "r%d\tcount:\t%d\n",
1407
                  largest_i,
1408 18 julius
                  insn_info->rD_use_freq[largest_i]);
1409
          insn_info->rD_use_freq[largest_i] = -1; // clear this one
1410 17 julius
          i++;
1411
        }
1412
    }
1413
 
1414 18 julius
  if (insn_info->has_rA)
1415 17 julius
    {
1416
      fprintf(stream,"rA usage:\n");
1417
      i = 0;
1418
      while(i<32 && i < max_stats)
1419
        {
1420
          largest_i=0;
1421
          for(j=0;j<32;j++)
1422 18 julius
            largest_i = (insn_info->rA_use_freq[j] >
1423
                         insn_info->rA_use_freq[largest_i]) ?
1424 17 julius
              j : largest_i;
1425
 
1426
          // No more interesting numbers
1427 18 julius
          if (insn_info->rA_use_freq[largest_i] == 0)
1428 17 julius
            break;
1429
 
1430
 
1431
          // largest_i has index of most frequent value
1432
          fprintf(stream,
1433
                  "r%d\tcount:\t%d\n",
1434
                  largest_i,
1435 18 julius
                  insn_info->rA_use_freq[largest_i]);
1436
          insn_info->rA_use_freq[largest_i] = -1; // clear this one
1437 17 julius
          i++;
1438
        }
1439
    }
1440
 
1441 18 julius
  if (insn_info->has_rB)
1442 17 julius
    {
1443
      fprintf(stream,"rB usage:\n");
1444
      i = 0;
1445
      while(i<32 && i < max_stats)
1446
        {
1447
          largest_i=0;
1448
          for(j=0;j<32;j++)
1449 18 julius
            largest_i = (insn_info->rB_use_freq[j] >
1450
                         insn_info->rB_use_freq[largest_i]) ?
1451 17 julius
              j : largest_i;
1452
 
1453
          // No more interesting numbers
1454 18 julius
          if (insn_info->rB_use_freq[largest_i] == 0)
1455 17 julius
            break;
1456
 
1457
 
1458
          // largest_i has index of most frequent value
1459
          fprintf(stream,
1460
                  "r%d\tcount:\t%d\n",
1461
                  largest_i,
1462 18 julius
                  insn_info->rB_use_freq[largest_i]);
1463
          insn_info->rB_use_freq[largest_i] = -1; // clear this one
1464 17 julius
          i++;
1465
        }
1466
    }
1467
}
1468 19 julius
 
1469 20 julius
 
1470
 
1471 19 julius
// Print out the most common n-tuple groupings for an instruction
1472
void or1k_32_generate_ntuple_stats(int n, struct or1k_insn_info *insn_info,
1473
                                   FILE * stream)
1474
{
1475 20 julius
  // Maximum number we'll print out
1476
#define MAX_NTUPLE_LISTING 5
1477
 
1478
 
1479
  int (*ntuplelist)[OR1K_MAX_GROUPINGS_ANALYSIS+1];
1480
  int *set;
1481
  int set_count, set_count2;
1482
 
1483
  // Get total number of sets for this n-tuple, eg:
1484
  // if n=2 (pairs) then groupings[1] is where our list is, and we store the number
1485
  // of sets in [0][0] of that n-tuple data.
1486 19 julius
  int total_sets_for_ntuple =  insn_info->groupings[n-1][0][0];
1487
 
1488
  if (total_sets_for_ntuple == 0)
1489
    return;
1490
 
1491 20 julius
  fprintf(stream, "%d-tuple groupings finishing with %s (%d)\n",n, insn_info->insn_string,
1492
          total_sets_for_ntuple);
1493 19 julius
 
1494 20 julius
  // Debug - dump out all of the info for the sets
1495
#if DEBUG_PRINT
1496
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
1497
    {
1498
 
1499
      printf("set: %d - count %d - set: ", set_count, insn_info->groupings[n-1][set_count+1][n]);
1500
 
1501
      for(set_count2=0;set_count2<n;set_count2++)
1502
        fprintf(stream, "%s\t",
1503
                or1k_32_insns[(insn_info->groupings[n-1][set_count+1][set_count2])]->insn_string);
1504
      printf("\n");
1505
    }
1506
#endif
1507
 
1508
  // A pointer to the n-tuple sets
1509 19 julius
  // This is actually a pointer to a 2-dimensional integer array, looking like:
1510 20 julius
  // [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1], so in 2-dimensional 
1511
  // array pointer fashion, we should provide the "column" sizing.
1512
      ntuplelist = insn_info->groupings[n-1];
1513 19 julius
 
1514
  // Let's make a copy of the counts for each... so we don't trash them
1515
  int set_count_copy[OR1K_MAX_ENTRIES_PER_GROUP+1];
1516 20 julius
 
1517
  assert(total_sets_for_ntuple <= OR1K_MAX_ENTRIES_PER_GROUP);
1518
 
1519 19 julius
  // Go through the list, copy the counts for each
1520
  for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
1521
    {
1522 20 julius
      // Pointer to a set's data
1523
      set = ntuplelist[set_count+1];
1524
      // Fish out the copy (0 to n-1 will be the instruction index, n will be the count)
1525
      set_count_copy[set_count+1] = set[n];
1526
      //printf("Set %d, count %d (%d) (%d)\n", set_count+1, set_count_copy[set_count+1], 
1527
      //set[n], insn_info->groupings[n-1][set_count+1][n] );
1528 19 julius
    }
1529
 
1530
  // Now go through, finding the most frequent n-tuple of instructions and
1531
  // print it out
1532
  int largest_indx = 0;
1533
  set_count=0;
1534
  while(set_count < total_sets_for_ntuple && set_count < MAX_NTUPLE_LISTING)
1535
    {
1536
      largest_indx = 0;
1537
      for(set_count2=0;set_count2<total_sets_for_ntuple;set_count2++)
1538
        largest_indx = (set_count_copy[set_count2 + 1] >
1539
                        set_count_copy[largest_indx + 1]) ?
1540
          set_count2 : largest_indx;
1541
      // largest_indx is the index of the set with the highest occurance, so
1542
      // let's print it out, but first get a pointer to the set's data
1543
      set = (int*)ntuplelist[largest_indx+1];
1544 20 julius
 
1545 19 julius
      // Print out the sequence of prior isntructions
1546
      fprintf(stream,"Seq:\t");
1547
      // Go through the indexes of the previous instructions, get their
1548
      // strings, and print them out
1549
      for(set_count2=0;set_count2<n;set_count2++)
1550
        fprintf(stream, "%s\t", or1k_32_insns[(set[set_count2])]->insn_string);
1551
 
1552
      // now print out the occurances
1553 21 julius
      fprintf(stream, "\t%d\ttimes (%f%%)\n", set[n],
1554
              (float)((float)set[n]/(float)insn_info->count)*100.0f);
1555
 
1556 19 julius
      // done printing this one out.. let's clear its count
1557
      set_count_copy[largest_indx + 1] = -1;
1558
 
1559
      set_count++;
1560
    }
1561
 
1562
  return;
1563
 
1564
}
1565
 
1566
 
1567
// Print out the stats relating to the sequences of instructions most
1568
// common before seeing this instruction
1569
void or1k_32_generate_groupings_stats(struct or1k_insn_info *insn_info,
1570
                                      FILE * stream)
1571
{
1572
  int n;
1573
  for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
1574
    or1k_32_generate_ntuple_stats(n, insn_info, stream);
1575
 
1576
}
1577 16 julius
 
1578 17 julius
void or1k_32_generate_stats(FILE * stream)
1579
{
1580
  // Generate some useful things
1581
  fprintf(stream, "Analysis output:\n");
1582
 
1583
  // 
1584
 
1585
  // Print out all stats for every instruction we saw!
1586 18 julius
  int insn_index;
1587
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
1588 17 julius
    {
1589 18 julius
      if (or1k_32_insns[insn_index] != NULL)
1590 19 julius
        {
1591
          or1k_32_insn_top_x(or1k_32_insns[insn_index],stream,10);
1592
          or1k_32_generate_groupings_stats(or1k_32_insns[insn_index],stream);
1593 21 julius
          fprintf(stream, "\t---\t---\t---\t---\n");
1594 19 julius
        }
1595 17 julius
    }
1596
 
1597
  // Do most frequent instruction analysis -- note this trashes instruction
1598
  // frequency count - should be fixed
1599 21 julius
  fprintf(stream, "Individual instruction frequency:\n");
1600 17 julius
  or1k_32_most_freq_insn(stream);
1601
 
1602
}
1603 19 julius
 
1604
 
1605
 
1606
 
1607
// Free up all added instruction statistic tracking structs
1608
void or1k_32_insn_lists_free(void)
1609
{
1610
  // Free all entries we m/calloc()'d
1611
  int insn_index;
1612
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
1613
    {
1614
      if (or1k_32_insns[insn_index] != NULL)
1615
        free(or1k_32_insns[insn_index]);
1616
    }
1617
}

powered by: WebSVN 2.1.0

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