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

Subversion Repositories or1k

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

Go to most recent revision | 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 706 markom
/* Most of the OR1K simulation is done in here.
21 2 cvs
 
22 706 markom
   When SIMPLE_EXECUTION is defined below a file insnset.c is included!
23
*/
24
 
25 2 cvs
#include <stdlib.h>
26
#include <stdio.h>
27
#include <string.h>
28
#include <ctype.h>
29
 
30 123 markom
#include "config.h"
31 2 cvs
#include "arch.h"
32 133 markom
#include "opcode/or32.h"
33 2 cvs
#include "branch_predict.h"
34
#include "abstract.h"
35 261 markom
#include "labels.h"
36 2 cvs
#include "parse.h"
37
#include "execute.h"
38
#include "stats.h"
39 54 lampret
#include "except.h"
40
#include "sprs.h"
41 102 lampret
#include "sim-config.h"
42 123 markom
#include "debug_unit.h"
43 2 cvs
 
44
/* General purpose registers. */
45
machword reg[MAX_GPRS];
46
 
47
/* Instruction queue */
48
struct iqueue_entry iqueue[20];
49
 
50 83 lampret
/* Is current insn in execution a delay insn? */
51
int delay_insn;
52
 
53 2 cvs
/* Benchmark multi issue execution */
54
int multissue[20];
55 6 lampret
int issued_per_cycle = 4;
56 2 cvs
 
57 431 markom
/* Whether break was hit - so we can step over a break */
58
static int break_just_hit = 0;
59
 
60 68 lampret
/* freemem 'pointer' */
61
extern unsigned long freemem;
62
 
63 2 cvs
/* Completition queue */
64 138 markom
struct iqueue_entry icomplet[20];
65 2 cvs
 
66 77 lampret
/* Program counter (and translated PC) */
67 2 cvs
unsigned long pc;
68 77 lampret
unsigned long pc_phy;
69 2 cvs
 
70 378 markom
/* Previous program counter */
71 479 markom
unsigned long pcprev = 0;
72 378 markom
 
73 2 cvs
/* Temporary program counter */
74 83 lampret
unsigned long pcnext;
75 2 cvs
 
76 123 markom
/* Delay instruction effective address register */
77
unsigned long pcdelay;
78
 
79 2 cvs
/* CCR */
80
int flag;
81
 
82
/* CCR (for dependency calculation) */
83
char ccr_flag[10] = "flag";
84
 
85 626 markom
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
86
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
87
static int sbuf_buf[MAX_SBUF_LEN] = {0};
88
static int sbuf_prev_cycles = 0;
89
 
90
/* Num cycles waiting for stores to complete */
91
int sbuf_wait_cyc = 0;
92
 
93
/* Number of total store cycles */
94
int sbuf_total_cyc = 0;
95
 
96 714 markom
/* Whether we are doing statistical analysis */
97
int do_stats = 0;
98
 
99 138 markom
/* Local data needed for execution.  */
100
static int next_delay_insn;
101
static int breakpoint;
102
static unsigned long *op;
103
static int num_op;
104
 
105 2 cvs
/* Implementation specific.
106
   Get an actual value of a specific register. */
107
 
108 560 markom
unsigned long evalsim_reg32(int regno)
109 2 cvs
{
110 138 markom
  if (regno < MAX_GPRS) {
111 560 markom
    return reg[regno];
112
  } else {
113 997 markom
    PRINTF("\nABORT: read out of registers\n");
114 884 markom
    runtime.sim.cont_run = 0;
115 560 markom
    return 0;
116
  }
117
}
118
 
119
/* Implementation specific.
120
   Set a specific register with value. */
121
 
122
void setsim_reg32(int regno, unsigned long value)
123
{
124
  if (regno == 0)               /* gpr0 is always zero */
125
    value = 0;
126
 
127
  if (regno < MAX_GPRS) {
128
    reg[regno] = value;
129
  } else {
130 997 markom
    PRINTF("\nABORT: write out of registers\n");
131 884 markom
    runtime.sim.cont_run = 0;
132 560 markom
  }
133
}
134
 
