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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [dlx/] [execute.c] - Blame information for rev 30

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

Line No. Rev Author Line
1 2 cvs
/* execute.c -- DLX dependent simulation
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* Most of the DLX simulation is done in this file. */
21
 
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <string.h>
25
 
26
#include "arch.h"
27
 
28
#include "branch_predict.h"
29
#include "abstract.h"
30
#include "parse.h"
31
#include "trace.h"
32
#include "execute.h"
33
#include "stats.h"
34
 
35
/* General purpose registers. */
36
machword reg[MAX_GPRS];
37
 
38
/* Instruction queue */
39
struct iqueue_entry iqueue[20];
40
 
41
/* Benchmark multi issue execution */
42
int multissue[20];
43
int supercycles;
44
 
45 6 lampret
/* Load and store stalls */
46
int loadcycles, storecycles;
47
 
48
/* Result forwarding stall cycles */
49
int forwardingcycles;
50
 
51 2 cvs
/* Completition queue */
52
struct icomplet_entry icomplet[20];
53
 
54
/* Program counter */
55
unsigned long pc;
56
 
57
/* Temporary program counter */
58
unsigned long pctemp;
59
 
60
/* Cycles counts fetch stages */
61
int cycles;
62
 
63
/* Implementation specific.
64
   Get an actual value of a specific register. */
65
 
66
machword eval_reg(char *regstr)
67
{
68
        int regno;
69
 
70
        regno = atoi(regstr + 1);
71
 
72
        if (regno < MAX_GPRS)
73
                return reg[regno];
74
        else {
75
                printf("\nEXCEPTION: read out of registers\n");
76
                cont_run = 0;
77
                return 0;
78
        }
79
}
80
 
81
/* Implementation specific.
82
   Set a specific register with value. */
83
 
84
void set_reg32(char *regstr, unsigned long value)
85
{
86
        int regno;
87
 
88
        regno = atoi(regstr + 1);
89
 
90
        if (regno == 0)          /* gpr0 is always zero */
91
                value = 0;
92
 
93
        if (regno < MAX_GPRS)
94
                reg[regno] = value;
95
        else {
96
                printf("\nEXCEPTION: write out of registers\n");
97
                cont_run = 0;
98
        }
99
 
100
        return;
101
}
102
 
103
/* Does srcoperand depend on computation of dstoperand? Return
104
   non-zero if yes.
105
 
106
 Cycle t                 Cycle t+1
107
dst: irrelevant         src: immediate                  always 0
108
dst: reg1 direct        src: reg2 direct                0 if reg1 != reg2
109
dst: reg1 disp          src: reg2 direct                always 0
110
dst: reg1 direct        src: reg2 disp                  0 if reg1 != reg2
111
dst: reg1 disp          src: reg2 disp                  always 1 (store must
112
                                                        finish before load)
113
*/
114
 
115
int depend_operands(char *dstoperand, char *srcoperand)
116
{
117
        char dst[OPERANDNAME_LEN];
118
        char src[OPERANDNAME_LEN];
119
 
120
        if (!srcoperand)
121
                return 0;
122
 
123
        if (!dstoperand)
124
                return 0;
125
 
126
        strcpy(dst, dstoperand);
127
        strcpy(src, srcoperand);
128
 
129
        if (*src == '#')                /* immediate */
130
                return 0;
131
        else
132
        if (!strstr(src, "("))
133
                if (*src == 'r') {      /* src: reg direct */
134
                        if (!strstr(dst, "("))
135
                                if (*dst == 'r')
136
                                        if (strcmp(dst, src) == 0)
137
                                                return 1; /* dst: reg direct */
138
                                        else
139
                                                return 0; /* dst: reg direct */
140
                                else
141
                                        return 0; /* dst: addr */
142
                        else
143
                                return 0; /* dst: reg disp */
144
                } else
145
                        return 0;        /* src: addr */
146
        else {                          /* src: register disp */
147
                char *regstr;
148
 
149
                regstr = strstr(src, "(r") + 1; /* regstr == "rXX)" */
150
                *strstr(regstr, ")") = '\0';            /* regstr == "rXX" */
151
 
152
                if (!strstr(dst, "("))
153
                        if (*dst == 'r')
154
                                if (strcmp(dst, regstr) == 0)
155
                                        return 1; /* dst: reg direct */
156
                                else
157
                                        return 0; /* dst: reg direct */
158
                        else
159
                                return 0; /* dst: addr */
160
                else
161
                        return 1; /* dst: reg disp */
162
        }
163
 
164
        return 0;
165
}
166
 
