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 1343

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