135
/* Implementation specific.
136
   Get an actual value of a specific register. */
137
 
138
inline static unsigned long eval_reg32(int regno)
139
{
140
  if (regno < MAX_GPRS) {
141 713 markom
#if RAW_RANGE_STATS
142 884 markom
      int delta = (runtime.sim.cycles - raw_stats.reg[regno]);
143 713 markom
      if ((unsigned long)delta < (unsigned long)MAX_RAW_RANGE)
144 535 markom
        raw_stats.range[delta]++;
145 713 markom
#endif /* RAW_RANGE */
146 138 markom
    return reg[regno];
147
  } else {
148 997 markom
    PRINTF("\nABORT: read out of registers\n");
149 884 markom
    runtime.sim.cont_run = 0;
150 138 markom
    return 0;
151
  }
152 2 cvs
}
153
 
154
/* Implementation specific.
155
   Set a specific register with value. */
156
 
157 560 markom
inline static void set_reg32(int regno, unsigned long value)
158 2 cvs
{
159 262 markom
#if 0   
160 138 markom
  if (strcmp(regstr, FRAME_REG) == 0) {
161 997 markom
    PRINTF("FP (%s) modified by insn at %x. ", FRAME_REG, pc);
162
    PRINTF("Old:%.8lx  New:%.8lx\n", eval_reg(regno), value);
163 138 markom
  }
164
 
165
  if (strcmp(regstr, STACK_REG) == 0) {
166 997 markom
    PRINTF("SP (%s) modified by insn at %x. ", STACK_REG, pc);
167
    PRINTF("Old:%.8lx  New:%.8lx\n", eval_reg(regmo), value);
168 138 markom
  }
169 2 cvs
#endif
170 560 markom
 
171 138 markom
  if (regno < MAX_GPRS) {
172
    reg[regno] = value;
173 713 markom
#if RAW_RANGE_STATS
174 884 markom
    raw_stats.reg[regno] = runtime.sim.cycles;
175 713 markom
#endif /* RAW_RANGE */
176 138 markom
  } else {
177 997 markom
    PRINTF("\nABORT: write out of registers\n");
178 884 markom
    runtime.sim.cont_run = 0;
179 138 markom
  }
180 2 cvs
}
181
 
182
/* Does srcoperand depend on computation of dstoperand? Return
183
   non-zero if yes.
184
 
185 262 markom
 Cycle t                 Cycle t+1
186
dst: irrelevant         src: immediate                  always 0
187
dst: reg1 direct        src: reg2 direct                0 if reg1 != reg2
188
dst: reg1 disp          src: reg2 direct                always 0
189
dst: reg1 direct        src: reg2 disp                  0 if reg1 != reg2
190
dst: reg1 disp          src: reg2 disp                  always 1 (store must
191
                                                        finish before load)
192 138 markom
dst: flag               src: flag                       always 1
193 2 cvs
*/
194
 
195 138 markom
int depend_operands(prev, next)
196
     struct iqueue_entry *prev;
197
     struct iqueue_entry *next;
198 2 cvs
{
199 138 markom
  /* Find destination type. */
200
  unsigned long type = 0;
201
  int i = 0;
202
  if (or32_opcodes[prev->insn_index].flags & OR32_W_FLAG
203
      && or32_opcodes[next->insn_index].flags & OR32_R_FLAG)
204
    return 1;
205 2 cvs
 
206 138 markom
  while (!(prev->op[i + MAX_OPERANDS] & OPTYPE_LAST))
207
    if (prev->op[i + MAX_OPERANDS] & OPTYPE_DST)
208
      {
209 262 markom
        type = prev->op[i + MAX_OPERANDS];
210
        break;
211 138 markom
      }
212
    else
213
      i++;
214 560 markom
 
215 138 markom
  /* We search all source operands - if we find confict => return 1 */
216
  i = 0;
217
  while (!(next->op[i + MAX_OPERANDS] & OPTYPE_LAST))
218
    if (!(next->op[i + MAX_OPERANDS] & OPTYPE_DST))
219
      {
220 262 markom
        if (next->op[i + MAX_OPERANDS] & OPTYPE_DIS)
221
          if (type & OPTYPE_DIS)
222
            return 1;
223
          else if (next->op[i] == prev->op[i]
224
                   && (next->op[i + MAX_OPERANDS] & OPTYPE_REG))
225
            return 1;
226
        if (next->op[i] == prev->op[i]
227
            && (next->op[i + MAX_OPERANDS] & OPTYPE_REG)
228
            && (type & OPTYPE_REG))
229
          return 1;
230
        i++;
231 138 markom
      }
232
    else
233
      i++;
234
  return 0;
235
}
236 2 cvs
 
