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 17

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
#include "or1k-32-insn.h"
14
 
15
// These should also be in insnanalysis.h insnanalysis.h
16
typedef uint32_t instruction;
17
typedef struct or1k_32_instruction_properties instruction_properties ;
18
 
19
#include "insn-lists.h"
20
 
21
 
22
int or1k_32_analyse_insn(uint32_t insn,
23
                         struct or1k_32_instruction_properties  * insn_props)
24
{
25
 
26
  switch(insn_or1k_opcode(insn))
27
    {
28
    case 0x00:
29
      insn_props->insn_string="l.j";
30
      insn_props->has_jumptarg = 1;
31
      break;
32
 
33
    case 0x01:
34
      insn_props->insn_string="l.jal";
35
      insn_props->has_jumptarg = 1;
36
      break;
37
 
38
     case 0x03:
39
      insn_props->insn_string="l.bnf";
40
      insn_props->has_branchtarg = 1;
41
      break;
42
 
43
    case 0x04:
44
      insn_props->insn_string="l.bf";
45
      insn_props->has_branchtarg = 1;
46
      break;
47
 
48
    case 0x05:
49
      insn_props->insn_string="l.nop";
50
      break;
51
 
52
    case 0x06:
53
      if((insn_or1k_opcode_0x06_get_id(insn)))
54
        insn_props->insn_string="l.macrc";
55
      else
56
        {
57
          insn_props->insn_string="l.movhi";
58
          insn_props->has_rD = 1;
59
          insn_props->has_imm = 1;
60
        }
61
 
62
      break;
63
 
64
    case 0x08:
65
 
66
      switch(insn_or1k_opcode_0x08_get_id(insn))
67
        {
68
        case 0x0:
69
          insn_props->insn_string="l.sys";
70
          break;
71
        case 0x2:
72
          insn_props->insn_string="l.trap";
73
          break;
74
        case 0x4:
75
          insn_props->insn_string="l.msync";
76
          break;
77
        case 0x5:
78
          insn_props->insn_string="l.psync";
79
          break;
80
        case 0x6:
81
          insn_props->insn_string="l.csync";
82
          break;
83
        default:
84
          printf("Unknown id (0x%x) in opcode 0x8",
85
                 insn_or1k_opcode_0x08_get_id(insn) );
86
          return 1;
87
          break;
88
        }
89
      break;
90
 
91
    case 0x09:
92
      insn_props->insn_string="l.rfe";
93
      break;
94
 
95
    case 0x0a:
96
      switch(insn_or1k_opcode_0x0a_get_op_hi(insn))
97
        {
98
        case 0x1:
99
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
100
            {
101
            case 0x0:
102
              break;
103
            case 0x1:
104
              break;
105
            case 0x2:
106
              break;
107
            case 0x3:
108
              break;
109
            case 0x4:
110
              break;
111
            case 0x5:
112
              break;
113
            case 0x6:
114
              break;
115
            case 0x7:
116
              break;
117
            case 0x8:
118
              break;
119
            case 0x9:
120
              break;
121
            case 0xa:
122
              break;
123
            case 0xb:
124
              break;
125
            default:
126
              printf("Unknown lv.all_xx insn");
127 17 julius
              return 1;
128 16 julius
            }
129
        case 0x2:
130
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
131
            {
132
            case 0x0:
133
              break;
134
            case 0x1:
135
              break;
136
            case 0x2:
137
              break;
138
            case 0x3:
139
              break;
140
            case 0x4:
141
              break;
142
            case 0x5:
143
              break;
144
            case 0x6:
145
              break;
146
            case 0x7:
147
              break;
148
            case 0x8:
149
              break;
150
            case 0x9:
151
              break;
152
            case 0xa:
153
              break;
154
            case 0xb:
155
              break;
156
            default:
157
              printf("Unknown lv.any_xx insn");
158 17 julius
              return 1;
159 16 julius
            }
160
          break;
161
        case 0x3:
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
            default:
187
              printf("Unknown lv.add/and/avg_xx insn");
188 17 julius
              return 1;
189 16 julius
            }
190
          break;
191
        case 0x4:
192
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
193
            {
194
            case 0x0:
195
              break;
196
            case 0x1:
197
              break;
198
            case 0x2:
199
              break;
200
            case 0x3:
201
              break;
202
            case 0x4:
203
              break;
204
            case 0x5:
205
              break;
206
            case 0x6:
207
              break;
208
            case 0x7:
209
              break;
210
            case 0x8:
211
              break;
212
            case 0x9:
213
              break;
214
            case 0xa:
215
              break;
216
            case 0xb:
217
              break;
218
            default:
219
              printf("Unknown lv.cmp_xx insn");
220 17 julius
              return 1;
221 16 julius
            }
222
          break;
223
        case 0x5:
224
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
225
            {
226
            case 0x4:
227
              break;
228
            case 0x5:
229
              break;
230
            case 0x6:
231
              break;
232
            case 0x7:
233
              break;
234
            case 0x8:
235
              break;
236
            case 0x9:
237
              break;
238
            case 0xa:
239
              break;
240
            case 0xb:
241
              break;
242
            case 0xc:
243
              break;
244
            case 0xd:
245
              break;
246
            case 0xe:
247
              break;
248
            case 0xf:
249
              break;
250
            default:
251
              printf("Unknown lv.alu_xx insn");
252 17 julius
              return 1;
253 16 julius
            }
254
          break;
255
        case 0x6:
256
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
257
            {
258
            case 0x0:
259
              break;
260
            case 0x1:
261
              break;
262
            case 0x2:
263
              break;
264
            case 0x3:
265
              break;
266
            case 0x4:
267
              break;
268
            case 0x5:
269
              break;
270
            case 0x6:
271
              break;
272
            case 0x7:
273
              break;
274
            case 0x8:
275
              break;
276
            case 0x9:
277
              break;
278
            case 0xa:
279
              break;
280
            case 0xb:
281
              break;
282
            case 0xc:
283
              break;
284
            case 0xd:
285
              break;
286
            case 0xe:
287
              break;
288
            case 0xf:
289
              break;
290
            default:
291
              printf("Unknown lv.pack_xx insn");
292 17 julius
              return 1;
293 16 julius
            }
294
          break;
295
        case 0x7:
296
          switch(insn_or1k_opcode_0x0a_get_op_lo(insn))
297
            {
298
            case 0x0:
299
              break;
300
            case 0x1:
301
              break;
302
            case 0x2:
303
              break;
304
            case 0x3:
305
              break;
306
            case 0x4:
307
              break;
308
            case 0x5:
309
              break;
310
            case 0x6:
311
              break;
312
            case 0x7:
313
              break;
314
            case 0x8:
315
              break;
316
            case 0x9:
317
              break;
318
            case 0xa:
319
              break;
320
            case 0xb:
321
              break;
322
            default:
323
              printf("Unknown lv.sub/unpack/xor_xx insn");
324 17 julius
              return 1;
325 16 julius
            }
326
          break;
327
        case 0xc:
328
          break;
329
        case 0xd:
330
          break;
331
        case 0xe:
332
          break;
333
        case 0xf:
334
          break;
335
        default:
336
          printf("Unknown lv.xxx insn hi op");
337 17 julius
          return 1;
338 16 julius
          break;
339
        }
340
      break;
341
 
342
    case 0x11:
343
      insn_props->insn_string="l.jr";
344
      insn_props->has_rB = 1;
345
      break;
346
 
347
    case 0x12:
348
      insn_props->insn_string="l.jalr";
349
      insn_props->has_rB = 1;
350
      break;
351
 
352
    case 0x13:
353
      insn_props->insn_string="l.maci";
354
      break;
355
 
356
    case 0x1c:
357
      insn_props->insn_string="l.cust1";
358
      break;
359
 
360
    case 0x1d:
361
      insn_props->insn_string="l.cust2";
362
      break;
363
 
364
    case 0x1e:
365
      insn_props->insn_string="l.cust3";
366
      break;
367
 
368
    case 0x1f:
369
      insn_props->insn_string="l.cust4";
370
      break;
371
 
372
    case 0x20:
373
      insn_props->insn_string="l.ld";
374
      insn_props->has_rD = 1;
375
      insn_props->has_rA = 1;
376
      insn_props->has_imm = 1;
377
      break;
378
 
379
    case 0x21:
380
      insn_props->insn_string="l.lwz";
381
      insn_props->has_rD = 1;
382
      insn_props->has_rA = 1;
383
      insn_props->has_imm = 1;
384
      break;
385
 
386
    case 0x22:
387
      insn_props->insn_string="l.lws";
388
      insn_props->has_rD = 1;
389
      insn_props->has_rA = 1;
390
      insn_props->has_imm = 1;
391
      break;
392
 
393
    case 0x23:
394
      insn_props->insn_string="l.lbz";
395
      insn_props->has_rD = 1;
396
      insn_props->has_rA = 1;
397
      insn_props->has_imm = 1;
398
      break;
399
 
400
    case 0x24:
401
      insn_props->insn_string="l.lbs";
402
      insn_props->has_rD = 1;
403
      insn_props->has_rA = 1;
404
      insn_props->has_imm = 1;
405
      break;
406
 
407
    case 0x25:
408
      insn_props->insn_string="l.lhz";
409
      insn_props->has_rD = 1;
410
      insn_props->has_rA = 1;
411
      insn_props->has_imm = 1;
412
      break;
413
 
414
    case 0x26:
415
      insn_props->insn_string="l.lhs";
416
      insn_props->has_rD = 1;
417
      insn_props->has_rA = 1;
418
      insn_props->has_imm = 1;
419
      break;
420
 
421
 
422
    case 0x27:
423
      insn_props->insn_string="l.addi";
424
      insn_props->has_rD = 1;
425
      insn_props->has_rA = 1;
426
      insn_props->has_imm = 1;
427
      break;
428
 
429
    case 0x28:
430
      insn_props->insn_string="l.addic";
431
      insn_props->has_rD = 1;
432
      insn_props->has_rA = 1;
433
      insn_props->has_imm = 1;
434
      break;
435
 
436
    case 0x29:
437
      insn_props->insn_string="l.andi";
438
      insn_props->has_rD = 1;
439
      insn_props->has_rA = 1;
440
      insn_props->has_imm = 1;
441
      break;
442
 
443
    case 0x2a:
444
      insn_props->insn_string="l.ori";
445
      insn_props->has_rD = 1;
446
      insn_props->has_rA = 1;
447
      insn_props->has_imm = 1;
448
      break;
449
 
450
    case 0x2b:
451
      insn_props->insn_string="l.xori";
452
      insn_props->has_rD = 1;
453
      insn_props->has_rA = 1;
454
      insn_props->has_imm = 1;
455
      break;
456
 
457
    case 0x2c:
458
      insn_props->insn_string="l.muli";
459
      insn_props->has_rD = 1;
460
      insn_props->has_rA = 1;
461
      insn_props->has_imm = 1;
462
      break;
463
 
464
    case 0x2d:
465
      insn_props->insn_string="l.mfspr";
466
      insn_props->has_rD = 1;
467
      insn_props->has_rA = 1;
468
      insn_props->has_imm = 1;
469
      break;
470
 
471
    case 0x2e:
472
      switch(insn_or1k_opcode_0x2e_get_op(insn))
473
        {
474
        case 0x0:
475
          insn_props->insn_string="l.slli";
476
          break;
477
        case 0x1:
478
          insn_props->insn_string="l.srli";
479
          break;
480
        case 0x2:
481
          insn_props->insn_string="l.srai";
482
          break;
483
        case 0x3:
484
          insn_props->insn_string="l.rori";
485
          break;
486
        default:
487
          printf("Unknown shift op (0x%x)",
488
                 insn_or1k_opcode_0x2e_get_op(insn));
489 17 julius
          return 1;
490 16 julius
          break;
491
        }
492
      break;
493
 
494
    case 0x2f:
495
      switch(insn_or1k_opcode_0x2f_get_op(insn))
496
        {
497
        case 0x0:
498
          insn_props->insn_string="l.sfeqi";
499
          break;
500
        case 0x1:
501
          insn_props->insn_string="l.sfnei";
502
          break;
503
        case 0x2:
504
          insn_props->insn_string="l.sfgtui";
505
          break;
506
        case 0x3:
507
          insn_props->insn_string="l.sfgeui";
508
          break;
509
        case 0x4:
510
          insn_props->insn_string="l.sfltui";
511
          break;
512
        case 0x5:
513
          insn_props->insn_string="l.sfleui";
514
          break;
515
        case 0xa:
516
          insn_props->insn_string="l.sfgtsi";
517
          break;
518
        case 0xb:
519
          insn_props->insn_string="l.sfgesi";
520
          break;
521
        case 0xc:
522
          insn_props->insn_string="l.sfltsi";
523
          break;
524
        case 0xd:
525
          insn_props->insn_string="l.sflesi";
526
          break;
527
 
528
        default:
529
          printf("Unknown set flag op (0x%x)",
530
                 insn_or1k_opcode_0x2f_get_op(insn));
531 17 julius
          return 1;
532 16 julius
          break;
533
        }
534
      insn_props->has_rA = 1;
535
      insn_props->has_imm = 1;
536
      break;
537
 
538
 
539
    case 0x30:
540
      insn_props->insn_string="l.mtspr";
541
      break;
542
 
543
    case 0x31:
544
      switch (insn_or1k_opcode_0x31_get_op(insn))
545
        {
546
        case 0x1:
547
          insn_props->insn_string="l.mac";
548
          break;
549
        case 0x2:
550
          insn_props->insn_string="l.msb";
551
          break;
552
        default:
553
          printf("Unknown mac op (0x%x)",
554
                 insn_or1k_opcode_0x31_get_op(insn));
555 17 julius
          return 1;
556 16 julius
        }
557
      break;
558
 
559
    case 0x32:
560
      switch(insn_or1k_opcode_0x32_get_op_hi(insn))
561
        {
562
        case 0x0:
563
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
564
            {
565
            case 0x0:
566
              insn_props->insn_string="lf.add.s";
567
              break;
568
            case 0x1:
569
              insn_props->insn_string="lf.sub.s";
570
              break;
571
            case 0x2:
572
              insn_props->insn_string="lf.mul.s";
573
              break;
574
            case 0x3:
575
              insn_props->insn_string="lf.div.s";
576
              break;
577
            case 0x4:
578
              insn_props->insn_string="lf.itof.s";
579
              break;
580
            case 0x5:
581
              insn_props->insn_string="lf.ftoi.s";
582
              break;
583
            case 0x6:
584
              insn_props->insn_string="lf.rem.s";
585
              break;
586
            case 0x7:
587
              insn_props->insn_string="lf.madd.s";
588
              break;
589
            case 0x8:
590
              insn_props->insn_string="lf.sfeq.s";
591
              break;
592
            case 0x9:
593
              insn_props->insn_string="lf.sfne.s";
594
              break;
595
            case 0xa:
596
              insn_props->insn_string="lf.sfgt.s";
597
              break;
598
            case 0xb:
599
              insn_props->insn_string="lf.sfge.s";
600
              break;
601
            case 0xc:
602
              insn_props->insn_string="lf.sflt.s";
603
              break;
604
            case 0xd:
605
              insn_props->insn_string="lf.sfle.s";
606
              break;
607
            default:
608
              printf("Unknown lf.xxx.s op (0x%x)",
609
                     insn_or1k_opcode_0x32_get_op_lo(insn));
610
              break;
611
            }
612
          break;
613
 
614
        case 0x1:
615
          switch(insn_or1k_opcode_0x32_get_op_lo(insn))
616
            {
617
            case 0x0:
618
              insn_props->insn_string="lf.add.d";
619
              break;
620
            case 0x1:
621
              insn_props->insn_string="lf.sub.d";
622
              break;
623
            case 0x2:
624
              insn_props->insn_string="lf.mul.d";
625
              break;
626
            case 0x3:
627
              insn_props->insn_string="lf.div.d";
628
              break;
629
            case 0x4:
630
              insn_props->insn_string="lf.itof.d";
631
              break;
632
            case 0x5:
633
              insn_props->insn_string="lf.ftoi.d";
634
              break;
635
            case 0x6:
636
              insn_props->insn_string="lf.rem.d";
637
              break;
638
            case 0x7:
639
              insn_props->insn_string="lf.madd.d";
640
              break;
641
            case 0x8:
642
              insn_props->insn_string="lf.sfeq.d";
643
              break;
644
            case 0x9:
645
              insn_props->insn_string="lf.sfne.d";
646
              break;
647
            case 0xa:
648
              insn_props->insn_string="lf.sfgt.d";
649
              break;
650
            case 0xb:
651
              insn_props->insn_string="lf.sfge.d";
652
              break;
653
            case 0xc:
654
              insn_props->insn_string="lf.sflt.d";
655
              break;
656
            case 0xd:
657
              insn_props->insn_string="lf.sfle.d";
658
              break;
659
            default:
660
              printf("Unknown lf.xxx.d op (0x%x)",
661
                     insn_or1k_opcode_0x32_get_op_lo(insn));
662
              break;
663
            }
664
          break;
665
 
666
        case 0xd:
667
          insn_props->insn_string="lf.cust1.s";
668
          break;
669
 
670
        case 0xe:
671
          insn_props->insn_string="lf.cust1.d";
672
          break;
673
 
674
        default:
675
          printf("Unknown lf.xxx opcode hi (0x%x)",
676
                 insn_or1k_opcode_0x32_get_op_hi(insn));
677 17 julius
          return 1;
678 16 julius
          break;
679
        }
680
      break;
681
 
682
    case 0x34:
683
      insn_props->insn_string="l.sd";
684
      break;
685
 
686
    case 0x35:
687
      insn_props->insn_string="l.sw";
688
      break;
689
 
690
    case 0x36:
691
      insn_props->insn_string="l.sb";
692
      break;
693
 
694
    case 0x37:
695
      insn_props->insn_string="l.sh";
696
      break;
697
 
698
    case 0x38:
699 17 julius
       insn_props->has_rD = 1;
700
       insn_props->has_rA = 1;
701
       insn_props->has_rB = 1;
702
       switch(insn_or1k_opcode_0x38_get_op_lo(insn))
703
         {
704
         case 0x0:
705 16 julius
          insn_props->insn_string="l.add";
706
          break;
707
        case 0x1:
708
          insn_props->insn_string="l.addc";
709
          break;
710
        case 0x2:
711
          insn_props->insn_string="l.sub";
712
          break;
713
        case 0x3:
714
          insn_props->insn_string="l.and";
715
          break;
716
        case 0x4:
717
          insn_props->insn_string="l.or";
718
          break;
719
        case 0x5:
720
          insn_props->insn_string="l.xor";
721
          break;
722
        case 0x6:
723
          insn_props->insn_string="l.mul";
724
          break;
725
        case 0x8:
726
          switch (insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
727
            {
728
            case 0x0:
729
              insn_props->insn_string="l.sll";
730
              break;
731
            case 0x1:
732
              insn_props->insn_string="l.srl";
733
              break;
734
            case 0x2:
735
              insn_props->insn_string="l.sra";
736
              break;
737
            case 0x3:
738
              insn_props->insn_string="l.ror";
739
              break;
740
            default:
741
              printf("Unknown ALU op 0x8 hi op (0x%x)",
742
                     insn_or1k_opcode_0x38_get_op_hi_4bit(insn));
743 17 julius
              return 1;
744 16 julius
              break;
745
            }
746
          break;
747
        case 0x9:
748
          insn_props->insn_string="l.div";
749
          break;
750
        case 0xa:
751
          insn_props->insn_string="l.divu";
752
          break;
753
        case 0xb:
754
          insn_props->insn_string="l.mulu";
755
          break;
756
        case 0xc:
757
          switch(insn_or1k_opcode_0x38_get_op_hi_4bit(insn))
758
            {
759
            case 0x0:
760
              insn_props->insn_string="l.exths";
761
              break;
762
            case 0x1:
763
              insn_props->insn_string="l.extbs";
764
              break;
765
            case 0x2:
766
              insn_props->insn_string="l.exthz";
767
              break;
768
            case 0x3:
769
              insn_props->insn_string="l.extbz";
770
              break;
771
            }
772
          insn_props->has_rB = 0;
773
          break;
774
 
775
        case 0xd:
776
          insn_props->insn_string="l.extws";
777
          insn_props->has_rB = 0;
778
          break;
779
 
780
        case 0xe:
781
          insn_props->insn_string="l.cmov";
782
          break;
783
 
784
        case 0xf:
785
          if (insn_or1k_opcode_0x38_get_op_hi_2bit(insn) & 0x1)
786
            insn_props->insn_string="l.fl1";
787
          else
788
            insn_props->insn_string="l.ff1";
789
          insn_props->has_rB = 0;
790
          break;
791
 
792
        default:
793
          printf("Unknown ALU lo op (0x%x)",
794
                 insn_or1k_opcode_0x38_get_op_lo(insn));
795 17 julius
          return 1;
796 16 julius
          break;
797
        }
798
      break;
799
 
800
    case 0x39:
801 17 julius
      insn_props->has_rA = 1;
802
      insn_props->has_rB = 1;
803 16 julius
      switch (insn_or1k_opcode_0x39_get_op(insn))
804
        {
805
        case 0x0:
806
          insn_props->insn_string="l.sfeq";
807
          break;
808
        case 0x1:
809
          insn_props->insn_string="l.sfne";
810
          break;
811
        case 0x2:
812
          insn_props->insn_string="l.sfgtu";
813
          break;
814
        case 0x3:
815
          insn_props->insn_string="l.sfgeu";
816
          break;
817
        case 0x4:
818
          insn_props->insn_string="l.sfltu";
819
          break;
820
        case 0x5:
821
          insn_props->insn_string="l.sfleu";
822
          break;
823
        case 0xa:
824
          insn_props->insn_string="l.sfgts";
825
          break;
826
        case 0xb:
827
          insn_props->insn_string="l.sfges";
828
          break;
829
        case 0xc:
830
          insn_props->insn_string="l.sflts";
831
          break;
832
        case 0xd:
833
          insn_props->insn_string="l.sfles";
834
          break;
835
        default:
836
          printf("Unknown opcode for l.sfxxx opcode (0x%x)",
837
                 insn_or1k_opcode_0x39_get_op(insn));
838 17 julius
          return 1;
839 16 julius
          break;
840
        }
841
      break;
842
 
843
    default:
844
      printf("Unknown opcode 0x%x",insn_or1k_opcode(insn));
845
      return 1;
846
      break;
847
    }
848
 
849
  return 0;
850
}
851
 