167
/* Implementation specific.
168
   Get an actual value represented by operand (register direct, register
169
   indirect (with displacement), immediate etc.).
170
 
171
   #n           - immediate n
172
   rXX          - register direct
173
   XX           - relative or absolute address (labels)
174
   n(XX)        - register indirect (with displacement) */
175
 
176
machword eval_operand(char *srcoperand)
177
{
178
        char operand[OPERANDNAME_LEN];
179
 
180
        strcpy(operand, srcoperand);
181
 
182
        if (*operand == '#')            /* immediate */
183
                return strtoul(&operand[1], NULL, 0);
184
        else
185
        if (!strstr(operand, "("))      /* not indirect but ...*/
186
                if (*operand == 'r')    /* ... register direct */
187
                        return eval_reg(operand);
188
 
189
                else                    /* ... rel. or abs. address */
190
                        return eval_label(operand);
191
        else {                          /* register indirect */
192
                int disp;               /* with possible displacement */
193
                char *regstr;
194
                unsigned int memaddr;
195
 
196
                disp = atoi(operand);   /* operand == "nn(rXX)" */
197
                regstr = strstr(operand, "(r") + 1;     /* regstr == "rXX)" */
198
                *strstr(regstr, ")") = '\0';            /* regstr == "rXX" */
199
                memaddr = eval_reg(regstr) + disp;
200
 
201
                return eval_mem32(memaddr);
202
        }
203
 
204
        return 0;
205
}
206
 
207
/* Implementation specific.
208
   Set destination operand (register direct, register indirect
209
   (with displacement) with value. */
210
 
211
void set_operand(char *dstoperand, unsigned long value)
212
{
213
        char operand[OPERANDNAME_LEN];
214
 
215
        strcpy(operand, dstoperand);
216
 
217
        if (*operand == '#')            /* immediate */
218
                printf("INTERNAL ERROR: Can't set immediate operand.\n");
219
        else
220
        if (!strstr(operand, "("))      /* not indirect but ...*/
221
                if (*operand == 'r')    /* ... register direct */
222
                        set_reg32(operand, value);
223
                else                    /* ... rel. or abs. address */
224
                        printf("INTERNAL ERROR: Can't set addr operand.\n");
225
        else {                          /* register indirect */
226
                int disp;               /* with possible displacement */
227
                char *regstr;
228
                unsigned int memaddr;
229
 
230
                disp = atoi(operand);   /* operand == "nn(rXX)" */
231
                regstr = strstr(operand, "(r") + 1;     /* regstr == "rXX)" */
232
                *strstr(regstr, ")") = '\0';            /* regstr == "rXX" */
233
                memaddr = eval_reg(regstr) + disp;
234
 
235
                set_mem32(memaddr, value);
236
        }
237
 
238
        return;
239
}
240
 
241
void reset()
242
{
243
        cycles = 0;
244
        supercycles = 0;
245 6 lampret
        loadcycles = 0;
246
        storecycles = 0;
247
        forwardingcycles = 0;
248 2 cvs
        memset(reg, 0, sizeof(reg));
249
        memset(iqueue, 0, sizeof(iqueue));
250
        memset(icomplet, 0, sizeof(icomplet));
251
        pctemp = eval_label("_main");
252
        pc = pctemp;
253
        set_reg32(STACK_REG , MEMORY_LEN - STACK_SIZE);
254
}
255
 
256
void fetch()
257
{
258
        /* Cycles after reset. */
259
        cycles++;
260
 
261 6 lampret
        /* Simulate instruction cache */
262
        ic_simulate(pc);
263
 
264 2 cvs
        /* Fetch instruction. */
265 30 lampret
        strcpy(iqueue[0].insn, mem[pc].insn->insn);
266
        strcpy(iqueue[0].op1, mem[pc].insn->op1);
267
        strcpy(iqueue[0].op2, mem[pc].insn->op2);
268
        strcpy(iqueue[0].op3, mem[pc].insn->op3);
269 2 cvs
        iqueue[0].insn_addr = pc;
270
        iqueue[0].dependdst = NULL;
271
        iqueue[0].dependsrc1 = NULL;
272
        iqueue[0].dependsrc2 = NULL;
273
 
274
        /* Increment program counter. */
275
        pc = pctemp;
276
        pctemp += 4;
277
 
278
        /* Check for breakpoint. */
279
        if (mem[pc].brk)
280
                cont_run = 0;    /* Breakpoint set. */
281
 
282
        return;
283
}
284
 