237 717 markom
/* Sets a new SPR_SR_OV value, based on next register value */
238 2 cvs
 
239 615 markom
#if SET_OV_FLAG
240 717 markom
#define set_ov_flag(value) (((value) & 0x80000000 ? setsprbits (SPR_SR, SPR_SR_OV, 1) : setsprbits (SPR_SR, SPR_SR_OV, 0)), value)
241
#else
242
#define set_ov_flag(value) (value)
243 615 markom
#endif
244 605 markom
 
245 123 markom
/* Modified by CZ 26/05/01 for new mode execution */
246
/* Fetch returns nonzero if instruction should NOT be executed.  */
247 557 markom
static inline int fetch()
248
{
249 221 markom
  struct mem_entry *entry;
250 123 markom
 
251 557 markom
  /* Update the pc for pending exceptions, or get physical pc */
252 574 markom
  if (!pending.valid)
253 631 simons
    pc_phy = immu_translate(pc, 0);
254 574 markom
 
255 557 markom
  if(pending.valid)
256
    except_handle_backend(pending.type, pending.address, pending.saved);
257 464 simons
 
258 557 markom
  if (CHECK_BREAKPOINTS) {
259
    /* MM: Check for breakpoint.  This has to be done in fetch cycle,
260
       because of peripheria.
261
       MM1709: if we cannot access the memory entry, we could not set the
262
       breakpoint earlier, so just chech the breakpoint list.  */
263
    if (has_breakpoint (pc_phy) && !break_just_hit) {
264
      break_just_hit = 1;
265
      return 1; /* Breakpoint set. */
266
    }
267
    break_just_hit = 0;
268 431 markom
  }
269 884 markom
  runtime.cpu.instructions++;
270 378 markom
 
271 538 markom
  pc_phy &= ~0x03;
272
 
273 378 markom
  /* Fetch instruction. */
274 560 markom
  iqueue[0].insn_addr = pc;
275 717 markom
  iqueue[0].insn = eval_insn (pc_phy, &breakpoint);
276 557 markom
 
277 378 markom
  /* update_pc will be called after execution */
278 77 lampret
 
279 378 markom
  return 0;
280 2 cvs
}
281
 
282 479 markom
/* This code actually updates the PC value.  */
283 626 markom
static inline void update_pc ()
284 142 chris
{
285 713 markom
  delay_insn = next_delay_insn;
286 479 markom
  pcprev = pc; /* Store value for later */
287
  pc = pcnext;
288
  pcnext = delay_insn ? pcdelay : pcnext + 4;
289 2 cvs
}
290
 