852
 
853
 
854
void or1k_32_collect_stats(uint32_t insn,
855
                         struct or1k_32_instruction_properties  * insn_props)
856
{
857
  // First calculate frequency
858
  int index = insn_lists_check(insn, insn_props);
859
 
860
  // Create new entry in list
861
  if (index == IS_UNIQUE)
862
    index = insn_lists_add_unique_insn(insn, insn_props);
863
 
864
  // Now count it
865
  insn_lists_add(index, insn, insn_props);
866
 
867
}
868
 
869
 
870
 
871
struct or1k_value_list
872
{
873
 
874
#define OR1K_VALUE_MAX_ENTRIES 64
875
  int count;
876
  // [value][occurances_of_value]
877 17 julius
  int32_t values[OR1K_VALUE_MAX_ENTRIES][2];
878 16 julius
 
879
};
880
 
881
 
882
struct or1k_insn_info
883
{
884
  char* insn_string;
885
 
886
  int count;
887
 
888
  int has_branchtarg;
889
  struct or1k_value_list branch_info;
890
 
891
  int has_imm;
892
 
893
  struct or1k_value_list imm_info;
894
 
895
  int has_rD;
896
  int rD_use_freq[32];
897
  int has_rA;
898
  int rA_use_freq[32];
899
  int has_rB;
900
  int rB_use_freq[32];
901
 
902
};
903
 
