"I am a person who works hard and plays hard."

Yuan Wei
Second Year Graduate Student Department of Computer Science
University of Virginia Charlottesville, VA 22903
Email: yw3f@cs.virginia.edu


Source Code Analysis

Main Page   Compound List   File List   Compound Members   File Members  

sim-eio.c

Go to the documentation of this file.
00001 /*
00002  * sim-eio.c - external I/O trace generator
00003  *
00004  * This file is a part of the SimpleScalar tool suite written by
00005  * Todd M. Austin as a part of the Multiscalar Research Project.
00006  *  
00007  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00008  * 
00009  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00010  *
00011  * This source file is distributed "as is" in the hope that it will be
00012  * useful.  The tool set comes with no warranty, and no author or
00013  * distributor accepts any responsibility for the consequences of its
00014  * use. 
00015  * 
00016  * Everyone is granted permission to copy, modify and redistribute
00017  * this tool set under the following conditions:
00018  * 
00019  *    This source code is distributed for non-commercial use only. 
00020  *    Please contact the maintainer for restrictions applying to 
00021  *    commercial use.
00022  *
00023  *    Permission is granted to anyone to make or distribute copies
00024  *    of this source code, either as received or modified, in any
00025  *    medium, provided that all copyright notices, permission and
00026  *    nonwarranty notices are preserved, and that the distributor
00027  *    grants the recipient permission for further redistribution as
00028  *    permitted by this document.
00029  *
00030  *    Permission is granted to distribute this file in compiled
00031  *    or executable form under the same conditions that apply for
00032  *    source code, provided that either:
00033  *
00034  *    A. it is accompanied by the corresponding machine-readable
00035  *       source code,
00036  *    B. it is accompanied by a written offer, with no time limit,
00037  *       to give anyone a machine-readable copy of the corresponding
00038  *       source code in return for reimbursement of the cost of
00039  *       distribution.  This written offer must permit verbatim
00040  *       duplication by anyone, or
00041  *    C. it is distributed by someone who received only the
00042  *       executable form, and is accompanied by a copy of the
00043  *       written offer of source code that they received concurrently.
00044  *
00045  * In other words, you are welcome to use, share and improve this
00046  * source file.  You are forbidden to forbid anyone else to use, share
00047  * and improve what you give them.
00048  *
00049  * INTERNET: dburger@cs.wisc.edu
00050  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00051  *
00052  * $Id: sim-eio.c,v 1.1.1.1 2000/05/26 15:19:03 taustin Exp $
00053  *
00054  * $Log: sim-eio.c,v $
00055  * Revision 1.1.1.1  2000/05/26 15:19:03  taustin
00056  * SimpleScalar Tool Set
00057  *
00058  *
00059  * Revision 1.3  1999/12/31 18:47:39  taustin
00060  * quad_t naming conflicts removed
00061  * periodic checkpointing (-perdump) support added to sim-eio
00062  *
00063  * Revision 1.2  1999/12/13 18:46:11  taustin
00064  * cross endian execution support added
00065  *
00066  * Revision 1.1  1998/08/27 16:24:56  taustin
00067  * Initial revision
00068  *
00069  *
00070  */
00071 
00072 #include <stdio.h>
00073 #include <stdlib.h>
00074 #include <math.h>
00075 
00076 #include "host.h"
00077 #include "misc.h"
00078 #include "machine.h"
00079 #include "regs.h"
00080 #include "memory.h"
00081 #include "loader.h"
00082 #include "syscall.h"
00083 #include "dlite.h"
00084 #include "options.h"
00085 #include "stats.h"
00086 #include "eio.h"
00087 #include "range.h"
00088 #include "sim.h"
00089 
00090 /*
00091  * This file implements a functional simulator.  This functional simulator is
00092  * the simplest, most user-friendly simulator in the simplescalar tool set.
00093  * Unlike sim-fast, this functional simulator checks for all instruction
00094  * errors, and the implementation is crafted for clarity rather than speed.
00095  */
00096 
00097 /* simulated registers */
00098 static struct regs_t regs;
00099 
00100 /* simulated memory */
00101 static struct mem_t *mem = NULL;
00102 
00103 /* track number of refs */
00104 static counter_t sim_num_refs = 0;
00105 
00106 /* maximum number of inst's to execute */
00107 static unsigned int max_insts;
00108 
00109 /* number of insts skipped before timing starts */
00110 static int fastfwd_count;
00111 
00112 /* non-zero when fastforward'ing */
00113 static int fastfwding = FALSE;
00114 
00115 /* external I/O filename */
00116 static char *trace_fname;
00117 static FILE *trace_fd = NULL;
00118 
00119 /* checkpoint filename and file descriptor */
00120 static enum { no_chkpt, one_shot_chkpt, periodic_chkpt } chkpt_kind = no_chkpt;
00121 static char *chkpt_fname;
00122 static FILE *chkpt_fd = NULL;
00123 static struct range_range_t chkpt_range;
00124 
00125 /* periodic checkpoint args */
00126 static counter_t per_chkpt_interval;
00127 static counter_t next_chkpt_cycle;
00128 static unsigned int chkpt_num;
00129 
00130 /* checkpoint output filename and range */
00131 static int chkpt_nelt = 0;
00132 static char *chkpt_opts[2];
00133 
00134 /* periodic checkpoint output filename and range */
00135 static int per_chkpt_nelt = 0;
00136 static char *per_chkpt_opts[2];
00137 
00138 
00139 /* register simulator-specific options */
00140 void
00141 sim_reg_options(struct opt_odb_t *odb)
00142 {
00143   opt_reg_header(odb, 
00144 "sim-eio: This simulator implements simulator support for generating\n"
00145 "external event traces (EIO traces) and checkpoint files.  External\n"
00146 "event traces capture one execution of a program, and allow it to be\n"
00147 "packaged into a single file for later re-execution.  EIO trace executions\n"
00148 "are 100% reproducible between subsequent executions (on the same platform.\n"
00149 "This simulator also provides functionality to generate checkpoints at\n"
00150 "arbitrary points within an external event trace (EIO) execution.  The\n"
00151 "checkpoint file (along with the EIO trace) can be used to start any\n"
00152 "SimpleScalar simulator in the middle of a program execution.\n"
00153                  );
00154 
00155   /* instruction limit */
00156   opt_reg_uint(odb, "-max:inst", "maximum number of inst's to execute",
00157                &max_insts, /* default */0,
00158                /* print */TRUE, /* format */NULL);
00159 
00160   opt_reg_int(odb, "-fastfwd", "number of insts skipped before tracing starts",
00161               &fastfwd_count, /* default */0,
00162               /* print */TRUE, /* format */NULL);
00163 
00164   opt_reg_string(odb, "-trace", "EIO trace file output file name",
00165                  &trace_fname, /* default */NULL,
00166                  /* print */TRUE, NULL);
00167 
00168   opt_reg_string_list(odb, "-perdump",
00169                       "periodic checkpoint every n instructions: "
00170                       "<base fname> <interval>",
00171                       per_chkpt_opts, /* sz */2, &per_chkpt_nelt,
00172                       /* default */NULL,
00173                       /* !print */FALSE, /* format */NULL, /* !accrue */FALSE);
00174 
00175   opt_reg_string_list(odb, "-dump",
00176                       "specify checkpoint file and trigger: <fname> <range>",
00177                       chkpt_opts, /* sz */2, &chkpt_nelt, /* default */NULL,
00178                       /* !print */FALSE, /* format */NULL, /* !accrue */FALSE);
00179 
00180   opt_reg_note(odb,
00181 "  Checkpoint range triggers are formatted as follows:\n"
00182 "\n"
00183 "    {{@|#}<start>}:{{@|#|+}<end>}\n"
00184 "\n"
00185 "  Both ends of the range are optional, if neither are specified, the range\n"
00186 "  triggers immediately.  Ranges that start with a `@' designate an address\n"
00187 "  range to trigger on, those that start with an `#' designate a cycle count\n"
00188 "  trigger.  All other ranges represent an instruction count range.  The\n"
00189 "  second argument, if specified with a `+', indicates a value relative\n"
00190 "  to the first argument, e.g., 1000:+100 == 1000:1100.\n"
00191 "\n"
00192 "    Examples:   -ptrace FOO.trc #0:#1000\n"
00193 "                -ptrace BAR.trc @2000:\n"
00194 "                -ptrace BLAH.trc :1500\n"
00195 "                -ptrace UXXE.trc :\n"
00196                );
00197 }
00198 
00199 /* check simulator-specific option values */
00200 void
00201 sim_check_options(struct opt_odb_t *odb, int argc, char **argv)
00202 {
00203   if (fastfwd_count < 0 || fastfwd_count >= 2147483647)
00204     fatal("bad fast forward count: %d", fastfwd_count);
00205 }
00206 
00207 /* register simulator-specific statistics */
00208 void
00209 sim_reg_stats(struct stat_sdb_t *sdb)
00210 {
00211   stat_reg_counter(sdb, "sim_num_insn",
00212                    "total number of instructions executed",
00213                    &sim_num_insn, sim_num_insn, NULL);
00214   stat_reg_counter(sdb, "sim_num_refs",
00215                    "total number of loads and stores executed",
00216                    &sim_num_refs, 0, NULL);
00217   stat_reg_int(sdb, "sim_elapsed_time",
00218                "total simulation time in seconds",
00219                &sim_elapsed_time, 0, NULL);
00220   stat_reg_formula(sdb, "sim_inst_rate",
00221                    "simulation speed (in insts/sec)",
00222                    "sim_num_insn / sim_elapsed_time", NULL);
00223   ld_reg_stats(sdb);
00224   mem_reg_stats(mem, sdb);
00225 }
00226 
00227 /* initialize the simulator */
00228 void
00229 sim_init(void)
00230 {
00231   sim_num_refs = 0;
00232 
00233   /* allocate and initialize register file */
00234   regs_init(&regs);
00235 
00236   /* allocate and initialize memory space */
00237   mem = mem_create("mem");
00238   mem_init(mem);
00239 }
00240 
00241 /* load program into simulated state */
00242 void
00243 sim_load_prog(char *fname,              /* program to load */
00244               int argc, char **argv,    /* program arguments */
00245               char **envp)              /* program environment */
00246 {
00247   /* load program text and data, set up environment, memory, and regs */
00248   ld_load_prog(fname, argc, argv, envp, &regs, mem, TRUE);
00249 
00250   if (chkpt_nelt == 2)
00251     {
00252       char *errstr;
00253 
00254       /* generate a checkpoint */
00255       if (!sim_eio_fd)
00256         fatal("checkpoints can only be generated while running an EIO trace");
00257 
00258       /* can't do regular & periodic chkpts at the same time */
00259       if (per_chkpt_nelt != 0)
00260         fatal("can't do both regular and periodic checkpoints");
00261 
00262 #if 0 /* this should work fine... */
00263       if (trace_fname != NULL)
00264         fatal("checkpoints cannot be generated with generating an EIO trace");
00265 #endif
00266 
00267       /* parse the range */
00268       errstr = range_parse_range(chkpt_opts[1], &chkpt_range);
00269       if (errstr)
00270         fatal("cannot parse pipetrace range, use: {<start>}:{<end>}");
00271 
00272       /* create the checkpoint file */
00273       chkpt_fname = chkpt_opts[0];
00274       chkpt_fd = eio_create(chkpt_fname);
00275 
00276       /* indicate checkpointing is now active... */
00277       chkpt_kind = one_shot_chkpt;
00278     }
00279 
00280   if (per_chkpt_nelt == 2)
00281     {
00282       chkpt_fname = per_chkpt_opts[0];
00283       if (strchr(chkpt_fname, '%') == NULL)
00284         fatal("periodic checkpoint filename must be printf-style format");
00285 
00286       if (sscanf(per_chkpt_opts[1], "%Ld", &per_chkpt_interval) != 1)
00287         fatal("can't parse periodic checkpoint interval '%s'",
00288               per_chkpt_opts[1]);
00289 
00290       /* indicate checkpointing is now active... */
00291       chkpt_kind = periodic_chkpt;
00292       chkpt_num = 1;
00293       next_chkpt_cycle = per_chkpt_interval;
00294     }
00295 
00296   if (trace_fname != NULL)
00297     {
00298       fprintf(stderr, "sim: tracing execution to EIO file `%s'...\n",
00299               trace_fname);
00300 
00301       /* create an EIO trace file */
00302       trace_fd = eio_create(trace_fname);
00303     }
00304 
00305   /* initialize the DLite debugger */
00306   dlite_init(md_reg_obj, dlite_mem_obj, dlite_mstate_obj);
00307 }
00308 
00309 
00310 /* print simulator-specific configuration information */
00311 void
00312 sim_aux_config(FILE *stream)            /* output stream */
00313 {
00314   /* nothing currently */
00315 }
00316 
00317 /* dump simulator-specific auxiliary simulator statistics */
00318 void
00319 sim_aux_stats(FILE *stream)             /* output stream */
00320 {
00321   /* nada */
00322 }
00323 
00324 /* un-initialize simulator-specific state */
00325 void
00326 sim_uninit(void)
00327 {
00328   if (trace_fd != NULL)
00329     eio_close(trace_fd);
00330 }
00331 
00332 
00333 /*
00334  * configure the execution engine
00335  */
00336 
00337 /*
00338  * precise architected register accessors
00339  */
00340 
00341 /* next program counter */
00342 #define SET_NPC(EXPR)           (regs.regs_NPC = (EXPR))
00343 
00344 /* current program counter */
00345 #define CPC                     (regs.regs_PC)
00346 
00347 /* general purpose registers */
00348 #define GPR(N)                  (regs.regs_R[N])
00349 #define SET_GPR(N,EXPR)         (regs.regs_R[N] = (EXPR))
00350 
00351 #if defined(TARGET_PISA)
00352 
00353 /* floating point registers, L->word, F->single-prec, D->double-prec */
00354 #define FPR_L(N)                (regs.regs_F.l[(N)])
00355 #define SET_FPR_L(N,EXPR)       (regs.regs_F.l[(N)] = (EXPR))
00356 #define FPR_F(N)                (regs.regs_F.f[(N)])
00357 #define SET_FPR_F(N,EXPR)       (regs.regs_F.f[(N)] = (EXPR))
00358 #define FPR_D(N)                (regs.regs_F.d[(N) >> 1])
00359 #define SET_FPR_D(N,EXPR)       (regs.regs_F.d[(N) >> 1] = (EXPR))
00360 
00361 /* miscellaneous register accessors */
00362 #define SET_HI(EXPR)            (regs.regs_C.hi = (EXPR))
00363 #define HI                      (regs.regs_C.hi)
00364 #define SET_LO(EXPR)            (regs.regs_C.lo = (EXPR))
00365 #define LO                      (regs.regs_C.lo)
00366 #define FCC                     (regs.regs_C.fcc)
00367 #define SET_FCC(EXPR)           (regs.regs_C.fcc = (EXPR))
00368 
00369 #elif defined(TARGET_ALPHA)
00370 
00371 /* floating point registers, L->word, F->single-prec, D->double-prec */
00372 #define FPR_Q(N)                (regs.regs_F.q[N])
00373 #define SET_FPR_Q(N,EXPR)       (regs.regs_F.q[N] = (EXPR))
00374 #define FPR(N)                  (regs.regs_F.d[N])
00375 #define SET_FPR(N,EXPR)         (regs.regs_F.d[N] = (EXPR))
00376 
00377 /* miscellaneous register accessors */
00378 #define FPCR                    (regs.regs_C.fpcr)
00379 #define SET_FPCR(EXPR)          (regs.regs_C.fpcr = (EXPR))
00380 #define UNIQ                    (regs.regs_C.uniq)
00381 #define SET_UNIQ(EXPR)          (regs.regs_C.uniq = (EXPR))
00382 
00383 #else
00384 #error No ISA target defined...
00385 #endif
00386 
00387 /* precise architected memory state accessor macros */
00388 #define READ_BYTE(SRC, FAULT)                                           \
00389   ((FAULT) = md_fault_none, MEM_READ_BYTE(mem, addr = (SRC)))
00390 #define READ_HALF(SRC, FAULT)                                           \
00391   ((FAULT) = md_fault_none, MEM_READ_HALF(mem, addr = (SRC)))
00392 #define READ_WORD(SRC, FAULT)                                           \
00393   ((FAULT) = md_fault_none, MEM_READ_WORD(mem, addr = (SRC)))
00394 #ifdef HOST_HAS_QWORD
00395 #define READ_QWORD(SRC, FAULT)                                          \
00396   ((FAULT) = md_fault_none, MEM_READ_QWORD(mem, addr = (SRC)))
00397 #endif /* HOST_HAS_QWORD */
00398 
00399 #define WRITE_BYTE(SRC, DST, FAULT)                                     \
00400   ((FAULT) = md_fault_none, MEM_WRITE_BYTE(mem, addr = (DST), (SRC)))
00401 #define WRITE_HALF(SRC, DST, FAULT)                                     \
00402   ((FAULT) = md_fault_none, MEM_WRITE_HALF(mem, addr = (DST), (SRC)))
00403 #define WRITE_WORD(SRC, DST, FAULT)                                     \
00404   ((FAULT) = md_fault_none, MEM_WRITE_WORD(mem, addr = (DST), (SRC)))
00405 #ifdef HOST_HAS_QWORD
00406 #define WRITE_QWORD(SRC, DST, FAULT)                                    \
00407   ((FAULT) = md_fault_none, MEM_WRITE_QWORD(mem, addr = (DST), (SRC)))
00408 #endif /* HOST_HAS_QWORD */
00409 
00410 /* system call handler macro */
00411 #define SYSCALL(INST)                                                   \
00412   ((trace_fd != NULL && !fastfwding)                                    \
00413    ? eio_write_trace(trace_fd, sim_num_insn,                            \
00414                      &regs, mem_access, mem, INST)                      \
00415    : sys_syscall(&regs, mem_access, mem, INST, TRUE))
00416 
00417 /* start simulation, program loaded, processor precise state initialized */
00418 void
00419 sim_main(void)
00420 {
00421   md_inst_t inst;
00422   register md_addr_t addr;
00423   enum md_opcode op;
00424   register bool_t is_write;
00425   enum md_fault_type fault;
00426 
00427   /* set up initial default next PC */
00428   regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);
00429 
00430   /* check for DLite debugger entry condition */
00431   if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
00432     dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
00433                sim_num_insn, &regs, mem);
00434 
00435   /* fast forward simulator loop, performs functional simulation for
00436      FASTFWD_COUNT insts, then turns on performance (timing) simulation */
00437   if (fastfwd_count > 0)
00438     {
00439       int icount;
00440 
00441       fprintf(stderr, "sim: ** fast forwarding %d insts **\n", fastfwd_count);
00442 
00443       fastfwding = TRUE;
00444       for (icount=0; icount < fastfwd_count; icount++)
00445         {
00446           /* maintain $r0 semantics */
00447           regs.regs_R[MD_REG_ZERO] = 0;
00448 #ifdef TARGET_ALPHA
00449           regs.regs_F.d[MD_REG_ZERO] = 0.0;
00450 #endif /* TARGET_ALPHA */
00451 
00452           /* get the next instruction to execute */
00453           MD_FETCH_INST(inst, mem, regs.regs_PC);
00454 
00455           /* set default reference address */
00456           addr = 0; is_write = FALSE;
00457 
00458           /* set default fault - none */
00459           fault = md_fault_none;
00460 
00461           /* decode the instruction */
00462           MD_SET_OPCODE(op, inst);
00463 
00464           /* execute the instruction */
00465           switch (op)
00466             {
00467 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)            \
00468             case OP:                                                    \
00469               SYMCAT(OP,_IMPL);                                         \
00470               break;
00471 #define DEFLINK(OP,MSK,NAME,MASK,SHIFT)                                 \
00472             case OP:                                                    \
00473               panic("attempted to execute a linking opcode");
00474 #define CONNECT(OP)
00475 #undef DECLARE_FAULT
00476 #define DECLARE_FAULT(FAULT)                                            \
00477               { fault = (FAULT); break; }
00478 #include "machine.def"
00479             default:
00480               panic("attempted to execute a bogus opcode");
00481             }
00482 
00483           if (fault != md_fault_none)
00484             fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);
00485 
00486           /* update memory access stats */
00487           if (MD_OP_FLAGS(op) & F_MEM)
00488             {
00489               if (MD_OP_FLAGS(op) & F_STORE)
00490                 is_write = TRUE;
00491             }
00492 
00493           /* check for DLite debugger entry condition */
00494           if (dlite_check_break(regs.regs_NPC,
00495                                 is_write ? ACCESS_WRITE : ACCESS_READ,
00496                                 addr, sim_num_insn, sim_num_insn))
00497             dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);
00498 
00499           /* go to the next instruction */
00500           regs.regs_PC = regs.regs_NPC;
00501           regs.regs_NPC += sizeof(md_inst_t);
00502         }
00503     }
00504   fastfwding = FALSE;
00505 
00506   if (trace_fd != NULL)
00507     {
00508       fprintf(stderr, "sim: writing EIO file initial checkpoint...\n");
00509       if (eio_write_chkpt(&regs, mem, trace_fd) != -1)
00510         panic("checkpoint code is broken");
00511     }
00512 
00513   fprintf(stderr, "sim: ** starting functional simulation **\n");
00514 
00515   /* set up initial default next PC */
00516   regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);
00517 
00518   while (TRUE)
00519     {
00520       /* maintain $r0 semantics */
00521       regs.regs_R[MD_REG_ZERO] = 0;
00522 #ifdef TARGET_ALPHA
00523       regs.regs_F.d[MD_REG_ZERO] = 0.0;
00524 #endif /* TARGET_ALPHA */
00525 
00526       /* check if checkpoint should be generated here... */
00527       if (chkpt_kind == one_shot_chkpt
00528           && !range_cmp_range1(&chkpt_range, regs.regs_NPC,
00529                                sim_num_insn, sim_num_insn))
00530         {
00531           myfprintf(stderr, "sim: writing checkpoint file `%s' @ inst %n...\n",
00532                   chkpt_fname, sim_num_insn);
00533 
00534           /* write the checkpoint file */
00535           eio_write_chkpt(&regs, mem, chkpt_fd);
00536 
00537           /* close the checkpoint file */
00538           eio_close(chkpt_fd);
00539 
00540           /* exit jumps to the target set in main() */
00541           longjmp(sim_exit_buf, /* exitcode + fudge */0+1);
00542         }
00543       else if (chkpt_kind == periodic_chkpt
00544                && sim_num_insn == next_chkpt_cycle)
00545         {
00546           char this_chkpt_fname[256];
00547 
00548           /* 'chkpt_fname' should be a printf format string */
00549           sprintf(this_chkpt_fname, chkpt_fname, chkpt_num);
00550           chkpt_fd = eio_create(this_chkpt_fname);
00551 
00552           myfprintf(stderr, "sim: writing checkpoint file `%s' @ inst %n...\n",
00553                   this_chkpt_fname, sim_num_insn);
00554 
00555           /* write the checkpoint file */
00556           eio_write_chkpt(&regs, mem, chkpt_fd);
00557 
00558           /* close the checkpoint file */
00559           eio_close(chkpt_fd);
00560 
00561           chkpt_num++;
00562           next_chkpt_cycle += per_chkpt_interval;
00563         }
00564 
00565       /* get the next instruction to execute */
00566       MD_FETCH_INST(inst, mem, regs.regs_PC);
00567 
00568       /* keep an instruction count */
00569       sim_num_insn++;
00570 
00571       /* set default reference address and access mode */
00572       addr = 0; is_write = FALSE;
00573 
00574       /* set default fault - none */
00575       fault = md_fault_none;
00576 
00577       /* decode the instruction */
00578       MD_SET_OPCODE(op, inst);
00579 
00580       /* execute the instruction */
00581       switch (op)
00582         {
00583 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)            \
00584         case OP:                                                        \
00585           SYMCAT(OP,_IMPL);                                             \
00586           break;
00587 #define DEFLINK(OP,MSK,NAME,MASK,SHIFT)                                 \
00588         case OP:                                                        \
00589           panic("attempted to execute a linking opcode");
00590 #define CONNECT(OP)
00591 #define DECLARE_FAULT(FAULT)                                            \
00592           { fault = (FAULT); break; }
00593 #include "machine.def"
00594         default:
00595           panic("bogus opcode");
00596       }
00597 
00598       if (fault != md_fault_none)
00599         fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);
00600 
00601       if (MD_OP_FLAGS(op) & F_MEM)
00602         {
00603           sim_num_refs++;
00604           if (MD_OP_FLAGS(op) & F_STORE)
00605             is_write = TRUE;
00606         }
00607 
00608       /* check for DLite debugger entry condition */
00609       if (dlite_check_break(regs.regs_NPC,
00610                             is_write ? ACCESS_WRITE : ACCESS_READ,
00611                             addr, sim_num_insn, sim_num_insn))
00612         dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);
00613 
00614       /* go to the next instruction */
00615       regs.regs_PC = regs.regs_NPC;
00616       regs.regs_NPC += sizeof(md_inst_t);
00617 
00618       /* finish early? */
00619       if (max_insts && sim_num_insn >= max_insts)
00620         return;
00621     }
00622 }


UVa CS Department of Computer Science
School of Engineering, University of Virginia
151 Engineer's Way, P.O. Box 400740
Charlottesville, Virginia 22904-4740

(434) 982-2200  Fax: (434) 982-2214