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

Subversion Repositories or1k

[/] [or1k/] [tags/] [or1k-1_0/] [or1ksim/] [cpu/] [or32/] [execute.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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