904
#define OR1K_32_MAX_INSNS 120
905
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
906
 
907
 
908
// List management/analysis functions - accessed through insn_lists() set of
909
// functions
910
 
911
// Variable to keep track of unique instructions we have
912
int num_unique_insns;
913
int num_seen_insns;
914
 
915
 
916
void or1k_32_insn_lists_init(void)
917
{
918
  num_unique_insns = 0;
919
  num_seen_insns = 0;
920
}
921
 
922
// List management/analysis functions
923
int or1k_32_insn_lists_check(uint32_t insn,
924
                             struct or1k_32_instruction_properties *insn_props)
925
{
926
 
927
  int num_to_check = num_unique_insns;
928
  int insn_strlen = strlen(insn_props->insn_string);
929
  while (num_to_check)
930
    {
931
 
932
      --num_to_check;
933
 
934
      if ((strncmp(insn_props->insn_string,
935
                   or1k_32_insns[num_to_check]->insn_string, insn_strlen) == 0)
936
          && (insn_strlen == strlen(or1k_32_insns[num_to_check]->insn_string)))
937
        {
938
          // Found match by string
939
          return num_to_check;
940
        }
941
    }
942
 
943
  return IS_UNIQUE;
944
}
945
 
946
// Add a unique instruction
947
int or1k_32_insn_lists_add_unique_insn(uint32_t insn,
948
                           struct or1k_32_instruction_properties *insn_props)
