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 1344

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