291 717 markom
#if SIMPLE_EXECUTION
292
static inline
293
#endif
294
void analysis (struct iqueue_entry *current)
295 2 cvs
{
296 713 markom
  if (config.cpu.dependstats) {
297
    /* Dynamic, dependency stats. */
298
    adddstats(icomplet[0].insn_index, current->insn_index, 1, check_depend());
299
 
300
    /* Dynamic, functional units stats. */
301
    addfstats(icomplet[0].func_unit, current->func_unit, 1, check_depend());
302
 
303
    /* Dynamic, single stats. */
304
    addsstats(current->insn_index, 1);
305
  }
306
 
307
  if (config.cpu.superscalar) {
308
    if ((current->func_unit == it_branch) || (current->func_unit == it_jump))
309 884 markom
      runtime.sim.storecycles += 0;
310 713 markom
 
311
    if (current->func_unit == it_store)
312 884 markom
      runtime.sim.storecycles += 1;
313 713 markom
 
314
    if (current->func_unit == it_load)
315 884 markom
      runtime.sim.loadcycles += 1;
316 713 markom
#if 0        
317
    if ((icomplet[0].func_unit == it_load) && check_depend())
318 884 markom
      runtime.sim.loadcycles++;
319 713 markom
#endif
320
 
321
    /* Pseudo multiple issue benchmark */
322
    if ((multissue[current->func_unit] < 1) || (check_depend())
323
     || (issued_per_cycle < 1)) {
324
      int i;
325
      for (i = 0; i < 20; i++)
326
        multissue[i] = 2;
327
      issued_per_cycle = 2;
328 884 markom
      runtime.cpu.supercycles++;
329 713 markom
      if (check_depend())
330 884 markom
        runtime.cpu.hazardwait++;
331 713 markom
      multissue[it_unknown] = 2;
332
      multissue[it_shift] = 2;
333
      multissue[it_compare] = 1;
334
      multissue[it_branch] = 1;
335
      multissue[it_jump] = 1;
336
      multissue[it_extend] = 2;
337
      multissue[it_nop] = 2;
338
      multissue[it_move] = 2;
339
      multissue[it_movimm] = 2;
340
      multissue[it_arith] = 2;
341
      multissue[it_store] = 2;
342
      multissue[it_load] = 2;
343
    }
344
    multissue[current->func_unit]--;
345
    issued_per_cycle--;
346
  }
347
 
348 394 markom
  if (config.cpu.dependstats)
349 123 markom
    /* Instruction waits in completition buffer until retired. */
350 713 markom
    memcpy (&icomplet[0], current, sizeof (struct iqueue_entry));
351 138 markom
 
352 394 markom
  if (config.sim.history) {
353 263 markom
    int i;
354
 
355 123 markom
    /* History of execution */
356
    for (i = HISTEXEC_LEN - 1; i; i--)
357
      histexec[i] = histexec[i - 1];
358 262 markom
    histexec[0] = icomplet[0].insn_addr;        /* add last insn */
359 123 markom
  }
360 714 markom
 
361
  if (config.sim.exe_log) dump_exe_log();
362 2 cvs
}
363
 
364 626 markom
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
365 630 markom
static inline sbuf_store (int cyc) {
366 884 markom
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
367 626 markom
  sbuf_total_cyc += cyc;
368 884 markom
  sbuf_prev_cycles = runtime.sim.cycles;
369 626 markom
 
370 997 markom
  //PRINTF (">STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
371
  //PRINTF ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
372 626 markom
  /* Take stores from buffer, that occured meanwhile */
373 630 markom
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
374 626 markom
    delta -= sbuf_buf[sbuf_tail];
375
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
376
    sbuf_count--;
377
  }
378
  if (sbuf_count)
379
    sbuf_buf[sbuf_tail] -= delta;
380 630 markom
 
381 626 markom
  /* Store buffer is full, take one out */
382
  if (sbuf_count >= config.cpu.sbuf_len) {
383
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
384 884 markom
    runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
385 630 markom
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
386 626 markom
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
387
    sbuf_count--;
388
  }
389
  /* Put newest store in the buffer */
390
  sbuf_buf[sbuf_head] = cyc;
391
  sbuf_head = (sbuf_head + 1) % MAX_SBUF_LEN;
392
  sbuf_count++;
393 997 markom
  //PRINTF ("|STORE %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
394 626 markom
}
395 294 markom
 
396 626 markom
/* Store buffer analysis - previous stores should commit, before any load */
397
static inline sbuf_load () {
398 884 markom
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
399
  sbuf_prev_cycles = runtime.sim.cycles;
400 630 markom
 
401 997 markom
  //PRINTF (">LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
402
  //PRINTF ("|%i,%i\n", sbuf_total_cyc, sbuf_wait_cyc);
403 629 markom
  /* Take stores from buffer, that occured meanwhile */
404 630 markom
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail]) {
405 629 markom
    delta -= sbuf_buf[sbuf_tail];
406
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
407
    sbuf_count--;
408
  }