285
void decode(struct iqueue_entry *cur)
286
{
287
 
288
        cur->dependdst = cur->op1;
289
        cur->dependsrc1 = cur->op2;     /* for calculating register */
290
        cur->dependsrc2 = cur->op3;     /* dependency */
291
 
292
        cur->func_unit = unknown;
293
 
294
        if (strcmp(cur->insn, "sw") == 0) {
295
                cur->func_unit = store;
296
                set_operand(cur->op1, eval_operand(cur->op2));
297
        } else
298
        if (strcmp(cur->insn, "sb") == 0) {
299
                cur->func_unit = store;
300
                set_operand(cur->op1, (eval_operand(cur->op2) << 24) + (eval_operand(cur->op1) & 0xffffff));
301
        } else
302
        if (strcmp(cur->insn, "sh") == 0) {
303
                cur->func_unit = store;
304
                set_operand(cur->op1, (eval_operand(cur->op2) << 16) + (eval_operand(cur->op1) & 0xffff));
305
        } else
306
        if (strcmp(cur->insn, "lw") == 0) {
307
                cur->func_unit = load;
308
                set_operand(cur->op1, eval_operand(cur->op2));
309
        } else
310
        if (strcmp(cur->insn, "lb") == 0) {
311
                signed char temp = (eval_operand(cur->op2) >> 24);
312
                cur->func_unit = load;
313
                set_operand(cur->op1, temp);
314
        } else
315
        if (strcmp(cur->insn, "lbu") == 0) {
316
                unsigned char temp = (eval_operand(cur->op2) >> 24);
317
                cur->func_unit = load;
318
                set_operand(cur->op1, temp);
319
        } else
320
        if (strcmp(cur->insn, "lh") == 0) {
321
                signed short temp = (eval_operand(cur->op2) >> 16);
322
                cur->func_unit = load;
323
                set_operand(cur->op1, temp);
324
        } else
325
        if (strcmp(cur->insn, "lhu") == 0) {
326
                unsigned short temp = (eval_operand(cur->op2) >> 16);
327
                cur->func_unit = load;
328
                set_operand(cur->op1, temp);
329
        } else
330
        if (strcmp(cur->insn, "lwi") == 0) {
331
                cur->func_unit = movimm;
332
                set_operand(cur->op1, eval_operand(cur->op2));
333
        } else
334
        if (strcmp(cur->insn, "lhi") == 0) {
335
                cur->func_unit = movimm;
336
                set_operand(cur->op1, eval_operand(cur->op2) << 16);
337
        } else
338
        if (strcmp(cur->insn, "and") == 0) {
339
                cur->func_unit = arith;
340
                set_operand(cur->op1, eval_operand(cur->op2) & eval_operand(cur->op3));
341
        } else
342
        if (strcmp(cur->insn, "andi") == 0) {
343
                cur->func_unit = arith;
344
                set_operand(cur->op1, eval_operand(cur->op2) & eval_operand(cur->op3));
345
        } else
346
        if (strcmp(cur->insn, "or") == 0) {
347
                cur->func_unit = arith;
348
                set_operand(cur->op1, eval_operand(cur->op2) | eval_operand(cur->op3));
349
        } else
350
        if (strcmp(cur->insn, "ori") == 0) {
351
                cur->func_unit = arith;
352
                set_operand(cur->op1, eval_operand(cur->op2) | eval_operand(cur->op3));
353
        } else
354
        if (strcmp(cur->insn, "xor") == 0) {
355
                cur->func_unit = arith;
356
                set_operand(cur->op1, eval_operand(cur->op2) ^ eval_operand(cur->op3));
357
        } else
358
        if (strcmp(cur->insn, "add") == 0) {
359
                signed long temp3, temp2, temp1;
360
                signed char temp4;
361
 
362
                cur->func_unit = arith;
363
                temp3 = eval_operand(cur->op3);
364
                temp2 = eval_operand(cur->op2);
365
                temp1 = temp2 + temp3;
366
                set_operand(cur->op1, temp1);
367
 
368
                temp4 = temp1;
369
                if (temp4 == temp1)
370
                        mstats.byteadd++;
371
        } else
372
        if (strcmp(cur->insn, "addi") == 0) {
373
                signed long temp3, temp2, temp1;
374
                signed char temp4;
375
 
376
                cur->func_unit = arith;
377
                temp3 = eval_operand(cur->op3);
378
                temp2 = eval_operand(cur->op2);
379
                temp1 = temp2 + temp3;
380
                set_operand(cur->op1, temp1);
381
 
382
                temp4 = temp1;
383
                if (temp4 == temp1)
384
                        mstats.byteadd++;
385
        } else
386
        if (strcmp(cur->insn, "addui") == 0) {
387
                unsigned long temp3, temp2, temp1;
388
                unsigned char temp4;
389
 
390
                cur->func_unit = arith;
391
                temp3 = eval_operand(cur->op3);
392
                temp2 = eval_operand(cur->op2);
393
                temp1 = temp2 + temp3;
394
                set_operand(cur->op1, temp1);
395
 
396
                temp4 = temp1;
397
                if (temp4 == temp1)
398
                        mstats.byteadd++;
399
        } else
400
        if (strcmp(cur->insn, "sub") == 0) {
401
                signed long temp3, temp2, temp1;
402
 
403
                cur->func_unit = arith;
404
                temp3 = eval_operand(cur->op3);
405
                temp2 = eval_operand(cur->op2);
406
                temp1 = temp2 - temp3;
407
                set_operand(cur->op1, temp1);
408
        } else
409
        if (strcmp(cur->insn, "subui") == 0) {
410
                unsigned long temp3, temp2, temp1;
411
 
412
                cur->func_unit = arith;
413
                temp3 = eval_operand(cur->op3);
414
                temp2 = eval_operand(cur->op2);
415
                temp1 = temp2 - temp3;
416
                set_operand(cur->op1, temp1);
417
        } else
418
        if (strcmp(cur->insn, "subi") == 0) {
419
                signed long temp3, temp2, temp1;
420
 
421
                cur->func_unit = arith;
422
                temp3 = eval_operand(cur->op3);
423
                temp2 = eval_operand(cur->op2);
424
                temp1 = temp2 - temp3;
425
                set_operand(cur->op1, temp1);
426
        } else
427
        if (strcmp(cur->insn, "mul") == 0) {
428
                signed long temp3, temp2, temp1;
429
 
430
                cur->func_unit = arith;
431
                temp3 = eval_operand(cur->op3);
432
                temp2 = eval_operand(cur->op2);
433
                temp1 = temp2 * temp3;
434
                set_operand(cur->op1, temp1);
435
        } else
436
        if (strcmp(cur->insn, "div") == 0) {
437
                signed long temp3, temp2, temp1;
438
 
439
                cur->func_unit = arith;
440
                temp3 = eval_operand(cur->op3);
441
                temp2 = eval_operand(cur->op2);
442
                temp1 = temp2 / temp3;
443
                set_operand(cur->op1, temp1);
444
        } else
445
        if (strcmp(cur->insn, "divu") == 0) {
446
                unsigned long temp3, temp2, temp1;
447
 
448
                cur->func_unit = arith;
449
                temp3 = eval_operand(cur->op3);
450
                temp2 = eval_operand(cur->op2);
451
                temp1 = temp2 / temp3;
452
                set_operand(cur->op1, temp1);
453
        } else
454
        if (strcmp(cur->insn, "slli") == 0) {
455
                cur->func_unit = shift;
456
                set_operand(cur->op1, eval_operand(cur->op2) << eval_operand(cur->op3));
457
        } else
458
        if (strcmp(cur->insn, "sll") == 0) {
459
                cur->func_unit = shift;
460
                set_operand(cur->op1, eval_operand(cur->op2) << eval_operand(cur->op3));
461
        } else
462
        if (strcmp(cur->insn, "srl") == 0) {
463
                cur->func_unit = shift;
464
                set_operand(cur->op1, eval_operand(cur->op2) >> eval_operand(cur->op3));
465
        } else
466
        if (strcmp(cur->insn, "srai") == 0) {
467
                cur->func_unit = shift;
468
                set_operand(cur->op1, (signed)eval_operand(cur->op2) / (1 << eval_operand(cur->op3)));
469
        } else
470
        if (strcmp(cur->insn, "sra") == 0) {
471
                cur->func_unit = shift;
472
                set_operand(cur->op1, (signed)eval_operand(cur->op2) / (1 << eval_operand(cur->op3)));
473
        } else
474
        if (strcmp(cur->insn, "jal") == 0) {
475
                cur->func_unit = jump;
476
                pctemp = eval_operand(cur->op1);
477
                set_reg32(LINK_REG, pc + 4);
478
        } else
479
        if (strcmp(cur->insn, "jr") == 0) {
480
                cur->func_unit = jump;
481
                cur->dependsrc1 = cur->op1;
482
                pctemp = eval_operand(cur->op1);
483
        } else
484
        if (strcmp(cur->insn, "j") == 0) {
485
                cur->func_unit = jump;
486
                pctemp = eval_operand(cur->op1);
487
        } else
488
        if (strcmp(cur->insn, "nop") == 0) {
489
                cur->func_unit = nop;
490
        } else
491
        if (strcmp(cur->insn, "beqz") == 0) {
492
                cur->func_unit = branch;
493
                cur->dependsrc1 = cur->op1;
494
                if (eval_operand(cur->op1) == 0) {
495
                        pctemp = eval_operand(cur->op2);
496
                        mstats.beqz.taken++;
497
                        bpb_update(cur->insn_addr, 1);
498
                        btic_update(pctemp);
499
                } else {
500
                        mstats.beqz.nottaken++;
501
                        bpb_update(cur->insn_addr, 0);
502
                        btic_update(pc);
503
                }
504
        } else
505
        if (strcmp(cur->insn, "bnez") == 0) {
506
                cur->func_unit = branch;
507
                cur->dependsrc1 = cur->op1;
508
                if (eval_operand(cur->op1) != 0) {
509
                        pctemp = eval_operand(cur->op2);
510
                        mstats.bnez.taken++;
511
                        bpb_update(cur->insn_addr, 1);
512
                        btic_update(pctemp);
513
                } else {
514
                        mstats.bnez.nottaken++;
515
                        bpb_update(cur->insn_addr, 0);
516
                        btic_update(pc);
517
                }
518
        } else
519
        if (strcmp(cur->insn, "seq") == 0) {
520
                cur->func_unit = compare;
521
                if (eval_operand(cur->op2) == eval_operand(cur->op3))
522
                        set_operand(cur->op1, 1);
523
                else
524
                        set_operand(cur->op1, 0);
525
        } else
526
        if (strcmp(cur->insn, "snei") == 0) {
527
                cur->func_unit = compare;
528
                if (eval_operand(cur->op2) != eval_operand(cur->op3))
529
                        set_operand(cur->op1, 1);
530
                else
531
                        set_operand(cur->op1, 0);
532
        } else
533
        if (strcmp(cur->insn, "sne") == 0) {
534
                cur->func_unit = compare;
535
                if (eval_operand(cur->op2) != eval_operand(cur->op3))
536
                        set_operand(cur->op1, 1);
537
                else
538
                        set_operand(cur->op1, 0);
539
        } else
540
        if (strcmp(cur->insn, "seqi") == 0) {
541
                cur->func_unit = compare;
542
                if (eval_operand(cur->op2) == eval_operand(cur->op3))
543
                        set_operand(cur->op1, 1);
544
                else
545
                        set_operand(cur->op1, 0);
546
        } else
547
        if (strcmp(cur->insn, "sgt") == 0) {
548
                cur->func_unit = compare;
549
                if ((signed)eval_operand(cur->op2) >
550
                    (signed)eval_operand(cur->op3))
551
                        set_operand(cur->op1, 1);
552
                else
553
                        set_operand(cur->op1, 0);
554
        } else
555
        if (strcmp(cur->insn, "sgtui") == 0) {
556
                cur->func_unit = compare;
557
                if ((unsigned)eval_operand(cur->op2) >
558
                    (unsigned)eval_operand(cur->op3))
559
                        set_operand(cur->op1, 1);
560
                else
561
                        set_operand(cur->op1, 0);
562
        } else
563
        if (strcmp(cur->insn, "sgeui") == 0) {
564
                cur->func_unit = compare;
565
                if ((unsigned)eval_operand(cur->op2) >=
566
                    (unsigned)eval_operand(cur->op3))
567
                        set_operand(cur->op1, 1);
568
                else
569
                        set_operand(cur->op1, 0);
570
        } else
571
        if (strcmp(cur->insn, "sgei") == 0) {
572
                cur->func_unit = compare;
573
                if ((signed)eval_operand(cur->op2) >= (signed)eval_operand(cur->op3))
574
                        set_operand(cur->op1, 1);
575
                else
576
                        set_operand(cur->op1, 0);
577
        } else
578
        if (strcmp(cur->insn, "sgti") == 0) {
579
                cur->func_unit = compare;
580
                if ((signed)eval_operand(cur->op2) >
581
                    (signed)eval_operand(cur->op3))
582
                        set_operand(cur->op1, 1);
583
                else
584
                        set_operand(cur->op1, 0);
585
        } else
586
        if (strcmp(cur->insn, "slt") == 0) {
587
                cur->func_unit = compare;
588
                if ((signed)eval_operand(cur->op2) <
589
                    (signed)eval_operand(cur->op3))
590
                        set_operand(cur->op1, 1);
591
                else
592
                        set_operand(cur->op1, 0);
593
        } else
594
        if (strcmp(cur->insn, "slti") == 0) {
595
                cur->func_unit = compare;
596
                if ((signed)eval_operand(cur->op2) <
597
                    (signed)eval_operand(cur->op3))
598
                        set_operand(cur->op1, 1);
599
                else
600
                        set_operand(cur->op1, 0);
601
        } else
602
        if (strcmp(cur->insn, "sle") == 0) {
603
                cur->func_unit = compare;
604
                if ((signed)eval_operand(cur->op2) <=
605
                    (signed)eval_operand(cur->op3))
606
                        set_operand(cur->op1, 1);
607
                else
608
                        set_operand(cur->op1, 0);
609
        } else
610
        if (strcmp(cur->insn, "slei") == 0) {
611
                cur->func_unit = compare;
612
                if ((signed)eval_operand(cur->op2) <=
613
                    (signed)eval_operand(cur->op3))
614
                        set_operand(cur->op1, 1);
615
                else
616
                        set_operand(cur->op1, 0);
617
        } else
618
        if (strcmp(cur->insn, "sleui") == 0) {
619
                cur->func_unit = compare;
620
                if ((unsigned)eval_operand(cur->op2) <=
621
                    (unsigned)eval_operand(cur->op3))
622
                        set_operand(cur->op1, 1);
623
                else
624
                        set_operand(cur->op1, 0);
625
        } else
626
        if (strcmp(cur->insn, "sleu") == 0) {
627
                cur->func_unit = compare;
628
                if ((unsigned)eval_operand(cur->op2) <=
629
                    (unsigned)eval_operand(cur->op3))
630
                        set_operand(cur->op1, 1);
631
                else
632
                        set_operand(cur->op1, 0);
633
        } else
634
        if (strcmp(cur->insn, "simrdtsc") == 0) {
635 6 lampret
                set_operand(cur->op1, cycles+loadcycles+storecycles+forwardingcycles);
636 2 cvs
        } else
637
        if (strcmp(cur->insn, "simprintf") == 0) {
638
                unsigned long stackaddr;
639
 
640
                stackaddr = eval_reg(FRAME_REG);
641
                simprintf(stackaddr, 0);
642
                /* printf("simprintf %x %x %x\n", stackaddr, fmtaddr, args); */
643
        } else {
644
                printf("\nEXCEPTION: illegal opcode %s ", cur->insn);
645
                printf("at %.8lx\n", cur->insn_addr);
646
                cont_run = 0;
647
        }
648
 
649
        /* Dynamic, dependency stats. */
650
        adddstats(icomplet[0].insn, iqueue[0].insn, 1, check_depend());
651
 
652
        /* Dynamic, functional units stats. */
653
        addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend());
