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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [dlx/] [execute.c] - Blame information for rev 480

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

Line No. Rev Author Line
1 19 jeremybenn
/* 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
/* Load and store stalls */
46
int loadcycles, storecycles;
47
 
48
/* Result forwarding stall cycles */
49
int forwardingcycles;
50
 
51
/* 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("\nABORT: 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("\nABORT: 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,int* breakpoint)
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,breakpoint);
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,int* breakpoint)
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, breakpoint);
236
        }
237
 
238
        return;
239
}
240
 
241
void reset()
242
{
243
        cycles = 0;
244
        supercycles = 0;
245
        loadcycles = 0;
246
        storecycles = 0;
247
        forwardingcycles = 0;
248
        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
        /* Simulate instruction cache */
262
        ic_simulate(pc);
263
 
264
        /* Fetch instruction. */
265
        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
        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
  int breakpoint = 0;
288
 
289
        cur->dependdst = cur->op1;
290
        cur->dependsrc1 = cur->op2;     /* for calculating register */
291
        cur->dependsrc2 = cur->op3;     /* dependency */
292
 
293
        cur->func_unit = unknown;
294
 
295
        if (strcmp(cur->insn, "sw") == 0) {
296
                cur->func_unit = store;
297
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint);
298
        } else
299
        if (strcmp(cur->insn, "sb") == 0) {
300
                cur->func_unit = store;
301
                set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 24) + (eval_operand(cur->op1,&breakpoint) & 0xffffff),&breakpoint);
302
        } else
303
        if (strcmp(cur->insn, "sh") == 0) {
304
                cur->func_unit = store;
305
                set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 16) + (eval_operand(cur->op1,&breakpoint) & 0xffff),&breakpoint);
306
        } else
307
        if (strcmp(cur->insn, "lw") == 0) {
308
                cur->func_unit = load;
309
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint);
310
        } else
311
        if (strcmp(cur->insn, "lb") == 0) {
312
                signed char temp = (eval_operand(cur->op2,&breakpoint) >> 24);
313
                cur->func_unit = load;
314
                set_operand(cur->op1, temp,&breakpoint);
315
        } else
316
        if (strcmp(cur->insn, "lbu") == 0) {
317
                unsigned char temp = (eval_operand(cur->op2,&breakpoint) >> 24);
318
                cur->func_unit = load;
319
                set_operand(cur->op1, temp,&breakpoint);
320
        } else
321
        if (strcmp(cur->insn, "lh") == 0) {
322
                signed short temp = (eval_operand(cur->op2,&breakpoint) >> 16);
323
                cur->func_unit = load;
324
                set_operand(cur->op1, temp,&breakpoint);
325
        } else
326
        if (strcmp(cur->insn, "lhu") == 0) {
327
                unsigned short temp = (eval_operand(cur->op2,&breakpoint) >> 16);
328
                cur->func_unit = load;
329
                set_operand(cur->op1, temp,&breakpoint);
330
        } else
331
        if (strcmp(cur->insn, "lwi") == 0) {
332
                cur->func_unit = movimm;
333
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint);
334
        } else
335
        if (strcmp(cur->insn, "lhi") == 0) {
336
                cur->func_unit = movimm;
337
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << 16,&breakpoint);
338
        } else
339
        if (strcmp(cur->insn, "and") == 0) {
340
                cur->func_unit = arith;
341
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint);
342
        } else
343
        if (strcmp(cur->insn, "andi") == 0) {
344
                cur->func_unit = arith;
345
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint);
346
        } else
347
        if (strcmp(cur->insn, "or") == 0) {
348
                cur->func_unit = arith;
349
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint);
350
        } else
351
        if (strcmp(cur->insn, "ori") == 0) {
352
                cur->func_unit = arith;
353
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint);
354
        } else
355
        if (strcmp(cur->insn, "xor") == 0) {
356
                cur->func_unit = arith;
357
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) ^ eval_operand(cur->op3,&breakpoint),&breakpoint);
358
        } else
359
        if (strcmp(cur->insn, "add") == 0) {
360
                signed long temp3, temp2, temp1;
361
                signed char temp4;
362
 
363
                cur->func_unit = arith;
364
                temp3 = eval_operand(cur->op3,&breakpoint);
365
                temp2 = eval_operand(cur->op2,&breakpoint);
366
                temp1 = temp2 + temp3;
367
                set_operand(cur->op1, temp1,&breakpoint);
368
 
369
                temp4 = temp1;
370
                if (temp4 == temp1)
371
                        mstats.byteadd++;
372
        } else