409
  if (sbuf_count)
410
    sbuf_buf[sbuf_tail] -= delta;
411
 
412 626 markom
  /* Wait for all stores to complete */
413
  while (sbuf_count > 0) {
414
    sbuf_wait_cyc += sbuf_buf[sbuf_tail];
415 884 markom
    runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
416 630 markom
    sbuf_prev_cycles += sbuf_buf[sbuf_tail];
417 626 markom
    sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
418
    sbuf_count--;
419
  }
420 997 markom
  //PRINTF ("|LOAD  %i,%i,%i,%i,%i\n", delta, sbuf_count, sbuf_tail, sbuf_head, sbuf_buf[sbuf_tail], sbuf_buf[sbuf_head]);
421 626 markom
}
422
 
423 712 markom
/* Outputs dissasembled instruction */
424 713 markom
void dump_exe_log ()
425 294 markom
{
426 479 markom
  unsigned long i = iqueue[0].insn_addr;
427 294 markom
 
428 479 markom
  if (i == 0xffffffff) return;
429 884 markom
  if (config.sim.exe_log_start <= runtime.cpu.instructions && (config.sim.exe_log_end <= 0 || runtime.cpu.instructions <= config.sim.exe_log_end)) {
430
    if (config.sim.exe_log_marker && runtime.cpu.instructions % config.sim.exe_log_marker == 0) {
431
      fprintf (runtime.sim.fexe_log, "--------------------- %8i instruction ---------------------\n", runtime.cpu.instructions);
432 693 markom
    }
433 672 markom
    switch (config.sim.exe_log_type) {
434
    case EXE_LOG_HARDWARE:
435 913 lampret
      fprintf (runtime.sim.fexe_log, "\nEXECUTED(%11lu): %.8lx:  ", runtime.cpu.instructions, i);
436 672 markom
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i), evalsim_mem8(i + 1));
437
      fprintf (runtime.sim.fexe_log, "%.2x%.2x", evalsim_mem8(i + 2), evalsim_mem8(i + 3));
438
      for(i = 0; i < MAX_GPRS; i++) {
439
        if (i % 4 == 0)
440
          fprintf(runtime.sim.fexe_log, "\n");
441
        fprintf (runtime.sim.fexe_log, "GPR%2u: %.8lx  ", i, reg[i]);
442
      }
443
      fprintf (runtime.sim.fexe_log, "\n");
444
      fprintf (runtime.sim.fexe_log, "SR   : %.8lx  ", mfspr(SPR_SR));
445
      fprintf (runtime.sim.fexe_log, "EPCR0: %.8lx  ", mfspr(SPR_EPCR_BASE));
446
      fprintf (runtime.sim.fexe_log, "EEAR0: %.8lx  ", mfspr(SPR_EEAR_BASE));
447
      fprintf (runtime.sim.fexe_log, "ESR0 : %.8lx\n", mfspr(SPR_ESR_BASE));
448
      break;
449 675 markom
    case EXE_LOG_SIMPLE:
450 672 markom
    case EXE_LOG_SOFTWARE:
451
      {
452 713 markom
        extern char *disassembled;
453
        disassemble_index (iqueue[0].insn, iqueue[0].insn_index);
454 714 markom
        {
455 672 markom
          struct label_entry *entry;
456
          entry = get_label(i);
457 714 markom
          if (entry)
458
            fprintf (runtime.sim.fexe_log, "%s:\n", entry->name);
459 672 markom
        }
460 714 markom
 
461 675 markom
        if (config.sim.exe_log_type == EXE_LOG_SOFTWARE) {
462 678 markom
          int i;
463
          for (i = 0; i < num_op; i++)
464 677 markom
            if (op[i + MAX_OPERANDS] & OPTYPE_DIS) {
465
              fprintf (runtime.sim.fexe_log, "EA =%08x ", op[i]);
466
            } else if ((op[i + MAX_OPERANDS] & OPTYPE_REG) && op[i]) {
467
              fprintf (runtime.sim.fexe_log, "r%-2i=%08x ", op[i], evalsim_reg32 (op[i]));
468
            } else
469 675 markom
            fprintf (runtime.sim.fexe_log, "             ");
470 678 markom
          for (; i < 3; i++)
471
            fprintf (runtime.sim.fexe_log, "             ");
472 675 markom
        }
473 677 markom
        fprintf (runtime.sim.fexe_log, "%.8lx ", i);
474 713 markom
        fprintf (runtime.sim.fexe_log, "%s\n", disassembled);
475 672 markom
      }
476
    }