654
 
655
        /* Dynamic, single stats. */
656
        addsstats(iqueue[0].insn, 1, 0);
657
 
658 6 lampret
        if (cur->func_unit == store)
659
                storecycles += 0;
660
 
661
        if (cur->func_unit == load)
662
                loadcycles += 0;
663
 
664
        if (check_depend())
665
                forwardingcycles += 0;
666
 
667 2 cvs
        /* Pseudo multiple issue benchmark */
668
        if ((multissue[cur->func_unit] == 0) || (check_depend())) {
669
                int i;
670
                for (i = 0; i < 20; i++)
671 6 lampret
                        multissue[i] = 9;
672 2 cvs
                supercycles++;
673 6 lampret
                multissue[arith] = 9;
674
                multissue[store] = 9;
675
                multissue[load] = 9;
676 2 cvs
        }
677
        multissue[cur->func_unit]--;
678
 
679
        return;
680
}
681
 
682
void execute()
683
{
684
        int i;
685
 
686
        /* Here comes real execution someday... */
687
 
688
        /* Instruction waits in completition buffer until retired. */
689
        strcpy(icomplet[0].insn, iqueue[0].insn);
690
        strcpy(icomplet[0].op1, iqueue[0].op1);
691
        strcpy(icomplet[0].op2, iqueue[0].op2);
692
        strcpy(icomplet[0].op3, iqueue[0].op3);
693
        icomplet[0].func_unit = iqueue[0].func_unit;
694
        icomplet[0].insn_addr = iqueue[0].insn_addr;
695
 
696
        if (iqueue[0].dependdst == iqueue[0].op1)
697
                icomplet[0].dependdst = icomplet[0].op1;
698
        else
699
        if (iqueue[0].dependdst == iqueue[0].op2)
700
                icomplet[0].dependdst = icomplet[0].op2;
701
        else
702
        if (iqueue[0].dependdst == iqueue[0].op3)
703
                icomplet[0].dependdst = icomplet[0].op3;
704
        else
705
                icomplet[0].dependdst = NULL;
706
 
707
        if (iqueue[0].dependsrc1 == iqueue[0].op1)
708
                icomplet[0].dependsrc1 = icomplet[0].op1;
709
        else
710
        if (iqueue[0].dependsrc1 == iqueue[0].op2)
711
                icomplet[0].dependsrc1 = icomplet[0].op2;
712
        else
713
        if (iqueue[0].dependsrc1 == iqueue[0].op3)
714
                icomplet[0].dependsrc1 = icomplet[0].op3;
715
        else
716
                icomplet[0].dependsrc1 = NULL;
717
 
718
        if (iqueue[0].dependsrc2 == iqueue[0].op1)
719
                icomplet[0].dependsrc2 = icomplet[0].op1;
720
        else
721
        if (iqueue[0].dependsrc2 == iqueue[0].op2)
722
                icomplet[0].dependsrc2 = icomplet[0].op2;
723
        else
724
        if (iqueue[0].dependsrc2 == iqueue[0].op3)
725
                icomplet[0].dependsrc2 = icomplet[0].op3;
726
        else
727
                icomplet[0].dependsrc2 = NULL;
728
 
729
        /* History of execution */
730
        for (i = HISTEXEC_LEN - 1; i; i--)
731
                histexec[i] = histexec[i - 1];
732
        histexec[0] = icomplet[0].insn_addr;      /* add last insn */
733
 
734
        return;
735
}
736
 
737
void dumpreg()
738
{
739
        int i;
740
 
741
        printf("\n\nIQ[0]:");
742
        dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4);
743 6 lampret
        printf(" (just executed)\tCYCLES: %u \nSuperscalar CYCLES: %u\n", cycles, supercycles);
744
        printf("Additional LOAD CYCLES: %u  STORE CYCLES: %u\n", loadcycles, storecycles);
745
        printf("Additional RESULT FORWARDING CYCLES: %u\nPC:", forwardingcycles);
746 2 cvs
        dumpmemory(pc, pc + 4);
747
        printf(" (next insn)");
748
        for(i = 0; i < MAX_GPRS; i++) {
749
                if (i % 4 == 0)
750
                        printf("\n");
751
                printf("GPR%.2u: %.8lx  ", i, reg[i]);
752
        }
753
}

powered by: WebSVN 2.1.0

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