373
        if (strcmp(cur->insn, "addi") == 0) {
374
                signed long temp3, temp2, temp1;
375
                signed char temp4;
376
 
377
                cur->func_unit = arith;
378
                temp3 = eval_operand(cur->op3,&breakpoint);
379
                temp2 = eval_operand(cur->op2,&breakpoint);
380
                temp1 = temp2 + temp3;
381
                set_operand(cur->op1, temp1,&breakpoint);
382
 
383
                temp4 = temp1;
384
                if (temp4 == temp1)
385
                        mstats.byteadd++;
386
        } else
387
        if (strcmp(cur->insn, "addui") == 0) {
388
                unsigned long temp3, temp2, temp1;
389
                unsigned char temp4;
390
 
391
                cur->func_unit = arith;
392
                temp3 = eval_operand(cur->op3,&breakpoint);
393
                temp2 = eval_operand(cur->op2,&breakpoint);
394
                temp1 = temp2 + temp3;
395
                set_operand(cur->op1, temp1,&breakpoint);
396
 
397
                temp4 = temp1;
398
                if (temp4 == temp1)
399
                        mstats.byteadd++;
400
        } else
401
        if (strcmp(cur->insn, "sub") == 0) {
402
                signed long temp3, temp2, temp1;
403
 
404
                cur->func_unit = arith;
405
                temp3 = eval_operand(cur->op3,&breakpoint);
406
                temp2 = eval_operand(cur->op2,&breakpoint);
407
                temp1 = temp2 - temp3;
408
                set_operand(cur->op1, temp1,&breakpoint);
409
        } else
410
        if (strcmp(cur->insn, "subui") == 0) {
411
                unsigned long temp3, temp2, temp1;
412
 
413
                cur->func_unit = arith;
414
                temp3 = eval_operand(cur->op3,&breakpoint);
415
                temp2 = eval_operand(cur->op2,&breakpoint);
416
                temp1 = temp2 - temp3;
417
                set_operand(cur->op1, temp1,&breakpoint);
418
        } else
419
        if (strcmp(cur->insn, "subi") == 0) {
420
                signed long temp3, temp2, temp1;
421
 
422
                cur->func_unit = arith;
423
                temp3 = eval_operand(cur->op3,&breakpoint);
424
                temp2 = eval_operand(cur->op2,&breakpoint);
425
                temp1 = temp2 - temp3;
426
                set_operand(cur->op1, temp1,&breakpoint);
427
        } else
428
        if (strcmp(cur->insn, "mul") == 0) {
429
                signed long temp3, temp2, temp1;
430
 
431
                cur->func_unit = arith;
432
                temp3 = eval_operand(cur->op3,&breakpoint);
433
                temp2 = eval_operand(cur->op2,&breakpoint);
434
                temp1 = temp2 * temp3;
435
                set_operand(cur->op1, temp1,&breakpoint);
436
        } else
437
        if (strcmp(cur->insn, "div") == 0) {
438
                signed long temp3, temp2, temp1;
439
 
440
                cur->func_unit = arith;
441
                temp3 = eval_operand(cur->op3,&breakpoint);
442
                temp2 = eval_operand(cur->op2,&breakpoint);
443
                temp1 = temp2 / temp3;
444
                set_operand(cur->op1, temp1,&breakpoint);
445
        } else
446
        if (strcmp(cur->insn, "divu") == 0) {
447
                unsigned long temp3, temp2, temp1;
448
 
449
                cur->func_unit = arith;
450
                temp3 = eval_operand(cur->op3,&breakpoint);
451
                temp2 = eval_operand(cur->op2,&breakpoint);
452
                temp1 = temp2 / temp3;
453
                set_operand(cur->op1, temp1,&breakpoint);
454
        } else
455
        if (strcmp(cur->insn, "slli") == 0) {
456
                cur->func_unit = shift;
457
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint);
458
        } else
459
        if (strcmp(cur->insn, "sll") == 0) {
460
                cur->func_unit = shift;
461
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint);
462
        } else
463
        if (strcmp(cur->insn, "srl") == 0) {
464
                cur->func_unit = shift;
465
                set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) >> eval_operand(cur->op3,&breakpoint),&breakpoint);
466
        } else