949
{
950
  // Add an instruction in or1k_32_insns[num_unique_instructions];
951
  // use calloc() so it clears it all first (hopefully!).. assumption!
952
  struct or1k_insn_info * new_insn
953
    = (struct or1k_insn_info *) calloc (sizeof(struct or1k_insn_info), 1);
954
 
955
  // Calloc() space for the string
956
  new_insn->insn_string = (char *) calloc(strlen(insn_props->insn_string), 1);
957
 
958
  // Copy in the instruction string
959
  strncpy(new_insn->insn_string, insn_props->insn_string,
960
          strlen(insn_props->insn_string));
961
 
962
  // Install the pointer for this new instruction in the list
963
  or1k_32_insns[num_unique_insns] = new_insn;;
964
 
965
  // Increment number of instructions we have
966
  num_unique_insns++;
967 17 julius
 
968
  // Debugging:
969
  //printf("Adding %dth instruction - %s\n",
970
  //num_unique_insns, new_insn->insn_string);
971
 
972 16 julius
  // Return index of newly created instruction
973
  return (num_unique_insns - 1);
974
 
975
}
976
 
977
// Add to, or increment incidences of, value in the value list
978 17 julius
void or1k_add_in_list(struct or1k_value_list * list, int32_t value)
979 16 julius
{
980
  int i;
981
  // See if it's already in the list
982
  i=list->count;
983
 
984
  while(i)
985
    {
986
      i--;
987
      if(list->values[i][0] == value)
988
        {
989
          (list->values[i][1])++;
990
          return;
991
        }
992
    }
993 17 julius
 
994
  if (list->count < OR1K_VALUE_MAX_ENTRIES)
995
    {
996
      // Not found, add it to the list
997
      list->values[(list->count)][0] = value;
998
      list->values[(list->count)][1] = 1;
999
      list->count++;
1000
    }
1001 16 julius
 
1002
}
1003
 
