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 19

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

powered by: WebSVN 2.1.0

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