467
        if (strcmp(cur->insn, "srai") == 0) {
468
                cur->func_unit = shift;
469
                set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint);
470
        } else
471
        if (strcmp(cur->insn, "sra") == 0) {
472
                cur->func_unit = shift;
473
                set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint);
474
        } else
475
        if (strcmp(cur->insn, "jal") == 0) {
476
                cur->func_unit = jump;
477
                pctemp = eval_operand(cur->op1,&breakpoint);
478
                set_reg32(LINK_REG, pc + 4);
479
        } else
480
        if (strcmp(cur->insn, "jr") == 0) {
481
                cur->func_unit = jump;
482
                cur->dependsrc1 = cur->op1;
483
                pctemp = eval_operand(cur->op1,&breakpoint);
484
        } else
485
        if (strcmp(cur->insn, "j") == 0) {
486
                cur->func_unit = jump;
487
                pctemp = eval_operand(cur->op1,&breakpoint);
488
        } else
489
        if (strcmp(cur->insn, "nop") == 0) {
490
                cur->func_unit = nop;
491
        } else
492
        if (strcmp(cur->insn, "beqz") == 0) {
493
                cur->func_unit = branch;
494
                cur->dependsrc1 = cur->op1;
495
                if (eval_operand(cur->op1,&breakpoint) == 0) {
496
                        pctemp = eval_operand(cur->op2,&breakpoint);
497
                        mstats.beqz.taken++;
498
                        bpb_update(cur->insn_addr, 1);
499
                        btic_update(pctemp);
500
                } else {
501
                        mstats.beqz.nottaken++;
502
                        bpb_update(cur->insn_addr, 0);
503
                        btic_update(pc);
504
                }
505
        } else
506
        if (strcmp(cur->insn, "bnez") == 0) {
507
                cur->func_unit = branch;
508
                cur->dependsrc1 = cur->op1;
509
                if (eval_operand(cur->op1,&breakpoint) != 0) {
510
                        pctemp = eval_operand(cur->op2,&breakpoint);
511
                        mstats.bnez.taken++;
512
                        bpb_update(cur->insn_addr, 1);
513
                        btic_update(pctemp);
514
                } else {
515
                        mstats.bnez.nottaken++;
516
                        bpb_update(cur->insn_addr, 0);
517
                        btic_update(pc);
518
                }
519
        } else
520
        if (strcmp(cur->insn, "seq") == 0) {
521
                cur->func_unit = compare;
522
                if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint))
523
                        set_operand(cur->op1, 1,&breakpoint);
524
                else
525
                        set_operand(cur->op1, 0,&breakpoint);
526
        } else
527
        if (strcmp(cur->insn, "snei") == 0) {
528
                cur->func_unit = compare;
529
                if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint))
530
                        set_operand(cur->op1, 1,&breakpoint);
531
                else
532
                        set_operand(cur->op1, 0,&breakpoint);
533
        } else
534
        if (strcmp(cur->insn, "sne") == 0) {
535
                cur->func_unit = compare;
536
                if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint))
537
                        set_operand(cur->op1, 1,&breakpoint);
538
                else
539
                        set_operand(cur->op1, 0,&breakpoint);
540
        } else
541
        if (strcmp(cur->insn, "seqi") == 0) {
542
                cur->func_unit = compare;
543
                if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint))
544
                        set_operand(cur->op1, 1,&breakpoint);
545
                else
546
                        set_operand(cur->op1, 0,&breakpoint);
547
        } else
548
        if (strcmp(cur->insn, "sgt") == 0) {
549
                cur->func_unit = compare;
550
                if ((signed)eval_operand(cur->op2,&breakpoint) >
551
                    (signed)eval_operand(cur->op3,&breakpoint))
552
                        set_operand(cur->op1, 1,&breakpoint);
553
                else
554
                        set_operand(cur->op1, 0,&breakpoint);
555
        } else
556
        if (strcmp(cur->insn, "sgtui") == 0) {
557
                cur->func_unit = compare;
558
                if ((unsigned)eval_operand(cur->op2,&breakpoint) >
559
                    (unsigned)eval_operand(cur->op3,&breakpoint))
560
                        set_operand(cur->op1, 1,&breakpoint);
561
                else
562
                        set_operand(cur->op1, 0,&breakpoint);
563
        } else