1004
 
1005
// Add stats for this instruction
1006
void or1k_32_insn_lists_add(int index, uint32_t insn,
1007
                            struct or1k_32_instruction_properties *insn_props)
1008
{
1009
  // Add stats for this instruction
1010
 
1011
  // Increment count
1012
  ((or1k_32_insns[index])->count)++;
1013
 
1014
  // Add branch target value information, if instruction has it
1015
  if (insn_props->has_branchtarg)
1016
    {
1017
      (or1k_32_insns[index])->has_branchtarg = 1;
1018
      or1k_add_in_list(&((or1k_32_insns[index])->branch_info),
1019 17 julius
                       (int32_t)insn_or1k_opcode_0x03_get_branchoff(insn));
1020 16 julius
    }
1021
 
1022
  // Add immediate value if it's got one
1023
  if (insn_props->has_imm)
1024
    {
1025
      (or1k_32_insns[index])->has_imm = 1;
1026
      or1k_add_in_list(&((or1k_32_insns[index])->imm_info),
1027 17 julius
                       (int32_t)insn_or1k_32_imm(insn));
1028 16 julius
    }
1029
 
1030
  // Add split immediate value if it's got one
1031
  if (insn_props->has_split_imm)
1032 17 julius
    {
1033 16 julius
      (or1k_32_insns[index])->has_imm = 1;
1034
      or1k_add_in_list(&((or1k_32_insns[index])->imm_info),
1035 17 julius
                       (int32_t)insn_or1k_32_split_imm(insn));
1036 16 julius
    }
1037
 
1038
 
1039
  // Increment count of use for particular rD
1040
  if (insn_props->has_rD)
1041
    {
1042
      (or1k_32_insns[index])->has_rD = 1;
1043
      ((or1k_32_insns[index])->rD_use_freq[insn_or1k_32_rD(insn)])++;
1044
    }
1045
 
1046
  // Increment count of use for particular rA
1047
  if (insn_props->has_rA)
1048
    {
1049
      (or1k_32_insns[index])->has_rA = 1;
1050
      ((or1k_32_insns[index])->rA_use_freq[insn_or1k_32_rA(insn)])++;
1051
    }
1052
 
1053
  // Increment count of use for particular rB
1054
  if (insn_props->has_rB)
1055
    {
1056
      (or1k_32_insns[index])->has_rB = 1;
1057
      ((or1k_32_insns[index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
1058
    }
1059
 
1060
  // Finished adding to stats for this instruction
1061
 
1062
  // Increment overall instructions "seen" counter
1063
  num_seen_insns++;
1064
 
1065
}
1066
 
1067
 
1068
// Free up all added instruction statistic tracking structs
1069
void or1k_32_insn_lists_free(void)
1070
{
1071
  while (num_unique_insns)
1072
    {
1073
 
1074
      num_unique_insns--;
1075
 
1076 17 julius
      free((or1k_32_insns[num_unique_insns]->insn_string));
1077 16 julius
      free(or1k_32_insns[num_unique_insns]);
1078
 
1079
    }
1080
}
1081 17 julius
 
1082
 
1083
#define DISPLAY_STRING
1084
//#define DISPLAY_CSV
1085
 
1086
void or1k_32_most_freq_insn(FILE * stream)
1087
{
1088
  // Print out most frequent instruction
1089
  int i, largest, largest_index;
1090
  int instructions_to_print = num_unique_insns;
1091
  while (instructions_to_print)
1092
    {
1093
      --instructions_to_print;
1094
      largest=0;
1095
      // Go through the list, find the largest, print it, eliminate it
1096
      for(i=0;i<num_unique_insns;i++)
1097
        if(((or1k_32_insns[i])->count) > largest)
1098
          {
1099
            largest = ((or1k_32_insns[i])->count);
1100
            largest_index = i;
1101
          }
1102
 
1103
      fprintf(stream,
1104
#ifdef DISPLAY_STRING      
1105
             "Insn:\t%s\t\tCount:\t\t%d\t(%f%%)\n",
1106
#endif
1107
#ifdef DISPLAY_CSV
1108
             // CSV format - "opcode string",frequency,percentage
1109
             "\"%s\",%d,%f\n",
1110
#endif
1111
             ((or1k_32_insns[largest_index])->insn_string),
1112
             ((or1k_32_insns[largest_index])->count),
1113
             (float)(((float)((or1k_32_insns[largest_index])->count))/
1114
                     ((float)num_seen_insns))*100.f);
1115
 
1116
 
1117
      ((or1k_32_insns[largest_index])->count) = -1; // Eliminate this one
1118
 
1119
    }
1120
}
1121
 
1122
 
1123
// Print out top x of each kept statistic for the requested instruction
1124
void or1k_32_insn_top_x(char* insn_string, FILE * stream, int max_stats)
1125
{
1126
  int i, j, largest, largest_i;
1127
 
1128
  // Confect an instruction properties object to fish out the instruction
1129
  struct or1k_32_instruction_properties temp_insn_props;
1130
  // Struct we'll copy the info into
1131
  struct or1k_insn_info insn_info;
1132
 
1133
  temp_insn_props.insn_string = insn_string;
1134
 
1135
  int insn_index = or1k_32_insn_lists_check(0, &temp_insn_props);
1136
  if (insn_index == IS_UNIQUE)
1137
    {
1138
      fprintf(stream,"Insn: \"%s\" was not seen\n",insn_string);
1139
      return;
1140
    }
1141
  else
1142
    {
1143
      fprintf(stream,"Insn: \"%s\" statistics (%d times (%f%%)):\n", insn_string,
1144
              or1k_32_insns[insn_index]->count,
1145
              (float)(((float)((or1k_32_insns[insn_index])->count))/
1146
                      ((float)num_seen_insns))*100.f
1147
              );
1148
    }
1149
 
1150
  // We have the instruction's index, copy it out (to make code neater!)
1151
  memcpy(&insn_info, or1k_32_insns[insn_index],
1152
         sizeof(struct or1k_insn_info));
1153
 
1154
  // Print out top max_stats branch targets
1155
 
1156
  if (insn_info.has_branchtarg)
1157
    {
1158
      fprintf(stream,"Branch values:\n");
1159
      i = 0;
1160
      while(i<insn_info.branch_info.count && i < max_stats)
1161
        {
1162
          largest_i=0;
1163
          for(j=0;j<insn_info.branch_info.count;j++)
1164
            largest_i = (insn_info.branch_info.values[j][1] >
1165
                         insn_info.branch_info.values[largest_i][1]) ?
1166
              j : largest_i;
1167
 
1168
          // largest_i has index of most frequent value
1169
          fprintf(stream,
1170
                  "value:\t0x%x\tcount:\t%d\n",
1171
                  insn_info.branch_info.values[largest_i][0],
1172
                  insn_info.branch_info.values[largest_i][1]);
1173
          insn_info.branch_info.values[largest_i][1] = -1; // clear this one
1174
          i++;
1175
        }
1176
    }
1177
  if (insn_info.has_imm)
1178
    {
1179
      fprintf(stream,"Immediate values:\n");
1180
      i = 0;
1181
      while(i<insn_info.imm_info.count && i < max_stats)
1182
        {
1183
          largest_i=0;
1184
          for(j=0;j<insn_info.imm_info.count;j++)
1185
            largest_i = (insn_info.imm_info.values[j][1] >
1186
                         insn_info.imm_info.values[largest_i][1]) ?
1187
              j : largest_i;
1188
 
1189
          // largest_i has index of most frequent value
1190
          fprintf(stream,
1191
                  "value:\t0x%x\tcount:\t%d\n",
1192
                  insn_info.imm_info.values[largest_i][0],
1193
                  insn_info.imm_info.values[largest_i][1]);
1194
          insn_info.imm_info.values[largest_i][1] = -1; // clear this one
1195
          i++;
1196
        }
1197
    }
1198
  if (insn_info.has_rD)
1199
    {
1200
      fprintf(stream,"rD usage:\n");
1201
      i = 0;
1202
      while(i<32 && i < max_stats)
1203
        {
1204
          largest_i=0;
1205
          for(j=0;j<32;j++)
1206
            largest_i = (insn_info.rD_use_freq[j] >
1207
                         insn_info.rD_use_freq[largest_i]) ?
1208
              j : largest_i;
1209
 
1210
          // No more interesting numbers
1211
          if (insn_info.rD_use_freq[largest_i] == 0)
1212
            break;
1213
 
1214
          // largest_i has index of most frequent value
1215
          fprintf(stream,
1216
                  "r%d\tcount:\t%d\n",
1217
                  largest_i,
1218
                  insn_info.rD_use_freq[largest_i]);
1219
          insn_info.rD_use_freq[largest_i] = -1; // clear this one
1220
          i++;
1221
        }
1222
    }
1223
 
1224
  if (insn_info.has_rA)
1225
    {
1226
      fprintf(stream,"rA usage:\n");
1227
      i = 0;
1228
      while(i<32 && i < max_stats)
1229
        {
1230
          largest_i=0;
1231
          for(j=0;j<32;j++)
1232
            largest_i = (insn_info.rA_use_freq[j] >
1233
                         insn_info.rA_use_freq[largest_i]) ?
1234
              j : largest_i;
1235
 
1236
          // No more interesting numbers
1237
          if (insn_info.rA_use_freq[largest_i] == 0)
1238
            break;
1239
 
1240
 
1241
          // largest_i has index of most frequent value
1242
          fprintf(stream,
1243
                  "r%d\tcount:\t%d\n",
1244
                  largest_i,
1245
                  insn_info.rA_use_freq[largest_i]);
1246
          insn_info.rA_use_freq[largest_i] = -1; // clear this one
1247
          i++;
1248
        }
1249
    }
1250
 
1251
  if (insn_info.has_rB)
1252
    {
1253
      fprintf(stream,"rB usage:\n");
1254
      i = 0;
1255
      while(i<32 && i < max_stats)
1256
        {
1257
          largest_i=0;
1258
          for(j=0;j<32;j++)
1259
            largest_i = (insn_info.rB_use_freq[j] >
1260
                         insn_info.rB_use_freq[largest_i]) ?
1261
              j : largest_i;
1262
 
1263
          // No more interesting numbers
1264
          if (insn_info.rB_use_freq[largest_i] == 0)
1265
            break;
1266
 
1267
 
1268
          // largest_i has index of most frequent value
1269
          fprintf(stream,
1270
                  "r%d\tcount:\t%d\n",
1271
                  largest_i,
1272
                  insn_info.rB_use_freq[largest_i]);
1273
          insn_info.rB_use_freq[largest_i] = -1; // clear this one
1274
          i++;
1275
        }
1276
    }
1277
}
1278 16 julius
 
1279 17 julius
void or1k_32_generate_stats(FILE * stream)
1280
{
1281
  // Generate some useful things
1282
  fprintf(stream, "Analysis output:\n");
1283
 
1284
  // 
1285
 
1286
  // Print out all stats for every instruction we saw!
1287
  int unique = num_unique_insns;
1288
  while (unique)
1289
    {
1290
      --unique;
1291
      or1k_32_insn_top_x(or1k_32_insns[unique]->insn_string,stream,10);
1292
    }
1293
 
1294
 
1295
  // Do most frequent instruction analysis -- note this trashes instruction
1296
  // frequency count - should be fixed
1297
  or1k_32_most_freq_insn(stream);
1298
 
1299
}

powered by: WebSVN 2.1.0

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