477
  }
478 294 markom
}
479
 
480 713 markom
/* Dump registers - 'r' or 't' command */
481 2 cvs
void dumpreg()
482
{
483 269 markom
  int i;
484 535 markom
  char temp[100];
485 269 markom
 
486 306 markom
  dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4, 1, 0);
487 897 markom
  generate_time_pretty (temp, runtime.sim.cycles * config.sim.clkcycle_ps);
488 997 markom
  PRINTF(" (executed) [time %s, #%i]\n", temp, runtime.cpu.instructions);
489 293 markom
  if (config.cpu.superscalar)
490 997 markom
    PRINTF ("Superscalar CYCLES: %u", runtime.cpu.supercycles);
491 293 markom
  if (config.cpu.hazards)
492 997 markom
    PRINTF ("  HAZARDWAIT: %u\n", runtime.cpu.hazardwait);
493 293 markom
  else
494
    if (config.cpu.superscalar)
495 997 markom
      PRINTF ("\n");
496 293 markom
 
497 1174 phoenix
  if (peek_into_itlb(pc))
498
    dumpmemory(pc, pc + 4, 1, 0);
499
  else
500 1177 phoenix
    PRINTF("%08x: : xxxxxxxx  ITLB miss follows", pc);
501 1174 phoenix
 
502 997 markom
  PRINTF(" (next insn) %s", (delay_insn?"(delay insn)":""));
503 269 markom
  for(i = 0; i < MAX_GPRS; i++) {
504
    if (i % 4 == 0)
505 997 markom
      PRINTF("\n");
506
    PRINTF("GPR%.2u: %.8lx  ", i, evalsim_reg32(i));
507 269 markom
  }
508 997 markom
  PRINTF("flag: %u\n", flag);
509 2 cvs
}
510 123 markom
 
511 713 markom
/* Generated/built in decoding/executing function */
512 712 markom
static inline void decode_execute (struct iqueue_entry *current);
513 706 markom
 
514
/* Wrapper around real decode_execute function -- some statistics here only */
515
static inline void decode_execute_wrapper (struct iqueue_entry *current)
516 123 markom
{
517 712 markom
  breakpoint = 0;
518 123 markom
  next_delay_insn = 0;
519 138 markom
 
520 123 markom
#ifndef HAS_EXECUTION
521
#error HAS_EXECUTION has to be defined in order to execute programs.
522
#endif
523 706 markom
 
524
  if(config.debug.enabled && CheckDebugUnit(DebugInstructionFetch, pc_phy))
525 717 markom
    breakpoint = 1;
526 706 markom
 
527 712 markom
  decode_execute (current);
528 706 markom
 
529 717 markom
#if SET_OV_FLAG
530 458 simons
  /* Check for range exception */
531 557 markom
  if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV))
532 611 simons
    except_handle (EXCEPT_RANGE, mfspr(SPR_EEAR_BASE));
533 717 markom
#endif
534 458 simons
 
535 123 markom
  if(breakpoint)
536 611 simons
    except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE));
537 123 markom
}
538
 