564
        if (strcmp(cur->insn, "sgeui") == 0) {
565
                cur->func_unit = compare;
566
                if ((unsigned)eval_operand(cur->op2,&breakpoint) >=
567
                    (unsigned)eval_operand(cur->op3,&breakpoint))
568
                        set_operand(cur->op1, 1,&breakpoint);
569
                else
570
                        set_operand(cur->op1, 0,&breakpoint);
571
        } else
572
        if (strcmp(cur->insn, "sgei") == 0) {
573
                cur->func_unit = compare;
574
                if ((signed)eval_operand(cur->op2,&breakpoint) >= (signed)eval_operand(cur->op3,&breakpoint))
575
                        set_operand(cur->op1, 1,&breakpoint);
576
                else
577
                        set_operand(cur->op1, 0,&breakpoint);
578
        } else
579
        if (strcmp(cur->insn, "sgti") == 0) {
580
                cur->func_unit = compare;
581
                if ((signed)eval_operand(cur->op2,&breakpoint) >
582
                    (signed)eval_operand(cur->op3,&breakpoint))
583
                        set_operand(cur->op1, 1,&breakpoint);
584
                else
585
                        set_operand(cur->op1, 0,&breakpoint);
586
        } else
587
        if (strcmp(cur->insn, "slt") == 0) {
588
                cur->func_unit = compare;
589
                if ((signed)eval_operand(cur->op2,&breakpoint) <
590
                    (signed)eval_operand(cur->op3,&breakpoint))
591
                        set_operand(cur->op1, 1,&breakpoint);
592
                else
593
                        set_operand(cur->op1, 0,&breakpoint);
594
        } else
595
        if (strcmp(cur->insn, "slti") == 0) {
596
                cur->func_unit = compare;
597
                if ((signed)eval_operand(cur->op2,&breakpoint) <
598
                    (signed)eval_operand(cur->op3,&breakpoint))
599
                        set_operand(cur->op1, 1,&breakpoint);
600
                else
601
                        set_operand(cur->op1, 0,&breakpoint);
602
        } else
603
        if (strcmp(cur->insn, "sle") == 0) {
604
                cur->func_unit = compare;
605
                if ((signed)eval_operand(cur->op2,&breakpoint) <=
606
                    (signed)eval_operand(cur->op3,&breakpoint))
607
                        set_operand(cur->op1, 1,&breakpoint);
608
                else
609
                        set_operand(cur->op1, 0,&breakpoint);
610
        } else
611
        if (strcmp(cur->insn, "slei") == 0) {
612
                cur->func_unit = compare;
613
                if ((signed)eval_operand(cur->op2,&breakpoint) <=
614
                    (signed)eval_operand(cur->op3,&breakpoint))
615
                        set_operand(cur->op1, 1,&breakpoint);
616
                else
617
                        set_operand(cur->op1, 0,&breakpoint);
618
        } else
619
        if (strcmp(cur->insn, "sleui") == 0) {
620
                cur->func_unit = compare;
621
                if ((unsigned)eval_operand(cur->op2,&breakpoint) <=
622
                    (unsigned)eval_operand(cur->op3,&breakpoint))
623
                        set_operand(cur->op1, 1,&breakpoint);
624
                else
625
                        set_operand(cur->op1, 0,&breakpoint);
626
        } else
627
        if (strcmp(cur->insn, "sleu") == 0) {
628
                cur->func_unit = compare;
629
                if ((unsigned)eval_operand(cur->op2,&breakpoint) <=
630
                    (unsigned)eval_operand(cur->op3,&breakpoint))
631
                        set_operand(cur->op1, 1,&breakpoint);
632
                else
633
                        set_operand(cur->op1, 0,&breakpoint);
634
        } else
635
        if (strcmp(cur->insn, "simrdtsc") == 0) {
636
                set_operand(cur->op1, cycles+loadcycles+storecycles+forwardingcycles,&breakpoint);
637
        } else
638
        if (strcmp(cur->insn, "simprintf") == 0) {
639
                unsigned long stackaddr;
640
 
641
                stackaddr = eval_reg(FRAME_REG);
642
                simprintf(stackaddr, 0);
643
                /* PRINTF("simprintf %x %x %x\n", stackaddr, fmtaddr, args); */
644
        } else {
645
                PRINTF("\nABORT: illegal opcode %s ", cur->insn);
646
                PRINTF("at %.8lx\n", cur->insn_addr);
647
                cont_run = 0;
648
        }
649
 
650
        /* Dynamic, dependency stats. */
651
        adddstats(icomplet[0].insn, iqueue[0].insn, 1, check_depend());
652
 
653
        /* Dynamic, functional units stats. */
654
        addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend());
655
 
656
        /* Dynamic, single stats. */
657
        addsstats(iqueue[0].insn, 1, 0);
658
 
659
        if (cur->func_unit == store)
660
                storecycles += 0;
661
 
662
        if (cur->func_unit == load)
663
                loadcycles += 0;
664
 
665
        if (check_depend())
666
                forwardingcycles += 0;
667
 
668
        /* Pseudo multiple issue benchmark */
669
        if ((multissue[cur->func_unit] == 0) || (check_depend())) {
670
                int i;
671
                for (i = 0; i < 20; i++)
672
                        multissue[i] = 9;
673
                supercycles++;
674
                multissue[arith] = 9;
675
                multissue[store] = 9;
676
                multissue[load] = 9;
677
        }
678
        multissue[cur->func_unit]--;
679
 
680
        return;
681
}
682
 
683
void execute()
684
{
685
        int i;
686
 
687
        /* Here comes real execution someday... */
688
 
689
        /* Instruction waits in completition buffer until retired. */
690
        strcpy(icomplet[0].insn, iqueue[0].insn);
691
        strcpy(icomplet[0].op1, iqueue[0].op1);
692
        strcpy(icomplet[0].op2, iqueue[0].op2);
693
        strcpy(icomplet[0].op3, iqueue[0].op3);
694
        icomplet[0].func_unit = iqueue[0].func_unit;
695
        icomplet[0].insn_addr = iqueue[0].insn_addr;
696
 
697
        if (iqueue[0].dependdst == iqueue[0].op1)
698
                icomplet[0].dependdst = icomplet[0].op1;
699
        else
700
        if (iqueue[0].dependdst == iqueue[0].op2)
701
                icomplet[0].dependdst = icomplet[0].op2;
702
        else
703
        if (iqueue[0].dependdst == iqueue[0].op3)
704
                icomplet[0].dependdst = icomplet[0].op3;
705
        else
706
                icomplet[0].dependdst = NULL;
707
 
708
        if (iqueue[0].dependsrc1 == iqueue[0].op1)
709
                icomplet[0].dependsrc1 = icomplet[0].op1;
710
        else
711
        if (iqueue[0].dependsrc1 == iqueue[0].op2)
712
                icomplet[0].dependsrc1 = icomplet[0].op2;
713
        else
714
        if (iqueue[0].dependsrc1 == iqueue[0].op3)
715
                icomplet[0].dependsrc1 = icomplet[0].op3;
716
        else
717
                icomplet[0].dependsrc1 = NULL;
718
 
719
        if (iqueue[0].dependsrc2 == iqueue[0].op1)
720
                icomplet[0].dependsrc2 = icomplet[0].op1;
721
        else
722
        if (iqueue[0].dependsrc2 == iqueue[0].op2)
723
                icomplet[0].dependsrc2 = icomplet[0].op2;
724
        else
725
        if (iqueue[0].dependsrc2 == iqueue[0].op3)
726
                icomplet[0].dependsrc2 = icomplet[0].op3;
727
        else
728
                icomplet[0].dependsrc2 = NULL;
729
 
730
        /* History of execution */
731
        for (i = HISTEXEC_LEN - 1; i; i--)
732
                histexec[i] = histexec[i - 1];
733
        histexec[0] = icomplet[0].insn_addr;      /* add last insn */
734
 
735
        return;
736
}
737
 
738
void dumpreg()
739
{
740
        int i;
741
 
742
        PRINTF("\n\nIQ[0]:");
743
        dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4);
744
        PRINTF(" (just executed)\tCYCLES: %u \nSuperscalar CYCLES: %u\n", cycles, supercycles);
745
        PRINTF("Additional LOAD CYCLES: %u  STORE CYCLES: %u\n", loadcycles, storecycles);
746
        PRINTF("Additional RESULT FORWARDING CYCLES: %u\nPC:", forwardingcycles);
747
        dumpmemory(pc, pc + 4);
748
        PRINTF(" (next insn)");
749
        for(i = 0; i < MAX_GPRS; i++) {
750
                if (i % 4 == 0)
751
                        PRINTF("\n");
752
                PRINTF("GPR%.2u: %.8lx  ", i, reg[i]);
753
        }
754
}

powered by: WebSVN 2.1.0

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