539 706 markom
/* Reset the CPU */
540 557 markom
void cpu_reset()
541
{
542 606 markom
  int i;
543 884 markom
  runtime.sim.cycles = 0;
544
  runtime.sim.loadcycles = 0;
545
  runtime.sim.storecycles = 0;
546
  runtime.cpu.instructions = 0;
547
  runtime.cpu.supercycles = 0;
548
  runtime.cpu.hazardwait = 0;
549 606 markom
  for (i = 0; i < MAX_GPRS; i++)
550
    set_reg32 (i, 0);
551 557 markom
  memset(iqueue, 0, sizeof(iqueue));
552
  memset(icomplet, 0, sizeof(icomplet));
553 626 markom
 
554
  sbuf_head = 0;
555
  sbuf_tail = 0;
556
  sbuf_count = 0;
557
  sbuf_prev_cycles = 0;
558 557 markom
 
559
  /* Cpu configuration */
560
  mtspr(SPR_UPR, config.cpu.upr);
561
  setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
562
  setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
563
  mtspr(SPR_SR, config.cpu.sr);
564
 
565
  pcnext = 0x0; /* MM1409: All programs should start at reset vector entry!  */
566 997 markom
  if (config.sim.verbose) PRINTF ("Starting at 0x%08x\n", pcnext);
567 557 markom
  pc = pcnext;
568
  pc_phy = pc;
569
  pcnext += 4;
570
  debug(1, "reset ...\n");
571
 
572
  /* MM1409: All programs should set their stack pointer!  */
573
  except_handle(EXCEPT_RESET, 0);
574
}
575
 
576 713 markom
/* Simulates one CPU clock cycle */
577 557 markom
inline int cpu_clock ()
578
{
579
  if(fetch()) {
580 997 markom
    PRINTF ("Breakpoint hit.\n");
581 884 markom
    runtime.sim.cont_run = 0; /* memory breakpoint encountered */
582 557 markom
    return 1;
583
  }
584 706 markom
  decode_execute_wrapper (&iqueue[0]);
585 557 markom
  update_pc();
586
  return 0;
587
}
588
 
589 713 markom
/* If decoding cannot be found, call this function */
590 706 markom
void l_invalid () {
591 713 markom
  /* It would be hard to handle this case for statistics; we skip it
592
     since it should not occur anyway:
593
  IFF (config.cpu.dependstats) current->func_unit = it_unknown; */
594 706 markom
  except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr);
595 123 markom
}
596 641 ivang
 
597 717 markom
#if !SIMPLE_EXECUTION
598
 
599
/* Include decode_execute function */
600
#include "execgen.c"
601
 
602
#else /* SIMPLE_EXECUTION */
603
 
604 720 markom
 
605 706 markom
#define INSTRUCTION(name) void name ()
606 720 markom
#define get_operand (op_no) op[(op_no)]
607 641 ivang
 
608 717 markom
/* Implementation specific.
609
   Parses and returns operands. */
610 641 ivang
 
611 717 markom
static void
612
eval_operands (unsigned long insn, int insn_index, int* breakpoint)
613
{
614
  struct insn_op_struct *opd = op_start[insn_index];
615
  unsigned long data = 0;
616
  int dis = 0;
617
  int no = 0;
618
 
619
  while (1)
620
    {
621
      unsigned long tmp = 0, nbits = 0;
622
      while (1)
623
        {
624
          tmp |= ((insn  >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << nbits;
625
          nbits += opd->data;
626
          if (opd->type & OPTYPE_OP)
627
            break;
628
          opd++;
629
        }
630
 
631
      /* Do we have to sign extend? */
632
      if (opd->type & OPTYPE_SIG)
633
        {
634
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
635
          if (tmp & (1 << sbit))
636
            tmp |= 0xFFFFFFFF << sbit;
637
        }
638
      if (opd->type & OPTYPE_DIS) {
639
        /* We have to read register later.  */
640
        data += tmp;
641
        dis = 1;
642
      } else
643
        {
644
          if (dis && (opd->type & OPTYPE_REG))
645
            op[no] = data + eval_reg32 (tmp);
646
          else
647
            op[no] = tmp;
648
          op[no + MAX_OPERANDS] = opd->type | (dis ? OPTYPE_DIS : 0);
649
          no++;
650
          data = 0;
651
          dis = 0;
652
        }
653
      if(opd->type & OPTYPE_LAST) {
654
        num_op = no;
655
        return;
656
      }
657
      opd++;
658
    }
659
  num_op = no;
660
}
661
 
662
/* Implementation specific.
663
   Evaluates source operand op_no. */
664
 
665
inline static unsigned long eval_operand32 (int op_no, int *breakpoint)
666
{
667
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
668
    /* memory accesses are not cached */
669
    return eval_mem32 (op[op_no], breakpoint);
670
  else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) {
671
    return eval_reg32 (op[op_no]);
672
  } else {
673
    return op[op_no];
674
  }
675
}
676
 
677
/* Implementation specific.
678
   Evaluates source operand op_no. */
679
 
680
static unsigned long eval_operand16 (int op_no, int *breakpoint)
681
{
682
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
683
    return eval_mem16 (op[op_no], breakpoint);
684
  }
685
  else {
686
    fprintf (stderr, "Invalid operand type.\n");
687
    exit (1);
688
  }
689
}
690
 
691
/* Implementation specific.
692
   Evaluates source operand op_no. */
693
 
694
static unsigned long eval_operand8 (int op_no, int *breakpoint)
695
{
696
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
697
    return eval_mem8 (op[op_no], breakpoint);
698
  else {
699
    fprintf (stderr, "Invalid operand type.\n");
700
    exit (1);
701
  }
702
}
703
 
704
/* Implementation specific.
705
   Set destination operand (register direct, register indirect
706
   (with displacement) with value. */
707
 
708
inline static void set_operand32(int op_no, unsigned long value, int* breakpoint)
709
{
710
  /* Mark this as destination operand.  */
711
  IFF (config.cpu.dependstats) op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
712
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
713
    set_mem32(op[op_no], value, breakpoint);
714
  } else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) {
715
    set_reg32(op[op_no], value);
716
  } else {
717
    fprintf (stderr, "Invalid operand type.\n");
718
    exit (1);
719
  }
720
}
721
 
722
/* Implementation specific.
723
   Set destination operand (register direct, register indirect
724
   (with displacement) with value. */
725
 
726
void set_operand16(int op_no, unsigned long value, int* breakpoint)
727
{
728
  /* Mark this as destination operand.  */
729
  op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
730
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) {
731
    set_mem16(op[op_no], value, breakpoint);
732
  }
733
  else
734
    {
735
      fprintf (stderr, "Invalid operand type.\n");
736
      exit (1);
737
    }
738
}
739
 
740
/* Implementation specific.
741
   Set destination operand (register direct, register indirect
742
   (with displacement) with value. */
743
 
744
void set_operand8(int op_no, unsigned long value, int* breakpoint)
745
{
746
  /* Mark this as destination operand.  */
747
  op[op_no + MAX_OPERANDS] |= OPTYPE_DST;
748
  if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS)
749
    set_mem8(op[op_no], value, breakpoint);
750
  else
751
    {
752
      fprintf (stderr, "Invalid operand type.\n");
753
      exit (1);
754
    }
755
}
756
 
757 713 markom
/* Simple and rather slow decoding function based on built automata. */
758 712 markom
static inline void decode_execute (struct iqueue_entry *current)
759 706 markom
{
760
  int insn_index;
761
 
762
  current->insn_index = insn_index = insn_decode(current->insn);
763 641 ivang
 
764 706 markom
  if (insn_index < 0)
765
    l_invalid();
766 123 markom
  else {
767 713 markom
    op = &current->op[0];
768
    eval_operands (current->insn, insn_index, &breakpoint);
769 706 markom
    or32_opcodes[insn_index].exec();
770 123 markom
  }
771 717 markom
  if (do_stats) analysis(&iqueue[0]);
772 123 markom
}
773
 
774 720 markom
#include "insnset.c"
775
 
776 717 markom
#endif /* !SIMPLE_EXECUTION */

powered by: WebSVN 2.1.0

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