File moves for the reorg. Tree is in broken state until I commit the makefile and
authorSteve Reinhardt <stever@eecs.umich.edu>
Fri, 10 Oct 2003 16:57:26 +0000 (09:57 -0700)
committerSteve Reinhardt <stever@eecs.umich.edu>
Fri, 10 Oct 2003 16:57:26 +0000 (09:57 -0700)
#include changes.

--HG--
rename : sim/cache/lzss_compression.cc => base/compression/lzss_compression.cc
rename : sim/cache/lzss_compression.hh => base/compression/lzss_compression.hh
rename : sim/cache/null_compression.hh => base/compression/null_compression.hh
rename : sim/hybrid_pred.cc => base/hybrid_pred.cc
rename : sim/hybrid_pred.hh => base/hybrid_pred.hh
rename : base/aout_object.cc => base/loader/aout_object.cc
rename : base/aout_object.hh => base/loader/aout_object.hh
rename : base/coff_sym.h => base/loader/coff_sym.h
rename : base/coff_symconst.h => base/loader/coff_symconst.h
rename : base/ecoff_object.cc => base/loader/ecoff_object.cc
rename : base/ecoff_object.hh => base/loader/ecoff_object.hh
rename : base/elf_object.cc => base/loader/elf_object.cc
rename : base/elf_object.hh => base/loader/elf_object.hh
rename : base/exec_aout.h => base/loader/exec_aout.h
rename : base/exec_ecoff.h => base/loader/exec_ecoff.h
rename : base/object_file.cc => base/loader/object_file.cc
rename : base/object_file.hh => base/loader/object_file.hh
rename : base/symtab.cc => base/loader/symtab.cc
rename : base/symtab.hh => base/loader/symtab.hh
rename : sim/predictor.hh => base/predictor.hh
rename : sim/sat_counter.cc => base/sat_counter.cc
rename : sim/sat_counter.hh => base/sat_counter.hh
rename : sim/base_cpu.cc => cpu/base_cpu.cc
rename : sim/base_cpu.hh => cpu/base_cpu.hh
rename : sim/exec_context.cc => cpu/exec_context.cc
rename : sim/exec_context.hh => cpu/exec_context.hh
rename : sim/exetrace.cc => cpu/exetrace.cc
rename : sim/exetrace.hh => cpu/exetrace.hh
rename : sim/op_class.hh => cpu/full_cpu/op_class.hh
rename : sim/smt.hh => cpu/full_cpu/smt.hh
rename : sim/inst_seq.hh => cpu/inst_seq.hh
rename : sim/intr_control.cc => cpu/intr_control.cc
rename : sim/intr_control.hh => cpu/intr_control.hh
rename : sim/memtest.cc => cpu/memtest/memtest.cc
rename : sim/memtest.hh => cpu/memtest/memtest.hh
rename : sim/pc_event.cc => cpu/pc_event.cc
rename : sim/pc_event.hh => cpu/pc_event.hh
rename : sim/simple_cpu.cc => cpu/simple_cpu/simple_cpu.cc
rename : sim/simple_cpu.hh => cpu/simple_cpu/simple_cpu.hh
rename : sim/static_inst.cc => cpu/static_inst.cc
rename : sim/static_inst.hh => cpu/static_inst.hh
extra : convert_revision : 05bd41acb2a424f1a38609fd4ac6df681bb479d6

82 files changed:
base/aout_object.cc [deleted file]
base/aout_object.hh [deleted file]
base/coff_sym.h [deleted file]
base/coff_symconst.h [deleted file]
base/compression/lzss_compression.cc [new file with mode: 0644]
base/compression/lzss_compression.hh [new file with mode: 0644]
base/compression/null_compression.hh [new file with mode: 0644]
base/ecoff_object.cc [deleted file]
base/ecoff_object.hh [deleted file]
base/elf_object.cc [deleted file]
base/elf_object.hh [deleted file]
base/exec_aout.h [deleted file]
base/exec_ecoff.h [deleted file]
base/hybrid_pred.cc [new file with mode: 0644]
base/hybrid_pred.hh [new file with mode: 0644]
base/loader/aout_object.cc [new file with mode: 0644]
base/loader/aout_object.hh [new file with mode: 0644]
base/loader/coff_sym.h [new file with mode: 0644]
base/loader/coff_symconst.h [new file with mode: 0644]
base/loader/ecoff_object.cc [new file with mode: 0644]
base/loader/ecoff_object.hh [new file with mode: 0644]
base/loader/elf_object.cc [new file with mode: 0644]
base/loader/elf_object.hh [new file with mode: 0644]
base/loader/exec_aout.h [new file with mode: 0644]
base/loader/exec_ecoff.h [new file with mode: 0644]
base/loader/object_file.cc [new file with mode: 0644]
base/loader/object_file.hh [new file with mode: 0644]
base/loader/symtab.cc [new file with mode: 0644]
base/loader/symtab.hh [new file with mode: 0644]
base/object_file.cc [deleted file]
base/object_file.hh [deleted file]
base/predictor.hh [new file with mode: 0644]
base/sat_counter.cc [new file with mode: 0644]
base/sat_counter.hh [new file with mode: 0644]
base/symtab.cc [deleted file]
base/symtab.hh [deleted file]
cpu/base_cpu.cc [new file with mode: 0644]
cpu/base_cpu.hh [new file with mode: 0644]
cpu/exec_context.cc [new file with mode: 0644]
cpu/exec_context.hh [new file with mode: 0644]
cpu/exetrace.cc [new file with mode: 0644]
cpu/exetrace.hh [new file with mode: 0644]
cpu/full_cpu/op_class.hh [new file with mode: 0644]
cpu/full_cpu/smt.hh [new file with mode: 0644]
cpu/inst_seq.hh [new file with mode: 0644]
cpu/intr_control.cc [new file with mode: 0644]
cpu/intr_control.hh [new file with mode: 0644]
cpu/memtest/memtest.cc [new file with mode: 0644]
cpu/memtest/memtest.hh [new file with mode: 0644]
cpu/pc_event.cc [new file with mode: 0644]
cpu/pc_event.hh [new file with mode: 0644]
cpu/simple_cpu/simple_cpu.cc [new file with mode: 0644]
cpu/simple_cpu/simple_cpu.hh [new file with mode: 0644]
cpu/static_inst.cc [new file with mode: 0644]
cpu/static_inst.hh [new file with mode: 0644]
sim/base_cpu.cc [deleted file]
sim/base_cpu.hh [deleted file]
sim/cache/lzss_compression.cc [deleted file]
sim/cache/lzss_compression.hh [deleted file]
sim/cache/null_compression.hh [deleted file]
sim/exec_context.cc [deleted file]
sim/exec_context.hh [deleted file]
sim/exetrace.cc [deleted file]
sim/exetrace.hh [deleted file]
sim/hybrid_pred.cc [deleted file]
sim/hybrid_pred.hh [deleted file]
sim/inst_seq.hh [deleted file]
sim/intr_control.cc [deleted file]
sim/intr_control.hh [deleted file]
sim/memtest.cc [deleted file]
sim/memtest.hh [deleted file]
sim/op_class.hh [deleted file]
sim/pc_event.cc [deleted file]
sim/pc_event.hh [deleted file]
sim/predictor.hh [deleted file]
sim/sat_counter.cc [deleted file]
sim/sat_counter.hh [deleted file]
sim/simple_cpu.cc [deleted file]
sim/simple_cpu.hh [deleted file]
sim/smt.hh [deleted file]
sim/static_inst.cc [deleted file]
sim/static_inst.hh [deleted file]

diff --git a/base/aout_object.cc b/base/aout_object.cc
deleted file mode 100644 (file)
index c0f43a6..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "aout_object.hh"
-
-#include "functional_memory.hh"
-#include "symtab.hh"
-
-#include "trace.hh"    // for DPRINTF
-
-#include "exec_aout.h"
-
-using namespace std;
-
-ObjectFile *
-AoutObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
-{
-    if (!N_BADMAG(*(aout_exechdr *)data)) {
-        return new AoutObject(fname, fd, len, data);
-    }
-    else {
-        return NULL;
-    }
-}
-
-
-AoutObject::AoutObject(const string &_filename, int _fd,
-                         size_t _len, uint8_t *_data)
-    : ObjectFile(_filename, _fd, _len, _data)
-{
-    execHdr = (aout_exechdr *)fileData;
-
-    entry = execHdr->entry;
-
-    text.baseAddr = N_TXTADDR(*execHdr);
-    text.size = execHdr->tsize;
-
-    data.baseAddr = N_DATADDR(*execHdr);
-    data.size = execHdr->dsize;
-
-    bss.baseAddr = N_BSSADDR(*execHdr);
-    bss.size = execHdr->bsize;
-
-    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
-             text.baseAddr, text.size, data.baseAddr, data.size,
-             bss.baseAddr, bss.size);
-}
-
-
-bool
-AoutObject::loadSections(FunctionalMemory *mem, bool loadPhys)
-{
-    Addr textAddr = text.baseAddr;
-    Addr dataAddr = data.baseAddr;
-
-    if (loadPhys) {
-        textAddr &= (ULL(1) << 40) - 1;
-        dataAddr &= (ULL(1) << 40) - 1;
-    }
-
-    // Since we don't really have an MMU and all memory is
-    // zero-filled, there's no need to set up the BSS segment.
-    if (text.size != 0)
-        mem->prot_write(textAddr, fileData + N_TXTOFF(*execHdr), text.size);
-    if (data.size != 0)
-        mem->prot_write(dataAddr, fileData + N_DATOFF(*execHdr), data.size);
-
-    return true;
-}
-
-
-bool
-AoutObject::loadGlobalSymbols(SymbolTable *symtab)
-{
-    // a.out symbols not supported yet
-    return false;
-}
-
-bool
-AoutObject::loadLocalSymbols(SymbolTable *symtab)
-{
-    // a.out symbols not supported yet
-    return false;
-}
diff --git a/base/aout_object.hh b/base/aout_object.hh
deleted file mode 100644 (file)
index baa8904..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __AOUT_OBJECT_HH__
-#define __AOUT_OBJECT_HH__
-
-#include "object_file.hh"
-
-// forward decls: avoid including exec_aout.h here
-struct aout_exechdr;
-
-class AoutObject : public ObjectFile
-{
-  protected:
-    aout_exechdr *execHdr;
-
-    AoutObject(const std::string &_filename, int _fd,
-                size_t _len, uint8_t *_data);
-
-  public:
-    virtual ~AoutObject() {}
-
-    virtual bool loadSections(FunctionalMemory *mem,
-                              bool loadPhys = false);
-    virtual bool loadGlobalSymbols(SymbolTable *symtab);
-    virtual bool loadLocalSymbols(SymbolTable *symtab);
-
-    static ObjectFile *tryFile(const std::string &fname, int fd,
-                               size_t len, uint8_t *data);
-};
-
-#endif // __AOUT_OBJECT_HH__
diff --git a/base/coff_sym.h b/base/coff_sym.h
deleted file mode 100644 (file)
index dae9d85..0000000
+++ /dev/null
@@ -1,491 +0,0 @@
-/* $Id$ */
-
-/*
- * Taken from binutils-2.14.90.0.5 include/coff/sym.h
- */
-
-/* Declarations of internal format of MIPS ECOFF symbols.
-   Originally contributed by MIPS Computer Systems and Third Eye Software.
-   Changes contributed by Cygnus Support are in the public domain.
-
-   This file is just aggregated with the files that make up the GNU
-   release; it is not considered part of GAS, GDB, or other GNU
-   programs.  */
-
-/*
- * |-----------------------------------------------------------|
- * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
- * | MIPS Computer Systems, Inc. grants reproduction and use   |
- * | rights to all parties, PROVIDED that this comment is      |
- * | maintained in the copy.                                   |
- * |-----------------------------------------------------------|
- */
-#ifndef _SYM_H
-#define _SYM_H
-
-/* (C) Copyright 1984 by Third Eye Software, Inc.
- *
- * Third Eye Software, Inc. grants reproduction and use rights to
- * all parties, PROVIDED that this comment is maintained in the copy.
- *
- * Third Eye makes no claims about the applicability of this
- * symbol table to a particular use.
- */
-
-/*
- * This file contains the definition of the Third Eye Symbol Table.
- *
- * Symbols are assumed to be in 'encounter order' - i.e. the order that
- * the things they represent were encountered by the compiler/assembler/loader.
- * EXCEPT for globals! These are assumed to be bunched together,
- * probably right after the last 'normal' symbol.  Globals ARE sorted
- * in ascending order.
- *
- * -----------------------------------------------------------------------
- * A brief word about Third Eye naming/use conventions:
- *
- * All arrays and index's are 0 based.
- * All "ifooMax" values are the highest legal value PLUS ONE. This makes
- * them good for allocating arrays, etc. All checks are "ifoo < ifooMax".
- *
- * "isym"      Index into the SYMbol table.
- * "ipd"       Index into the Procedure Descriptor array.
- * "ifd"       Index into the File Descriptor array.
- * "iss"       Index into String Space.
- * "cb"                Count of Bytes.
- * "rgPd"      array whose domain is "0..ipdMax-1" and RanGe is PDR.
- * "rgFd"      array whose domain is "0..ifdMax-1" and RanGe is FDR.
- */
-
-
-/*
- * Symbolic Header (HDR) structure.
- * As long as all the pointers are set correctly,
- * we don't care WHAT order the various sections come out in!
- *
- * A file produced solely for the use of CDB will probably NOT have
- * any instructions or data areas in it, as these are available
- * in the original.
- */
-
-typedef struct ecoff_symhdr {
-    coff_short magic;          /* to verify validity of the table */
-    coff_short vstamp;         /* version stamp */
-    coff_int   ilineMax;       /* number of line number entries */
-    coff_int   idnMax;         /* max index into dense number table */
-    coff_int   ipdMax;         /* number of procedures */
-    coff_int   isymMax;        /* number of local symbols */
-    coff_int   ioptMax;        /* max index into optimization symbol entries */
-    coff_int   iauxMax;        /* number of auxillary symbol entries */
-    coff_int   issMax;         /* max index into local strings */
-    coff_int   issExtMax;      /* max index into external strings */
-    coff_int   ifdMax;         /* number of file descriptor entries */
-    coff_int   crfd;           /* number of relative file descriptor entries */
-    coff_int   iextMax;        /* max index into external symbols */
-    coff_addr  cbLine;         /* number of bytes for line number entries */
-    coff_addr  cbLineOffset;   /* offset to start of line number entries*/
-    coff_addr  cbDnOffset;     /* offset to start dense number table */
-    coff_addr  cbPdOffset;     /* offset to procedure descriptor table */
-    coff_addr  cbSymOffset;    /* offset to start of local symbols*/
-    coff_addr  cbOptOffset;    /* offset to optimization symbol entries */
-    coff_addr  cbAuxOffset;    /* offset to start of auxillary symbol entries*/
-    coff_addr  cbSsOffset;     /* offset to start of local strings */
-    coff_addr  cbSsExtOffset;  /* offset to start of external strings */
-    coff_addr  cbFdOffset;     /* offset to file descriptor table */
-    coff_addr  cbRfdOffset;    /* offset to relative file descriptor table */
-    coff_addr  cbExtOffset;    /* offset to start of external symbol entries*/
-    /* If you add machine dependent fields, add them here */
-} HDRR, *pHDRR;
-#define cbHDRR sizeof(HDRR)
-#define hdrNil ((pHDRR)0)
-
-/*
- * The FDR and PDR structures speed mapping of address <-> name.
- * They are sorted in ascending memory order and are kept in
- * memory by CDB at runtime.
- */
-
-/*
- * File Descriptor
- *
- * There is one of these for EVERY FILE, whether compiled with
- * full debugging symbols or not.  The name of a file should be
- * the path name given to the compiler.         This allows the user
- * to simply specify the names of the directories where the COMPILES
- * were done, and we will be able to find their files.
- * A field whose comment starts with "R - " indicates that it will be
- * setup at runtime.
- */
-typedef struct ecoff_fdr {
-    coff_addr  adr;            /* memory address of beginning of file */
-    coff_addr  cbLineOffset;   /* byte offset from header for this file ln's */
-    coff_addr  cbLine;         /* size of lines for this file */
-    coff_addr  cbSs;           /* number of bytes in the ss */
-    coff_int   rss;            /* file name (of source, if known) */
-    coff_int   issBase;        /* file's string space */
-    coff_int   isymBase;       /* beginning of symbols */
-    coff_int   csym;           /* count file's of symbols */
-    coff_int   ilineBase;      /* file's line symbols */
-    coff_int   cline;          /* count of file's line symbols */
-    coff_int   ioptBase;       /* file's optimization entries */
-    coff_int   copt;           /* count of file's optimization entries */
-    coff_int   ipdFirst;       /* start of procedures for this file */
-    coff_int   cpd;            /* count of procedures for this file */
-    coff_int   iauxBase;       /* file's auxiliary entries */
-    coff_int   caux;           /* count of file's auxiliary entries */
-    coff_int   rfdBase;        /* index into the file indirect table */
-    coff_int   crfd;           /* count file indirect entries */
-    unsigned lang: 5;  /* language for this file */
-    unsigned fMerge : 1;       /* whether this file can be merged */
-    unsigned fReadin : 1;      /* true if it was read in (not just created) */
-    unsigned fBigendian : 1;/* if set, was compiled on big endian machine */
-    /* aux's will be in compile host's sex */
-    unsigned glevel : 2;       /* level this file was compiled with */
-    unsigned reserved : 22;  /* reserved for future use */
-    coff_uint  reserved2;
-} FDR, *pFDR;
-#define cbFDR sizeof(FDR)
-#define fdNil ((pFDR)0)
-#define ifdNil -1
-#define ifdTemp 0
-#define ilnNil -1
-
-
-/*
- * Procedure Descriptor
- *
- * There is one of these for EVERY TEXT LABEL.
- * If a procedure is in a file with full symbols, then isym
- * will point to the PROC symbols, else it will point to the
- * global symbol for the label.
- */
-
-typedef struct pdr {
-    coff_addr  adr;            /* memory address of start of procedure */
-    coff_addr  cbLineOffset;   /* byte offset for this procedure from the fd base */
-    coff_int   isym;           /* start of local symbol entries */
-    coff_int   iline;          /* start of line number entries*/
-    coff_uint  regmask;        /* save register mask */
-    coff_int   regoffset;      /* save register offset */
-    coff_int   iopt;           /* start of optimization symbol entries*/
-    coff_uint  fregmask;       /* save floating point register mask */
-    coff_int   fregoffset;     /* save floating point register offset */
-    coff_int   frameoffset;    /* frame size */
-    coff_int   lnLow;          /* lowest line in the procedure */
-    coff_int   lnHigh;         /* highest line in the procedure */
-    /* These fields are new for 64 bit ECOFF.  */
-    unsigned gp_prologue : 8; /* byte size of GP prologue */
-    unsigned gp_used : 1;      /* true if the procedure uses GP */
-    unsigned reg_frame : 1;    /* true if register frame procedure */
-    unsigned prof : 1; /* true if compiled with -pg */
-    unsigned reserved : 13;    /* reserved: must be zero */
-    unsigned localoff : 8;     /* offset of local variables from vfp */
-    coff_short framereg;       /* frame pointer register */
-    coff_short pcreg;          /* offset or reg of return pc */
-} PDR, *pPDR;
-#define cbPDR sizeof(PDR)
-#define pdNil ((pPDR) 0)
-#define ipdNil -1
-
-/*
- * The structure of the runtime procedure descriptor created by the loader
- * for use by the static exception system.
- */
-/*
- * If 0'd out because exception_info chokes Visual C++ and because there
- * don't seem to be any references to this structure elsewhere in gdb.
- */
-#if 0
-typedef struct runtime_pdr {
-    coff_addr  adr;            /* memory address of start of procedure */
-    coff_uint  regmask;        /* save register mask */
-    coff_int   regoffset;      /* save register offset */
-    coff_uint  fregmask;       /* save floating point register mask */
-    coff_int   fregoffset;     /* save floating point register offset */
-    coff_int   frameoffset;    /* frame size */
-    coff_ushort        framereg;       /* frame pointer register */
-    coff_ushort        pcreg;          /* offset or reg of return pc */
-    coff_int   irpss;          /* index into the runtime string table */
-    coff_uint  reserved;
-    struct exception_info *exception_info;/* pointer to exception array */
-} RPDR, *pRPDR;
-#define cbRPDR sizeof(RPDR)
-#define rpdNil ((pRPDR) 0)
-#endif
-
-/*
- * Line Numbers
- *
- * Line Numbers are segregated from the normal symbols because they
- * are [1] smaller , [2] are of no interest to your
- * average loader, and [3] are never needed in the middle of normal
- * scanning and therefore slow things down.
- *
- * By definition, the first LINER for any given procedure will have
- * the first line of a procedure and represent the first address.
- */
-
-typedef        coff_int LINER, *pLINER;
-#define lineNil ((pLINER)0)
-#define cbLINER sizeof(LINER)
-#define ilineNil       -1
-
-
-
-/*
- * The Symbol Structure                (GFW, to those who Know!)
- */
-
-typedef struct ecoff_sym {
-    coff_long  value;          /* value of symbol */
-    coff_int   iss;            /* index into String Space of name */
-    unsigned st : 6;   /* symbol type */
-    unsigned sc  : 5;  /* storage class - text, data, etc */
-    unsigned reserved : 1;     /* reserved */
-    unsigned index : 20;       /* index into sym/aux table */
-} SYMR, *pSYMR;
-#define symNil ((pSYMR)0)
-#define cbSYMR sizeof(SYMR)
-#define isymNil -1
-#define indexNil 0xfffff
-#define issNil -1
-#define issNull 0
-
-
-/* The following converts a memory resident string to an iss.
- * This hack is recognized in SbFIss, in sym.c of the debugger.
- */
-#define IssFSb(sb) (0x80000000 | ((coff_ulong)(sb)))
-
-/* E X T E R N A L   S Y M B O L  R E C O R D
- *
- *     Same as the SYMR except it contains file context to determine where
- *     the index is.
- */
-typedef struct ecoff_extsym {
-    SYMR       asym;           /* symbol for the external */
-    unsigned jmptbl:1; /* symbol is a jump table entry for shlibs */
-    unsigned cobol_main:1;     /* symbol is a cobol main procedure */
-    unsigned weakext:1;        /* symbol is weak external */
-    unsigned reserved:29;      /* reserved for future use */
-    coff_int ifd;              /* where the iss and index fields point into */
-} EXTR, *pEXTR;
-#define extNil ((pEXTR)0)
-#define cbEXTR sizeof(EXTR)
-
-
-/* A U X I L L A R Y   T Y P E  I N F O R M A T I O N */
-
-/*
- * Type Information Record
- */
-typedef struct {
-    unsigned fBitfield : 1; /* set if bit width is specified */
-    unsigned continued : 1; /* indicates additional TQ info in next AUX */
-    unsigned bt  : 6;  /* basic type */
-    unsigned tq4 : 4;
-    unsigned tq5 : 4;
-    /* ---- 16 bit boundary ---- */
-    unsigned tq0 : 4;
-    unsigned tq1 : 4;  /* 6 type qualifiers - tqPtr, etc. */
-    unsigned tq2 : 4;
-    unsigned tq3 : 4;
-} TIR, *pTIR;
-#define cbTIR sizeof(TIR)
-#define tiNil ((pTIR)0)
-#define itqMax 6
-
-/*
- * Relative symbol record
- *
- * If the rfd field is 4095, the index field indexes into the global symbol
- *     table.
- */
-
-typedef struct {
-    unsigned   rfd : 12;    /* index into the file indirect table */
-    unsigned   index : 20; /* index int sym/aux/iss tables */
-} RNDXR, *pRNDXR;
-#define cbRNDXR sizeof(RNDXR)
-#define rndxNil ((pRNDXR)0)
-
-/* dense numbers or sometimes called block numbers are stored in this type,
- *     a rfd of 0xffffffff is an index into the global table.
- */
-typedef struct {
-    coff_uint  rfd;    /* index into the file table */
-    coff_uint  index;  /* index int sym/aux/iss tables */
-} DNR, *pDNR;
-#define cbDNR sizeof(DNR)
-#define dnNil ((pDNR)0)
-
-
-
-/*
- * Auxillary information occurs only if needed.
- * It ALWAYS occurs in this order when present.
-
-            isymMac            used by stProc only
-            TIR                        type info
-            TIR                        additional TQ info (if first TIR was not enough)
-            rndx               if (bt == btStruct,btUnion,btEnum,btSet,btRange,
-                                    btTypedef):
-                                    rsym.index == iaux for btSet or btRange
-                                    else rsym.index == isym
-            dimLow             btRange, btSet
-            dimMac             btRange, btSet
-            rndx0              As many as there are tq arrays
-            dimLow0
-            dimHigh0
-            ...
-            rndxMax-1
-            dimLowMax-1
-            dimHighMax-1
-            width in bits      if (bit field), width in bits.
- */
-#define cAuxMax (6 + (idimMax*3))
-
-/* a union of all possible info in the AUX universe */
-typedef union {
-    TIR        ti;             /* type information record */
-    RNDXR      rndx;           /* relative index into symbol table */
-    coff_int   dnLow;          /* low dimension */
-    coff_int   dnHigh;         /* high dimension */
-    coff_int   isym;           /* symbol table index (end of proc) */
-    coff_int   iss;            /* index into string space (not used) */
-    coff_int   width;          /* width for non-default sized struc fields */
-    coff_int   count;          /* count of ranges for variant arm */
-} AUXU, *pAUXU;
-#define cbAUXU sizeof(AUXU)
-#define auxNil ((pAUXU)0)
-#define iauxNil -1
-
-
-/*
- * Optimization symbols
- *
- * Optimization symbols contain some overlap information with the normal
- * symbol table. In particular, the proc information
- * is somewhat redundant but necessary to easily find the other information
- * present.
- *
- * All of the offsets are relative to the beginning of the last otProc
- */
-
-typedef struct {
-    unsigned ot: 8;            /* optimization type */
-    unsigned value: 24;        /* address where we are moving it to */
-    RNDXR      rndx;           /* points to a symbol or opt entry */
-    coff_ulong offset; /* relative offset this occured */
-} OPTR, *pOPTR;
-#define optNil ((pOPTR) 0)
-#define cbOPTR sizeof(OPTR)
-#define ioptNil -1
-
-/*
- * File Indirect
- *
- * When a symbol is referenced across files the following procedure is used:
- *     1) use the file index to get the File indirect entry.
- *     2) use the file indirect entry to get the File descriptor.
- *     3) add the sym index to the base of that file's sym table
- *
- */
-
-typedef coff_long RFDT, *pRFDT;
-#define cbRFDT sizeof(RFDT)
-#define rfdNil -1
-
-/*
- * The file indirect table in the mips loader is known as an array of FITs.
- * This is done to keep the code in the loader readable in the area where
- * these tables are merged.  Note this is only a name change.
- */
-typedef coff_int FIT, *pFIT;
-#define cbFIT  sizeof(FIT)
-#define ifiNil -1
-#define fiNil  ((pFIT) 0)
-
-#ifdef _LANGUAGE_PASCAL
-#define ifdNil -1
-#define ilnNil -1
-#define ipdNil -1
-#define ilineNil -1
-#define isymNil -1
-#define indexNil 16#fffff
-#define issNil -1
-#define issNull 0
-#define itqMax 6
-#define iauxNil -1
-#define ioptNil -1
-#define rfdNil -1
-#define ifiNil -1
-#endif /* _LANGUAGE_PASCAL */
-
-
-/* Dense numbers
- *
- * Rather than use file index, symbol index pairs to represent symbols
- *     and globals, we use dense number so that they can be easily embeded
- *     in intermediate code and the programs that process them can
- *     use direct access tabls instead of hash table (which would be
- *     necesary otherwise because of the sparse name space caused by
- *     file index, symbol index pairs. Dense number are represented
- *     by RNDXRs.
- */
-
-/*
- * The following table defines the meaning of each SYM field as
- * a function of the "st". (scD/B == scData OR scBss)
- *
- * Note: the value "isymMac" is used by symbols that have the concept
- * of enclosing a block of related information.         This value is the
- * isym of the first symbol AFTER the end associated with the primary
- * symbol. For example if a procedure was at isym==90 and had an
- * isymMac==155, the associated end would be at isym==154, and the
- * symbol at 155 would probably (although not necessarily) be the
- * symbol for the next procedure.  This allows rapid skipping over
- * internal information of various sorts. "stEnd"s ALWAYS have the
- * isym of the primary symbol that started the block.
- *
-
-ST             SC      VALUE           INDEX
---------       ------  --------        ------
-stFile         scText  address         isymMac
-stLabel                scText  address         ---
-stGlobal       scD/B   address         iaux
-stStatic       scD/B   address         iaux
-stParam                scAbs   offset          iaux
-stLocal                scAbs   offset          iaux
-stProc         scText  address         iaux    (isymMac is first AUX)
-stStaticProc   scText  address         iaux    (isymMac is first AUX)
-
-stMember       scNil   ordinal         ---     (if member of enum)
-        (mipsread thinks the case below has a bit, not byte, offset.)
-stMember       scNil   byte offset     iaux    (if member of struct/union)
-stMember       scBits  bit offset      iaux    (bit field spec)
-
-stBlock                scText  address         isymMac (text block)
-        (the code seems to think that rather than scNil, we see scInfo for
-         the two cases below.)
-stBlock                scNil   cb              isymMac (struct/union member define)
-stBlock                scNil   cMembers        isymMac (enum member define)
-
-        (New types added by SGI to simplify things:)
-stStruct       scInfo  cb              isymMac (struct type define)
-stUnion                scInfo  cb              isymMac (union  type define)
-stEnum         scInfo  cMembers        isymMac (enum   type define)
-
-stEnd          scText  address         isymStart
-stEnd          scNil   -------         isymStart (struct/union/enum)
-
-stTypedef      scNil   -------         iaux
-stRegReloc     sc???   value           old register number
-stForward      sc???   new address     isym to original symbol
-
-stConstant     scInfo  value           --- (scalar)
-stConstant     scInfo  iss             --- (complex, e.g. string)
-
- *
- */
-#endif
diff --git a/base/coff_symconst.h b/base/coff_symconst.h
deleted file mode 100644 (file)
index caed413..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/* $Id$ */
-
-/*
- * Taken from binutils-2.14.90.0.5 include/coff/symconst.h
- */
-
-/* Declarations of constants for internal format of MIPS ECOFF symbols.
-   Originally contributed by MIPS Computer Systems and Third Eye Software.
-   Changes contributed by Cygnus Support are in the public domain.
-
-   This file is just aggregated with the files that make up the GNU
-   release; it is not considered part of GAS, GDB, or other GNU
-   programs.  */
-
-/*
- * |-----------------------------------------------------------|
- * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
- * | MIPS Computer Systems, Inc. grants reproduction and use   |
- * | rights to all parties, PROVIDED that this comment is      |
- * | maintained in the copy.                                   |
- * |-----------------------------------------------------------|
- */
-
-/* (C) Copyright 1984 by Third Eye Software, Inc.
- *
- * Third Eye Software, Inc. grants reproduction and use rights to
- * all parties, PROVIDED that this comment is maintained in the copy.
- *
- * Third Eye makes no claims about the applicability of this
- * symbol table to a particular use.
- */
-
-/* glevels for field in FDR */
-#define GLEVEL_0       2
-#define GLEVEL_1       1
-#define GLEVEL_2       0       /* for upward compat reasons. */
-#define GLEVEL_3       3
-
-/* magic number fo symheader */
-#define magicSym       0x7009
-/* The Alpha uses this value instead, for some reason.  */
-#define magicSym2      0x1992
-
-/* Language codes */
-#define langC          0
-#define langPascal     1
-#define langFortran    2
-#define        langAssembler   3       /* one Assembley inst might map to many mach */
-#define langMachine    4
-#define langNil                5
-#define langAda                6
-#define langPl1                7
-#define langCobol      8
-#define langStdc       9       /* FIXME: Collides with SGI langCplusplus */
-#define langCplusplus  9       /* FIXME: Collides with langStdc */
-#define langCplusplusV2        10      /* SGI addition */
-#define langMax                11      /* maximun allowed 32 -- 5 bits */
-
-/* The following are value definitions for the fields in the SYMR */
-
-/*
- * Storage Classes
- */
-
-#define scNil          0
-#define scText         1       /* text symbol */
-#define scData         2       /* initialized data symbol */
-#define scBss          3       /* un-initialized data symbol */
-#define scRegister     4       /* value of symbol is register number */
-#define scAbs          5       /* value of symbol is absolute */
-#define scUndefined    6       /* who knows? */
-#define scCdbLocal     7       /* variable's value is IN se->va.?? */
-#define scBits         8       /* this is a bit field */
-#define scCdbSystem    9       /* variable's value is IN CDB's address space */
-#define scDbx          9       /* overlap dbx internal use */
-#define scRegImage     10      /* register value saved on stack */
-#define scInfo         11      /* symbol contains debugger information */
-#define scUserStruct   12      /* address in struct user for current process */
-#define scSData                13      /* load time only small data */
-#define scSBss         14      /* load time only small common */
-#define scRData                15      /* load time only read only data */
-#define scVar          16      /* Var parameter (fortran,pascal) */
-#define scCommon       17      /* common variable */
-#define scSCommon      18      /* small common */
-#define scVarRegister  19      /* Var parameter in a register */
-#define scVariant      20      /* Variant record */
-#define scSUndefined   21      /* small undefined(external) data */
-#define scInit         22      /* .init section symbol */
-#define scBasedVar     23      /* Fortran or PL/1 ptr based var */
-#define scXData         24      /* exception handling data */
-#define scPData         25      /* Procedure section */
-#define scFini          26      /* .fini section */
-#define scRConst       27      /* .rconst section */
-#define scMax          32
-
-
-/*
- *   Symbol Types
- */
-
-#define stNil          0       /* Nuthin' special */
-#define stGlobal       1       /* external symbol */
-#define stStatic       2       /* static */
-#define stParam                3       /* procedure argument */
-#define stLocal                4       /* local variable */
-#define stLabel                5       /* label */
-#define stProc         6       /*     "      "  Procedure */
-#define stBlock                7       /* beginnning of block */
-#define stEnd          8       /* end (of anything) */
-#define stMember       9       /* member (of anything  - struct/union/enum */
-#define stTypedef      10      /* type definition */
-#define stFile         11      /* file name */
-#define stRegReloc     12      /* register relocation */
-#define stForward      13      /* forwarding address */
-#define stStaticProc   14      /* load time only static procs */
-#define stConstant     15      /* const */
-#define stStaParam     16      /* Fortran static parameters */
-    /* These new symbol types have been recently added to SGI machines. */
-#define stStruct       26      /* Beginning of block defining a struct type */
-#define stUnion                27      /* Beginning of block defining a union type */
-#define stEnum         28      /* Beginning of block defining an enum type */
-#define stIndirect     34      /* Indirect type specification */
-    /* Pseudo-symbols - internal to debugger */
-#define stStr          60      /* string */
-#define stNumber       61      /* pure number (ie. 4 NOR 2+2) */
-#define stExpr         62      /* 2+2 vs. 4 */
-#define stType         63      /* post-coersion SER */
-#define stMax          64
-
-/* definitions for fields in TIR */
-
-/* type qualifiers for ti.tq0 -> ti.(itqMax-1) */
-#define tqNil  0       /* bt is what you see */
-#define tqPtr  1       /* pointer */
-#define tqProc 2       /* procedure */
-#define tqArray 3      /* duh */
-#define tqFar  4       /* longer addressing - 8086/8 land */
-#define tqVol  5       /* volatile */
-#define tqConst 6      /* const */
-#define tqMax  8
-
-/* basic types as seen in ti.bt */
-#define btNil          0       /* undefined (also, enum members) */
-#define btAdr          1       /* address - integer same size as pointer */
-#define btChar         2       /* character */
-#define btUChar                3       /* unsigned character */
-#define btShort                4       /* short */
-#define btUShort       5       /* unsigned short */
-#define btInt          6       /* int */
-#define btUInt         7       /* unsigned int */
-#define btLong         8       /* long */
-#define btULong                9       /* unsigned long */
-#define btFloat                10      /* float (real) */
-#define btDouble       11      /* Double (real) */
-#define btStruct       12      /* Structure (Record) */
-#define btUnion                13      /* Union (variant) */
-#define btEnum         14      /* Enumerated */
-#define btTypedef      15      /* defined via a typedef, isymRef points */
-#define btRange                16      /* subrange of int */
-#define btSet          17      /* pascal sets */
-#define btComplex      18      /* fortran complex */
-#define btDComplex     19      /* fortran double complex */
-#define btIndirect     20      /* forward or unnamed typedef */
-#define btFixedDec     21      /* Fixed Decimal */
-#define btFloatDec     22      /* Float Decimal */
-#define btString       23      /* Varying Length Character String */
-#define btBit          24      /* Aligned Bit String */
-#define btPicture      25      /* Picture */
-#define btVoid         26      /* void */
-#define btLongLong     27      /* long long */
-#define btULongLong    28      /* unsigned long long */
-#define btMax          64
diff --git a/base/compression/lzss_compression.cc b/base/compression/lzss_compression.cc
new file mode 100644 (file)
index 0000000..a193321
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ * LZSSCompression definitions.
+ */
+
+#include <assert.h>
+
+#include "lzss_compression.hh"
+
+#include "misc.hh" //for fatal
+
+int
+LZSSCompression::findSubString(uint8_t *src, int front, int back, int size)
+{
+    int subSize = 0;
+    int max_length = 2048;
+    if (size - back < max_length) {
+        max_length = size - back;
+    }
+    for (int i = 0; i < max_length; ++i) {
+        if (src[front+i] != src[back+i]) {
+            return subSize;
+        }
+        ++subSize;
+    }
+    return subSize;
+}
+
+int
+LZSSCompression::emitByte(uint8_t *dest, uint8_t byte)
+{
+    if ((byte >> 5 & 0x7) == 0 || (byte >> 5 & 0x7) == 7) {
+        // If the top 3 bits are the same, emit 00<6bits>
+        dest[0] = byte & 0x3f;
+        return 1;
+    } else {
+        // emit 01XXXXXX <8 bits>
+        dest[0] = 0x40;
+        dest[1] = byte;
+        return 2;
+    }
+}
+
+void
+LZSSCompression::emitString(uint8_t *dest, uint16_t P, uint16_t L)
+{
+    // Emit 1<7P> <5P><3L> <8L>
+    dest[0] = 1<<7 | (P >> 5 & 0x7f);
+    dest[1] = ((P & 0x1f) << 3) | (L>>8 & 0x3);
+    dest[2] = L & 0xFF;
+}
+
+int
+LZSSCompression::compress(uint8_t *dest, uint8_t *src, int size)
+{
+    if (size > 4096) {
+        fatal("Compression can only handle block sizes of 4096 bytes or less");
+    }
+
+    // Encode the first byte.
+    int dest_index = emitByte(dest, src[0]);
+    int i = 1;
+    // A 11 bit field
+    uint16_t L;
+    // A 12 bit field
+    uint16_t P = 0;
+
+    while (i < size && dest_index < size) {
+        L = 0;
+
+        if (dest_index+3 >= size) {
+            dest_index = size;
+            continue;
+        }
+
+        if (i == size - 1) {
+            // Output the character
+            dest_index += emitByte(&dest[dest_index], src[i]);
+            ++i;
+            continue;
+        }
+        for (int j = 0; j < i; ++j) {
+            int sub_size = findSubString(src, j, i, size);
+            if (sub_size >= L) {
+                L = sub_size;
+                P = j;
+            }
+        }
+        if (L > 1) {
+            // Output the string reference
+            emitString(&dest[dest_index], P, L);
+            dest_index += 3;
+            i = i+L;
+        } else {
+            // Output the character
+            dest_index += emitByte(&dest[dest_index], src[i]);
+            ++i;
+        }
+    }
+
+    if (dest_index >= size) {
+        // Have expansion instead of compression, just copy.
+        memcpy(dest,src,size);
+        return size;
+    }
+    return dest_index;
+}
+
+int
+LZSSCompression::uncompress(uint8_t *dest, uint8_t *src, int size)
+{
+    int index = 0;
+    int i = 0;
+    while (i < size) {
+        if (src[i] & 1<<7 ) {
+            // We have a string
+            // Extract P
+            int start = (src[i] & 0x3f)<<5 | ((src[i+1] >> 3) & 0x1f);
+            // Extract L
+            int len = (src[i+1] & 0x07)<<8 | src[i+2];
+            i += 3;
+            for (int j = start; j < start+len; ++j) {
+                dest[index++] = dest[j];
+            }
+        } else {
+            // We have a character
+            if (src[i] & 1<<6) {
+                // Value is in the next byte
+                dest[index++] = src[i+1];
+                i += 2;
+            } else {
+                // just extend the lower 6 bits
+                dest[index++] = (src[i] & 0x3f) | ((src[i] & 1<<5) ? 0xC0 : 0);
+                ++i;
+            }
+        }
+    }
+    return index;
+}
diff --git a/base/compression/lzss_compression.hh b/base/compression/lzss_compression.hh
new file mode 100644 (file)
index 0000000..5fb47d3
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LZSS_COMPRESSION_HH__
+#define __LZSS_COMPRESSION_HH__
+
+/** @file
+ * LZSSCompression declarations.
+ */
+
+#include "host.hh" // for uint8_t
+
+/**
+ * Simple LZSS compression scheme.
+ */
+class LZSSCompression
+{
+    /**
+     * Finds the longest substrings that start at the given offsets.
+     * @param src The source block that we search for substrings.
+     * @param front The smaller offset.
+     * @param back The larger offset.
+     * @param size The size of the source block.
+     * @return The size of the longest substring.
+     */
+    int findSubString(uint8_t *src, int front, int back, int size);
+
+    /**
+     * Emit an encoded byte to the compressed data array. If the 2 high
+     * order bits can be signed extended, use 1 byte encoding, if not use 2
+     * bytes.
+     * @param dest The compressed data.
+     * @param byte The byte to emit.
+     * @return The number of bytes used to encode.
+     */
+    int emitByte(uint8_t *dest, uint8_t byte);
+
+    /**
+     * Emit a string reference to the compressed data array. A string reference
+     * always uses 3 bytes. 1 flag bit, 12 bits for the starting position, and
+     * 11 bits for the length of the string. This allows compression of 4096
+     * byte blocks with string lengths of up to 2048 bytes.
+     * @param dest The compressed data.
+     * @param P The starting position in the uncompressed data.
+     * @param L The length in bytes of the string.
+     */
+    void emitString(uint8_t *dest, uint16_t P, uint16_t L);
+
+  public:
+    /**
+     * Compresses the source block and stores it in the destination block. If
+     * the compressed block grows to larger than the source block, it aborts
+     * and just performs a copy.
+     * @param dest The destination block.
+     * @param src The block to be compressed.
+     * @param size The size of the source block.
+     * @return The size of the compressed block.
+     *
+     * @pre Destination has enough storage to hold the compressed block.
+     */
+    int compress(uint8_t *dest, uint8_t *src, int size);
+
+    /**
+     * Unompresses the source block and stores it in the destination block.
+     * @param dest The destination block.
+     * @param src The block to be uncompressed.
+     * @param size The size of the source block.
+     * @return The size of the uncompressed block.
+     *
+     * @pre Destination has enough storage to hold the uncompressed block.
+     */
+    int uncompress(uint8_t *dest, uint8_t *src, int size);
+};
+
+#endif //__LZSS_COMPRESSION_HH__
diff --git a/base/compression/null_compression.hh b/base/compression/null_compression.hh
new file mode 100644 (file)
index 0000000..d2bc76e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NULL_COMPRESSION_HH__
+#define __NULL_COMPRESSION_HH__
+
+/**
+ * @file
+ * This file defines a doNothing compression algorithm.
+ */
+
+/**
+ * A dummy compression class to use when no data compression is desired.
+ */
+class NullCompression
+{
+  public:
+    /**
+     * Uncompress the data, causes a fatal since no data should be compressed.
+     * @param dest The output buffer.
+     * @param src  The compressed data.
+     * @param size The number of bytes in src.
+     *
+     * @retval The size of the uncompressed data.
+     */
+    static int uncompress(uint8_t * dest, uint8_t *src, int size)
+    {
+        fatal("Can't uncompress data");
+    }
+
+    /**
+     * Compress the data, just returns the source data.
+     * @param dest The output buffer.
+     * @param src  The data to be compressed.
+     * @param size The number of bytes in src.
+     *
+     * @retval The size of the compressed data.
+     */
+
+    static int compress(uint8_t *dest, uint8_t *src, int size)
+    {
+        memcpy(dest,src,size);
+        return size;
+    }
+};
+
+#endif //__NULL_COMPRESSION_HH__
diff --git a/base/ecoff_object.cc b/base/ecoff_object.cc
deleted file mode 100644 (file)
index 87ad6fd..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "ecoff_object.hh"
-
-#include "functional_memory.hh"
-#include "symtab.hh"
-
-#include "trace.hh"    // for DPRINTF
-
-#include "exec_ecoff.h"
-#include "coff_sym.h"
-#include "coff_symconst.h"
-
-using namespace std;
-
-ObjectFile *
-EcoffObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
-{
-    if (((ecoff_filehdr *)data)->f_magic == ECOFF_MAGIC_ALPHA) {
-        // it's Alpha ECOFF
-        return new EcoffObject(fname, fd, len, data);
-    }
-    else {
-        return NULL;
-    }
-}
-
-
-EcoffObject::EcoffObject(const string &_filename, int _fd,
-                         size_t _len, uint8_t *_data)
-    : ObjectFile(_filename, _fd, _len, _data)
-{
-    execHdr = (ecoff_exechdr *)fileData;
-    fileHdr = &(execHdr->f);
-    aoutHdr = &(execHdr->a);
-
-    entry = aoutHdr->entry;
-
-    text.baseAddr = aoutHdr->text_start;
-    text.size = aoutHdr->tsize;
-
-    data.baseAddr = aoutHdr->data_start;
-    data.size = aoutHdr->dsize;
-
-    bss.baseAddr = aoutHdr->bss_start;
-    bss.size = aoutHdr->bsize;
-
-    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
-             text.baseAddr, text.size, data.baseAddr, data.size,
-             bss.baseAddr, bss.size);
-}
-
-
-bool
-EcoffObject::loadSections(FunctionalMemory *mem, bool loadPhys)
-{
-    Addr textAddr = text.baseAddr;
-    Addr dataAddr = data.baseAddr;
-
-    if (loadPhys) {
-        textAddr &= (ULL(1) << 40) - 1;
-        dataAddr &= (ULL(1) << 40) - 1;
-    }
-
-    // Since we don't really have an MMU and all memory is
-    // zero-filled, there's no need to set up the BSS segment.
-    mem->prot_write(textAddr, fileData + ECOFF_TXTOFF(execHdr), text.size);
-    mem->prot_write(dataAddr, fileData + ECOFF_DATOFF(execHdr), data.size);
-
-    return true;
-}
-
-
-bool
-EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
-{
-    if (!symtab)
-        return false;
-
-    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
-        cprintf("wrong magic\n");
-        return false;
-    }
-
-    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
-    if (syms->magic != magicSym2) {
-        cprintf("bad symbol header magic\n");
-        exit(1);
-    }
-
-    ecoff_extsym *ext_syms = (ecoff_extsym *)(fileData + syms->cbExtOffset);
-
-    char *ext_strings = (char *)(fileData + syms->cbSsExtOffset);
-    for (int i = 0; i < syms->iextMax; i++) {
-        ecoff_sym *entry = &(ext_syms[i].asym);
-        if (entry->iss != -1)
-            symtab->insert(entry->value, ext_strings + entry->iss);
-    }
-
-    return true;
-}
-
-bool
-EcoffObject::loadLocalSymbols(SymbolTable *symtab)
-{
-    if (!symtab)
-        return false;
-
-    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
-        cprintf("wrong magic\n");
-        return false;
-    }
-
-    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
-    if (syms->magic != magicSym2) {
-        cprintf("bad symbol header magic\n");
-        exit(1);
-    }
-
-    ecoff_sym *local_syms = (ecoff_sym *)(fileData + syms->cbSymOffset);
-    char *local_strings = (char *)(fileData + syms->cbSsOffset);
-    ecoff_fdr *fdesc = (ecoff_fdr *)(fileData + syms->cbFdOffset);
-
-    for (int i = 0; i < syms->ifdMax; i++) {
-        ecoff_sym *entry = (ecoff_sym *)(local_syms + fdesc[i].isymBase);
-        char *strings = (char *)(local_strings + fdesc[i].issBase);
-        for (int j = 0; j < fdesc[i].csym; j++) {
-            if (entry[j].st == stGlobal || entry[j].st == stProc)
-                if (entry[j].iss != -1)
-                    symtab->insert(entry[j].value, strings + entry[j].iss);
-        }
-    }
-
-    for (int i = 0; i < syms->isymMax; i++) {
-        ecoff_sym *entry = &(local_syms[i]);
-        if (entry->st == stProc)
-            symtab->insert(entry->value, local_strings + entry->iss);
-    }
-
-    return true;
-}
diff --git a/base/ecoff_object.hh b/base/ecoff_object.hh
deleted file mode 100644 (file)
index af757cd..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __ECOFF_OBJECT_HH__
-#define __ECOFF_OBJECT_HH__
-
-#include "object_file.hh"
-
-// forward decls: avoid including exec_ecoff.h here
-struct ecoff_exechdr;
-struct ecoff_filehdr;
-struct ecoff_aouthdr;
-
-class EcoffObject : public ObjectFile
-{
-  protected:
-    ecoff_exechdr *execHdr;
-    ecoff_filehdr *fileHdr;
-    ecoff_aouthdr *aoutHdr;
-
-    EcoffObject(const std::string &_filename, int _fd,
-                size_t _len, uint8_t *_data);
-
-  public:
-    virtual ~EcoffObject() {}
-
-    virtual bool loadSections(FunctionalMemory *mem,
-                              bool loadPhys = false);
-    virtual bool loadGlobalSymbols(SymbolTable *symtab);
-    virtual bool loadLocalSymbols(SymbolTable *symtab);
-
-    static ObjectFile *tryFile(const std::string &fname, int fd,
-                               size_t len, uint8_t *data);
-};
-
-#endif // __ECOFF_OBJECT_HH__
diff --git a/base/elf_object.cc b/base/elf_object.cc
deleted file mode 100644 (file)
index 97f50e2..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "elf_object.hh"
-
-#include "functional_memory.hh"
-#include "symtab.hh"
-
-#include "trace.hh"    // for DPRINTF
-
-#include "exec_elf.h"
-
-using namespace std;
-
-ObjectFile *
-ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
-{
-    if (memcmp(((Elf64_Ehdr *)data)->e_ident, ELFMAG, SELFMAG) == 0) {
-        // for now we'll assume it's a 64-bit Alpha binary
-        return new ElfObject(fname, fd, len, data);
-    }
-    else {
-        return NULL;
-    }
-}
-
-
-ElfObject::ElfObject(const string &_filename, int _fd,
-                         size_t _len, uint8_t *_data)
-    : ObjectFile(_filename, _fd, _len, _data)
-{
-    ehdr = (Elf64_Ehdr *)fileData;
-
-    entry = ehdr->e_entry;
-
-    phdr = (Elf64_Phdr *)(fileData + ehdr->e_phoff);
-    assert(sizeof(Elf64_Phdr) == ehdr->e_phentsize);
-
-    bool foundText = false;
-    bool foundData = false;
-    for (int i = 0; i < ehdr->e_phnum; ++i) {
-        Elf64_Phdr *p = &phdr[i];
-
-        // for now we don't care about non-loadable segments
-        if (!(p->p_type & PT_LOAD))
-            continue;
-
-        if (p->p_flags & PF_X) {
-            // executable: must be text
-            assert(!foundText);
-            foundText = true;
-            textPhdrIdx = i;
-            text.baseAddr = p->p_vaddr;
-            text.size = p->p_filesz;
-            assert(p->p_filesz == p->p_memsz);
-        }
-        else {
-            assert(p->p_flags & PF_R);
-            assert(!foundData);
-            foundData = true;
-            dataPhdrIdx = i;
-            data.baseAddr = p->p_vaddr;
-            data.size = p->p_filesz;
-            bss.baseAddr = data.baseAddr + data.size;
-            bss.size = p->p_memsz - p->p_filesz;
-        }
-    }
-
-    assert(foundText && foundData);
-
-    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
-             text.baseAddr, text.size, data.baseAddr, data.size,
-             bss.baseAddr, bss.size);
-}
-
-
-bool
-ElfObject::loadSections(FunctionalMemory *mem, bool loadPhys)
-{
-    Addr textAddr = text.baseAddr;
-    Addr dataAddr = data.baseAddr;
-
-    if (loadPhys) {
-        textAddr &= (ULL(1) << 40) - 1;
-        dataAddr &= (ULL(1) << 40) - 1;
-    }
-
-    // Since we don't really have an MMU and all memory is
-    // zero-filled, there's no need to set up the BSS segment.
-    if (text.size != 0)
-        mem->prot_write(textAddr, fileData + phdr[textPhdrIdx].p_offset,
-                        text.size);
-    if (data.size != 0)
-        mem->prot_write(dataAddr, fileData + phdr[dataPhdrIdx].p_offset,
-                        data.size);
-
-    return true;
-}
-
-
-bool
-ElfObject::loadGlobalSymbols(SymbolTable *symtab)
-{
-    // symbols not supported yet
-    return false;
-}
-
-bool
-ElfObject::loadLocalSymbols(SymbolTable *symtab)
-{
-    // symbols not supported yet
-    return false;
-}
diff --git a/base/elf_object.hh b/base/elf_object.hh
deleted file mode 100644 (file)
index c90f6eb..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __ELF_OBJECT_HH__
-#define __ELF_OBJECT_HH__
-
-#include "object_file.hh"
-
-// forward decls: avoid including exec_elf.hh here
-struct Elf64_Ehdr;
-struct Elf64_Phdr;
-
-class ElfObject : public ObjectFile
-{
-  protected:
-    Elf64_Ehdr *ehdr;
-    Elf64_Phdr *phdr;
-
-    int textPhdrIdx;
-    int dataPhdrIdx;
-
-    ElfObject(const std::string &_filename, int _fd,
-              size_t _len, uint8_t *_data);
-
-  public:
-    virtual ~ElfObject() {}
-
-    virtual bool loadSections(FunctionalMemory *mem,
-                              bool loadPhys = false);
-    virtual bool loadGlobalSymbols(SymbolTable *symtab);
-    virtual bool loadLocalSymbols(SymbolTable *symtab);
-
-    static ObjectFile *tryFile(const std::string &fname, int fd,
-                               size_t len, uint8_t *data);
-};
-
-#endif // __ELF_OBJECT_HH__
diff --git a/base/exec_aout.h b/base/exec_aout.h
deleted file mode 100644 (file)
index baed30c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $Id$ */
-
-/*
- * Taken from NetBSD sys/exec_aout.h
- */
-
-/*     $NetBSD: exec_aout.h,v 1.29 2002/12/10 17:14:31 thorpej Exp $   */
-
-/*
- * Copyright (c) 1993, 1994 Christopher G. Demetriou
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Christopher G. Demetriou.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SYS_EXEC_AOUT_H_
-#define _SYS_EXEC_AOUT_H_
-
-#ifndef N_PAGSIZ
-#define        N_PAGSIZ(ex)    (AOUT_LDPGSZ)
-#endif
-
-/* a_magic */
-#define        OMAGIC          0407    /* old impure format */
-#define        NMAGIC          0410    /* read-only text */
-#define        ZMAGIC          0413    /* demand load format */
-
-#define        N_ALIGN(ex,x) \
-        (N_GETMAGIC(ex) == ZMAGIC ? \
-        ((x) + AOUT_LDPGSZ - 1) & ~(AOUT_LDPGSZ - 1) : (x))
-
-/* Valid magic number check. */
-#define        N_BADMAG(ex) \
-        (N_GETMAGIC(ex) != NMAGIC && N_GETMAGIC(ex) != OMAGIC && \
-        N_GETMAGIC(ex) != ZMAGIC)
-
-#include "aout_machdep.h"
-
-#endif /* !_SYS_EXEC_AOUT_H_ */
diff --git a/base/exec_ecoff.h b/base/exec_ecoff.h
deleted file mode 100644 (file)
index 8c559ab..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/* $Id$ */
-
-/*
- * Taken from NetBSD sys/exec_ecoff.h
- */
-
-/*     $NetBSD: exec_ecoff.h,v 1.13 2003/01/18 09:53:18 thorpej Exp $  */
-
-/*
- * Copyright (c) 1994 Adam Glass
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Adam Glass.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef        _SYS_EXEC_ECOFF_H_
-#define        _SYS_EXEC_ECOFF_H_
-
-#include "ecoff_machdep.h"
-
-struct ecoff_filehdr {
-        coff_ushort f_magic;   /* magic number */
-        coff_ushort f_nscns;   /* # of sections */
-        coff_uint   f_timdat;  /* time and date stamp */
-        coff_ulong  f_symptr;  /* file offset of symbol table */
-        coff_uint   f_nsyms;   /* # of symbol table entries */
-        coff_ushort f_opthdr;  /* sizeof the optional header */
-        coff_ushort f_flags;   /* flags??? */
-};
-
-struct ecoff_aouthdr {
-        coff_ushort magic;
-        coff_ushort vstamp;
-        ECOFF_PAD
-        coff_ulong  tsize;
-        coff_ulong  dsize;
-        coff_ulong  bsize;
-        coff_ulong  entry;
-        coff_ulong  text_start;
-        coff_ulong  data_start;
-        coff_ulong  bss_start;
-        ECOFF_MACHDEP;
-};
-
-struct ecoff_scnhdr {          /* needed for size info */
-        char   s_name[8];      /* name */
-        coff_ulong  s_paddr;   /* physical addr? for ROMing?*/
-        coff_ulong  s_vaddr;   /* virtual addr? */
-        coff_ulong  s_size;            /* size */
-        coff_ulong  s_scnptr;  /* file offset of raw data */
-        coff_ulong  s_relptr;  /* file offset of reloc data */
-        coff_ulong  s_lnnoptr; /* file offset of line data */
-        coff_ushort s_nreloc;  /* # of relocation entries */
-        coff_ushort s_nlnno;   /* # of line entries */
-        coff_uint   s_flags;   /* flags */
-};
-
-struct ecoff_exechdr {
-        struct ecoff_filehdr f;
-        struct ecoff_aouthdr a;
-};
-
-#define ECOFF_HDR_SIZE (sizeof(struct ecoff_exechdr))
-
-#define ECOFF_OMAGIC 0407
-#define ECOFF_NMAGIC 0410
-#define ECOFF_ZMAGIC 0413
-
-#define ECOFF_ROUND(value, by) \
-        (((value) + (by) - 1) & ~((by) - 1))
-
-#define ECOFF_BLOCK_ALIGN(ep, value) \
-        ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_ROUND((value), ECOFF_LDPGSZ) : \
-         (value))
-
-#define ECOFF_TXTOFF(ep) \
-        ((ep)->a.magic == ECOFF_ZMAGIC ? 0 : \
-         ECOFF_ROUND(ECOFF_HDR_SIZE + (ep)->f.f_nscns * \
-                     sizeof(struct ecoff_scnhdr), ECOFF_SEGMENT_ALIGNMENT(ep)))
-
-#define ECOFF_DATOFF(ep) \
-        (ECOFF_BLOCK_ALIGN((ep), ECOFF_TXTOFF(ep) + (ep)->a.tsize))
-
-#define ECOFF_SEGMENT_ALIGN(ep, value) \
-        (ECOFF_ROUND((value), ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_LDPGSZ : \
-         ECOFF_SEGMENT_ALIGNMENT(ep))))
-
-#endif /* !_SYS_EXEC_ECOFF_H_ */
diff --git a/base/hybrid_pred.cc b/base/hybrid_pred.cc
new file mode 100644 (file)
index 0000000..ed7f781
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+#include <sstream>
+
+#include "hybrid_pred.hh"
+#include "statistics.hh"
+#include "sim_stats.hh"
+
+using namespace std;
+
+HybridPredictor::HybridPredictor(const char *_p_name, const char *_z_name,
+                                 const char *_o_name,
+                                 unsigned _index_bits, unsigned _counter_bits,
+                                 unsigned _zero_change, unsigned _one_change,
+                                 unsigned _thresh,
+                                 unsigned _global_bits,
+                                 unsigned _global_thresh,
+                                 bool _reg_individual_stats)
+{
+    stringstream local_name, global_name;
+
+    pred_name = _p_name;
+    one_name  = _o_name;
+    zero_name = _z_name;
+    reg_individual_stats = _reg_individual_stats;
+
+    local_name << pred_name.c_str() << ":L";
+    local = new SaturatingCounterPred(local_name.str(), zero_name, one_name,
+                                      _index_bits, _counter_bits,
+                                      _zero_change, _one_change, _thresh);
+
+    global_name << pred_name.c_str() << ":G";
+    global = new SaturatingCounterPred(global_name.str(), zero_name, one_name,
+                                       0, _global_bits, 1, 1, _global_thresh);
+}
+
+void HybridPredictor::regStats()
+{
+    using namespace Statistics;
+
+    string p_name;
+    stringstream description;
+
+    if (reg_individual_stats)
+        p_name = pred_name + ":A";
+    else
+        p_name = pred_name;
+
+
+    //
+    //  Number of predictions
+    //
+    stringstream num_zero_preds;
+    num_zero_preds << p_name << ":" << zero_name << ":preds";
+    description << "number of predictions of " << zero_name;
+    pred_zero
+        .name(num_zero_preds.str())
+        .desc(description.str());
+    description.str("");
+
+    stringstream num_one_preds;
+    num_one_preds << p_name << ":" << one_name << ":preds";
+    description << "number of predictions of " << one_name;
+    pred_one
+        .name(num_one_preds.str())
+        .desc(description.str())
+        ;
+    description.str("");
+
+    //
+    //  Count the number of correct predictions
+    //
+    stringstream num_zero_correct;
+    num_zero_correct << p_name << ":" << zero_name << ":corr_preds";
+    description << "number of correct " << zero_name << " preds" ;
+    correct_pred_zero
+        .name(num_zero_correct.str())
+        .desc(description.str())
+        ;
+    description.str("");
+
+    stringstream num_one_correct;
+    num_one_correct << p_name << ":" << one_name << ":corr_preds";
+    description << "number of correct " << one_name << " preds" ;
+    correct_pred_one
+        .name(num_one_correct.str())
+        .desc(description.str())
+        ;
+    description.str("");
+
+
+    //
+    //  Number of predictor updates
+    //
+    stringstream num_zero_updates;
+    num_zero_updates << p_name << ":" << zero_name << ":updates" ;
+    description << "number of actual " << zero_name << "s" ;
+    record_zero
+        .name(num_zero_updates.str())
+        .desc(description.str())
+        ;
+    description.str("");
+
+    stringstream num_one_updates;
+    num_one_updates << p_name << ":" << one_name << ":updates" ;
+    description << "number of actual " << one_name << "s" ;
+    record_one
+        .name(num_one_updates.str())
+        .desc(description.str())
+        ;
+    description.str("");
+
+    //
+    //  Local & Global predictor stats
+    //
+    if (reg_individual_stats) {
+        local->regStats();
+        global->regStats();
+    }
+}
+
+void HybridPredictor::regFormulas()
+{
+    using namespace Statistics;
+
+    string p_name;
+    stringstream description;
+    stringstream name;
+
+    if (reg_individual_stats)
+        p_name = pred_name + ":A";
+    else
+        p_name = pred_name;
+
+    //
+    //  Number of predictions
+    //
+    name << p_name << ":predictions" ;
+    total_preds
+        .name(name.str())
+        .desc("total number of predictions made")
+        ;
+    total_preds = pred_one + pred_zero;
+    name.str("");
+
+    //
+    //  Fraction of all predictions that are one or zero
+    //
+    name << p_name << ":" << zero_name << ":pred_frac";
+    description << "fraction of all preds that were " << zero_name ;
+    frac_preds_zero
+        .name(name.str())
+        .desc(description.str())
+        ;
+    frac_preds_zero = 100 * record_zero / total_preds;
+    description.str("");
+    name.str("");
+
+    name << p_name << ":" << one_name << ":pred_frac";
+    description << "fraction of all preds that were " << one_name ;
+    frac_preds_one
+        .name(name.str())
+        .desc(description.str())
+        ;
+    frac_preds_one = 100 * record_one / total_preds;
+    description.str("");
+    name.str("");
+
+    //
+    //  Count the number of correct predictions
+    //
+    name << p_name << ":correct_preds" ;
+    total_correct
+        .name(name.str())
+        .desc("total number of correct predictions made")
+        ;
+    total_correct = correct_pred_one + correct_pred_zero;
+    name.str("");
+
+
+    //
+    //  Prediction accuracy rates
+    //
+    name << p_name << ":pred_rate";
+    total_accuracy
+        .name(name.str())
+        .desc("fraction of all preds that were correct")
+        ;
+    total_accuracy = 100 * total_correct / total_preds;
+    name.str("");
+
+    name << p_name << ":" << zero_name << ":pred_rate" ;
+    description << "fraction of "<< zero_name <<" preds that were correct";
+    zero_accuracy
+        .name(name.str())
+        .desc(description.str())
+        ;
+    zero_accuracy = 100 * correct_pred_zero / pred_zero;
+    description.str("");
+    name.str("");
+
+    name << p_name << ":" << one_name << ":pred_rate" ;
+    description << "fraction of "<< one_name <<" preds that were correct";
+    one_accuracy
+        .name(name.str())
+        .desc(description.str())
+        ;
+    one_accuracy = 100 * correct_pred_one / pred_one;
+    description.str("");
+    name.str("");
+
+    //
+    //  Coverage
+    //
+    name << p_name << ":" << zero_name << ":coverage";
+    description << "fraction of " << zero_name
+                << "s that were predicted correctly";
+    zero_coverage
+        .name(name.str())
+        .desc(description.str())
+        ;
+    zero_coverage = 100 * correct_pred_zero / record_zero;
+    description.str("");
+    name.str("");
+
+    name << p_name << ":" << one_name << ":coverage";
+    description << "fraction of " << one_name
+                << "s that were predicted correctly";
+    one_coverage
+        .name(name.str())
+        .desc(description.str())
+        ;
+    one_coverage = 100 * correct_pred_one / record_one;
+    description.str("");
+    name.str("");
+
+    //
+    //  Local & Global predictor stats
+    //
+    if (reg_individual_stats) {
+        local->regFormulas();
+        global->regFormulas();
+    }
+
+}
+
diff --git a/base/hybrid_pred.hh b/base/hybrid_pred.hh
new file mode 100644 (file)
index 0000000..f6e14e3
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//==========================================================================
+//
+//  This predictor takes the AND of a "local" and a "global" predictor
+//  in order to determine its prediction.
+//
+//
+//
+//
+
+#ifndef __HYBRID_PRED_HH__
+#define __HYBRID_PRED_HH__
+
+#include <string>
+
+#include "sat_counter.hh"
+
+#include "statistics.hh"
+#include "sim_stats.hh"
+
+class HybridPredictor : public GenericPredictor
+{
+  private:
+    std::string pred_name;
+    std::string one_name;
+    std::string zero_name;
+    bool reg_individual_stats;
+
+    SaturatingCounterPred *local;
+    SaturatingCounterPred *global;
+
+    unsigned long max_index;
+
+    //
+    //  Stats
+    //
+    Statistics::Scalar<> pred_one; //num_one_preds
+    Statistics::Scalar<> pred_zero; //num_zero_preds
+    Statistics::Scalar<> correct_pred_one; //num_one_correct
+    Statistics::Scalar<> correct_pred_zero; //num_zero_correct
+    Statistics::Scalar<> record_one; //num_one_updates
+    Statistics::Scalar<> record_zero; //num_zero_updates
+
+    Statistics::Formula total_preds;
+    Statistics::Formula frac_preds_zero;
+    Statistics::Formula frac_preds_one;
+    Statistics::Formula total_correct;
+    Statistics::Formula total_accuracy;
+    Statistics::Formula zero_accuracy;
+    Statistics::Formula one_accuracy;
+    Statistics::Formula zero_coverage;
+    Statistics::Formula one_coverage;
+
+  public:
+    HybridPredictor(const char *_p_name, const char *_z_name,
+                    const char *_o_name,
+                    unsigned _index_bits, unsigned _counter_bits,
+                    unsigned _zero_change, unsigned _one_change,
+                    unsigned _thresh,
+                    unsigned _global_bits, unsigned _global_thresh,
+                    bool _reg_individual_stats = false);
+
+    void clear() {
+        global->clear();
+        local->clear();
+    }
+
+    unsigned peek(unsigned long _index) {
+        unsigned l = local->peek(_index);
+        unsigned g = global->peek(_index);
+
+        if (l && g)
+            return 1;
+
+        return 0;
+    }
+
+    unsigned value(unsigned long _index) {
+        unsigned l = local->peek(_index);
+        unsigned g = global->peek(_index);
+
+        l = l & 0xFFFF;
+        g = g & 0xFFFF;
+
+        return  (l << 16) | g;
+
+    }
+
+    unsigned predict(unsigned long _index) {
+        unsigned l = local->predict(_index);
+        unsigned g = global->predict(_index);
+
+        if (l && g) {
+            ++pred_one;
+            return 1;
+        }
+
+        ++pred_zero;
+        return 0;
+    }
+
+
+    //
+    //  This version need only be used if local/global statistics
+    //  will be maintained
+    //
+    unsigned predict(unsigned long _index, unsigned &_pdata) {
+        unsigned l = local->predict(_index);
+        unsigned g = global->predict(_index);
+
+        //
+        //  bit 0 => local predictor result
+        //  bit 1 => global predictor result
+        //
+        _pdata = 0;
+        if (l)
+            _pdata |= 1;
+        if (g)
+            _pdata |= 2;
+        if (l && g) {
+            ++pred_one;
+            return 1;
+        }
+
+        ++pred_zero;
+        return 0;
+    }
+
+    void record(unsigned long _index, unsigned _val, unsigned _predicted) {
+
+        if (_val) {
+            local->record(_index, _val, 0);
+            global->record(_index, _val, 0);
+            ++record_one;
+
+            if (_val == _predicted) {
+                ++correct_pred_one;
+            }
+        } else {
+            local->record(_index, _val, 0);
+            global->record(_index, _val, 0);
+            ++record_zero;
+
+            if (_val == _predicted)
+                ++correct_pred_zero;
+        }
+    }
+
+    void record(unsigned long _index, unsigned _val, unsigned _predicted,
+                unsigned _pdata)
+    {
+
+        local->record(_index, _val, (_pdata & 1));
+        global->record(_index, _val, ((_pdata & 2) ? 1 : 0));
+
+
+        if (_val) {
+            ++record_one;
+
+            if (_val == _predicted)
+                ++correct_pred_one;
+        } else {
+            ++record_zero;
+
+            if (_val == _predicted)
+                ++correct_pred_zero;
+        }
+    }
+
+    void regStats();
+    void regFormulas();
+};
+
+
+#endif  // _HYBRID_PRED_HH__
+
diff --git a/base/loader/aout_object.cc b/base/loader/aout_object.cc
new file mode 100644 (file)
index 0000000..c0f43a6
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "aout_object.hh"
+
+#include "functional_memory.hh"
+#include "symtab.hh"
+
+#include "trace.hh"    // for DPRINTF
+
+#include "exec_aout.h"
+
+using namespace std;
+
+ObjectFile *
+AoutObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
+{
+    if (!N_BADMAG(*(aout_exechdr *)data)) {
+        return new AoutObject(fname, fd, len, data);
+    }
+    else {
+        return NULL;
+    }
+}
+
+
+AoutObject::AoutObject(const string &_filename, int _fd,
+                         size_t _len, uint8_t *_data)
+    : ObjectFile(_filename, _fd, _len, _data)
+{
+    execHdr = (aout_exechdr *)fileData;
+
+    entry = execHdr->entry;
+
+    text.baseAddr = N_TXTADDR(*execHdr);
+    text.size = execHdr->tsize;
+
+    data.baseAddr = N_DATADDR(*execHdr);
+    data.size = execHdr->dsize;
+
+    bss.baseAddr = N_BSSADDR(*execHdr);
+    bss.size = execHdr->bsize;
+
+    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
+             text.baseAddr, text.size, data.baseAddr, data.size,
+             bss.baseAddr, bss.size);
+}
+
+
+bool
+AoutObject::loadSections(FunctionalMemory *mem, bool loadPhys)
+{
+    Addr textAddr = text.baseAddr;
+    Addr dataAddr = data.baseAddr;
+
+    if (loadPhys) {
+        textAddr &= (ULL(1) << 40) - 1;
+        dataAddr &= (ULL(1) << 40) - 1;
+    }
+
+    // Since we don't really have an MMU and all memory is
+    // zero-filled, there's no need to set up the BSS segment.
+    if (text.size != 0)
+        mem->prot_write(textAddr, fileData + N_TXTOFF(*execHdr), text.size);
+    if (data.size != 0)
+        mem->prot_write(dataAddr, fileData + N_DATOFF(*execHdr), data.size);
+
+    return true;
+}
+
+
+bool
+AoutObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+    // a.out symbols not supported yet
+    return false;
+}
+
+bool
+AoutObject::loadLocalSymbols(SymbolTable *symtab)
+{
+    // a.out symbols not supported yet
+    return false;
+}
diff --git a/base/loader/aout_object.hh b/base/loader/aout_object.hh
new file mode 100644 (file)
index 0000000..baa8904
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __AOUT_OBJECT_HH__
+#define __AOUT_OBJECT_HH__
+
+#include "object_file.hh"
+
+// forward decls: avoid including exec_aout.h here
+struct aout_exechdr;
+
+class AoutObject : public ObjectFile
+{
+  protected:
+    aout_exechdr *execHdr;
+
+    AoutObject(const std::string &_filename, int _fd,
+                size_t _len, uint8_t *_data);
+
+  public:
+    virtual ~AoutObject() {}
+
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false);
+    virtual bool loadGlobalSymbols(SymbolTable *symtab);
+    virtual bool loadLocalSymbols(SymbolTable *symtab);
+
+    static ObjectFile *tryFile(const std::string &fname, int fd,
+                               size_t len, uint8_t *data);
+};
+
+#endif // __AOUT_OBJECT_HH__
diff --git a/base/loader/coff_sym.h b/base/loader/coff_sym.h
new file mode 100644 (file)
index 0000000..dae9d85
--- /dev/null
@@ -0,0 +1,491 @@
+/* $Id$ */
+
+/*
+ * Taken from binutils-2.14.90.0.5 include/coff/sym.h
+ */
+
+/* Declarations of internal format of MIPS ECOFF symbols.
+   Originally contributed by MIPS Computer Systems and Third Eye Software.
+   Changes contributed by Cygnus Support are in the public domain.
+
+   This file is just aggregated with the files that make up the GNU
+   release; it is not considered part of GAS, GDB, or other GNU
+   programs.  */
+
+/*
+ * |-----------------------------------------------------------|
+ * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
+ * | MIPS Computer Systems, Inc. grants reproduction and use   |
+ * | rights to all parties, PROVIDED that this comment is      |
+ * | maintained in the copy.                                   |
+ * |-----------------------------------------------------------|
+ */
+#ifndef _SYM_H
+#define _SYM_H
+
+/* (C) Copyright 1984 by Third Eye Software, Inc.
+ *
+ * Third Eye Software, Inc. grants reproduction and use rights to
+ * all parties, PROVIDED that this comment is maintained in the copy.
+ *
+ * Third Eye makes no claims about the applicability of this
+ * symbol table to a particular use.
+ */
+
+/*
+ * This file contains the definition of the Third Eye Symbol Table.
+ *
+ * Symbols are assumed to be in 'encounter order' - i.e. the order that
+ * the things they represent were encountered by the compiler/assembler/loader.
+ * EXCEPT for globals! These are assumed to be bunched together,
+ * probably right after the last 'normal' symbol.  Globals ARE sorted
+ * in ascending order.
+ *
+ * -----------------------------------------------------------------------
+ * A brief word about Third Eye naming/use conventions:
+ *
+ * All arrays and index's are 0 based.
+ * All "ifooMax" values are the highest legal value PLUS ONE. This makes
+ * them good for allocating arrays, etc. All checks are "ifoo < ifooMax".
+ *
+ * "isym"      Index into the SYMbol table.
+ * "ipd"       Index into the Procedure Descriptor array.
+ * "ifd"       Index into the File Descriptor array.
+ * "iss"       Index into String Space.
+ * "cb"                Count of Bytes.
+ * "rgPd"      array whose domain is "0..ipdMax-1" and RanGe is PDR.
+ * "rgFd"      array whose domain is "0..ifdMax-1" and RanGe is FDR.
+ */
+
+
+/*
+ * Symbolic Header (HDR) structure.
+ * As long as all the pointers are set correctly,
+ * we don't care WHAT order the various sections come out in!
+ *
+ * A file produced solely for the use of CDB will probably NOT have
+ * any instructions or data areas in it, as these are available
+ * in the original.
+ */
+
+typedef struct ecoff_symhdr {
+    coff_short magic;          /* to verify validity of the table */
+    coff_short vstamp;         /* version stamp */
+    coff_int   ilineMax;       /* number of line number entries */
+    coff_int   idnMax;         /* max index into dense number table */
+    coff_int   ipdMax;         /* number of procedures */
+    coff_int   isymMax;        /* number of local symbols */
+    coff_int   ioptMax;        /* max index into optimization symbol entries */
+    coff_int   iauxMax;        /* number of auxillary symbol entries */
+    coff_int   issMax;         /* max index into local strings */
+    coff_int   issExtMax;      /* max index into external strings */
+    coff_int   ifdMax;         /* number of file descriptor entries */
+    coff_int   crfd;           /* number of relative file descriptor entries */
+    coff_int   iextMax;        /* max index into external symbols */
+    coff_addr  cbLine;         /* number of bytes for line number entries */
+    coff_addr  cbLineOffset;   /* offset to start of line number entries*/
+    coff_addr  cbDnOffset;     /* offset to start dense number table */
+    coff_addr  cbPdOffset;     /* offset to procedure descriptor table */
+    coff_addr  cbSymOffset;    /* offset to start of local symbols*/
+    coff_addr  cbOptOffset;    /* offset to optimization symbol entries */
+    coff_addr  cbAuxOffset;    /* offset to start of auxillary symbol entries*/
+    coff_addr  cbSsOffset;     /* offset to start of local strings */
+    coff_addr  cbSsExtOffset;  /* offset to start of external strings */
+    coff_addr  cbFdOffset;     /* offset to file descriptor table */
+    coff_addr  cbRfdOffset;    /* offset to relative file descriptor table */
+    coff_addr  cbExtOffset;    /* offset to start of external symbol entries*/
+    /* If you add machine dependent fields, add them here */
+} HDRR, *pHDRR;
+#define cbHDRR sizeof(HDRR)
+#define hdrNil ((pHDRR)0)
+
+/*
+ * The FDR and PDR structures speed mapping of address <-> name.
+ * They are sorted in ascending memory order and are kept in
+ * memory by CDB at runtime.
+ */
+
+/*
+ * File Descriptor
+ *
+ * There is one of these for EVERY FILE, whether compiled with
+ * full debugging symbols or not.  The name of a file should be
+ * the path name given to the compiler.         This allows the user
+ * to simply specify the names of the directories where the COMPILES
+ * were done, and we will be able to find their files.
+ * A field whose comment starts with "R - " indicates that it will be
+ * setup at runtime.
+ */
+typedef struct ecoff_fdr {
+    coff_addr  adr;            /* memory address of beginning of file */
+    coff_addr  cbLineOffset;   /* byte offset from header for this file ln's */
+    coff_addr  cbLine;         /* size of lines for this file */
+    coff_addr  cbSs;           /* number of bytes in the ss */
+    coff_int   rss;            /* file name (of source, if known) */
+    coff_int   issBase;        /* file's string space */
+    coff_int   isymBase;       /* beginning of symbols */
+    coff_int   csym;           /* count file's of symbols */
+    coff_int   ilineBase;      /* file's line symbols */
+    coff_int   cline;          /* count of file's line symbols */
+    coff_int   ioptBase;       /* file's optimization entries */
+    coff_int   copt;           /* count of file's optimization entries */
+    coff_int   ipdFirst;       /* start of procedures for this file */
+    coff_int   cpd;            /* count of procedures for this file */
+    coff_int   iauxBase;       /* file's auxiliary entries */
+    coff_int   caux;           /* count of file's auxiliary entries */
+    coff_int   rfdBase;        /* index into the file indirect table */
+    coff_int   crfd;           /* count file indirect entries */
+    unsigned lang: 5;  /* language for this file */
+    unsigned fMerge : 1;       /* whether this file can be merged */
+    unsigned fReadin : 1;      /* true if it was read in (not just created) */
+    unsigned fBigendian : 1;/* if set, was compiled on big endian machine */
+    /* aux's will be in compile host's sex */
+    unsigned glevel : 2;       /* level this file was compiled with */
+    unsigned reserved : 22;  /* reserved for future use */
+    coff_uint  reserved2;
+} FDR, *pFDR;
+#define cbFDR sizeof(FDR)
+#define fdNil ((pFDR)0)
+#define ifdNil -1
+#define ifdTemp 0
+#define ilnNil -1
+
+
+/*
+ * Procedure Descriptor
+ *
+ * There is one of these for EVERY TEXT LABEL.
+ * If a procedure is in a file with full symbols, then isym
+ * will point to the PROC symbols, else it will point to the
+ * global symbol for the label.
+ */
+
+typedef struct pdr {
+    coff_addr  adr;            /* memory address of start of procedure */
+    coff_addr  cbLineOffset;   /* byte offset for this procedure from the fd base */
+    coff_int   isym;           /* start of local symbol entries */
+    coff_int   iline;          /* start of line number entries*/
+    coff_uint  regmask;        /* save register mask */
+    coff_int   regoffset;      /* save register offset */
+    coff_int   iopt;           /* start of optimization symbol entries*/
+    coff_uint  fregmask;       /* save floating point register mask */
+    coff_int   fregoffset;     /* save floating point register offset */
+    coff_int   frameoffset;    /* frame size */
+    coff_int   lnLow;          /* lowest line in the procedure */
+    coff_int   lnHigh;         /* highest line in the procedure */
+    /* These fields are new for 64 bit ECOFF.  */
+    unsigned gp_prologue : 8; /* byte size of GP prologue */
+    unsigned gp_used : 1;      /* true if the procedure uses GP */
+    unsigned reg_frame : 1;    /* true if register frame procedure */
+    unsigned prof : 1; /* true if compiled with -pg */
+    unsigned reserved : 13;    /* reserved: must be zero */
+    unsigned localoff : 8;     /* offset of local variables from vfp */
+    coff_short framereg;       /* frame pointer register */
+    coff_short pcreg;          /* offset or reg of return pc */
+} PDR, *pPDR;
+#define cbPDR sizeof(PDR)
+#define pdNil ((pPDR) 0)
+#define ipdNil -1
+
+/*
+ * The structure of the runtime procedure descriptor created by the loader
+ * for use by the static exception system.
+ */
+/*
+ * If 0'd out because exception_info chokes Visual C++ and because there
+ * don't seem to be any references to this structure elsewhere in gdb.
+ */
+#if 0
+typedef struct runtime_pdr {
+    coff_addr  adr;            /* memory address of start of procedure */
+    coff_uint  regmask;        /* save register mask */
+    coff_int   regoffset;      /* save register offset */
+    coff_uint  fregmask;       /* save floating point register mask */
+    coff_int   fregoffset;     /* save floating point register offset */
+    coff_int   frameoffset;    /* frame size */
+    coff_ushort        framereg;       /* frame pointer register */
+    coff_ushort        pcreg;          /* offset or reg of return pc */
+    coff_int   irpss;          /* index into the runtime string table */
+    coff_uint  reserved;
+    struct exception_info *exception_info;/* pointer to exception array */
+} RPDR, *pRPDR;
+#define cbRPDR sizeof(RPDR)
+#define rpdNil ((pRPDR) 0)
+#endif
+
+/*
+ * Line Numbers
+ *
+ * Line Numbers are segregated from the normal symbols because they
+ * are [1] smaller , [2] are of no interest to your
+ * average loader, and [3] are never needed in the middle of normal
+ * scanning and therefore slow things down.
+ *
+ * By definition, the first LINER for any given procedure will have
+ * the first line of a procedure and represent the first address.
+ */
+
+typedef        coff_int LINER, *pLINER;
+#define lineNil ((pLINER)0)
+#define cbLINER sizeof(LINER)
+#define ilineNil       -1
+
+
+
+/*
+ * The Symbol Structure                (GFW, to those who Know!)
+ */
+
+typedef struct ecoff_sym {
+    coff_long  value;          /* value of symbol */
+    coff_int   iss;            /* index into String Space of name */
+    unsigned st : 6;   /* symbol type */
+    unsigned sc  : 5;  /* storage class - text, data, etc */
+    unsigned reserved : 1;     /* reserved */
+    unsigned index : 20;       /* index into sym/aux table */
+} SYMR, *pSYMR;
+#define symNil ((pSYMR)0)
+#define cbSYMR sizeof(SYMR)
+#define isymNil -1
+#define indexNil 0xfffff
+#define issNil -1
+#define issNull 0
+
+
+/* The following converts a memory resident string to an iss.
+ * This hack is recognized in SbFIss, in sym.c of the debugger.
+ */
+#define IssFSb(sb) (0x80000000 | ((coff_ulong)(sb)))
+
+/* E X T E R N A L   S Y M B O L  R E C O R D
+ *
+ *     Same as the SYMR except it contains file context to determine where
+ *     the index is.
+ */
+typedef struct ecoff_extsym {
+    SYMR       asym;           /* symbol for the external */
+    unsigned jmptbl:1; /* symbol is a jump table entry for shlibs */
+    unsigned cobol_main:1;     /* symbol is a cobol main procedure */
+    unsigned weakext:1;        /* symbol is weak external */
+    unsigned reserved:29;      /* reserved for future use */
+    coff_int ifd;              /* where the iss and index fields point into */
+} EXTR, *pEXTR;
+#define extNil ((pEXTR)0)
+#define cbEXTR sizeof(EXTR)
+
+
+/* A U X I L L A R Y   T Y P E  I N F O R M A T I O N */
+
+/*
+ * Type Information Record
+ */
+typedef struct {
+    unsigned fBitfield : 1; /* set if bit width is specified */
+    unsigned continued : 1; /* indicates additional TQ info in next AUX */
+    unsigned bt  : 6;  /* basic type */
+    unsigned tq4 : 4;
+    unsigned tq5 : 4;
+    /* ---- 16 bit boundary ---- */
+    unsigned tq0 : 4;
+    unsigned tq1 : 4;  /* 6 type qualifiers - tqPtr, etc. */
+    unsigned tq2 : 4;
+    unsigned tq3 : 4;
+} TIR, *pTIR;
+#define cbTIR sizeof(TIR)
+#define tiNil ((pTIR)0)
+#define itqMax 6
+
+/*
+ * Relative symbol record
+ *
+ * If the rfd field is 4095, the index field indexes into the global symbol
+ *     table.
+ */
+
+typedef struct {
+    unsigned   rfd : 12;    /* index into the file indirect table */
+    unsigned   index : 20; /* index int sym/aux/iss tables */
+} RNDXR, *pRNDXR;
+#define cbRNDXR sizeof(RNDXR)
+#define rndxNil ((pRNDXR)0)
+
+/* dense numbers or sometimes called block numbers are stored in this type,
+ *     a rfd of 0xffffffff is an index into the global table.
+ */
+typedef struct {
+    coff_uint  rfd;    /* index into the file table */
+    coff_uint  index;  /* index int sym/aux/iss tables */
+} DNR, *pDNR;
+#define cbDNR sizeof(DNR)
+#define dnNil ((pDNR)0)
+
+
+
+/*
+ * Auxillary information occurs only if needed.
+ * It ALWAYS occurs in this order when present.
+
+            isymMac            used by stProc only
+            TIR                        type info
+            TIR                        additional TQ info (if first TIR was not enough)
+            rndx               if (bt == btStruct,btUnion,btEnum,btSet,btRange,
+                                    btTypedef):
+                                    rsym.index == iaux for btSet or btRange
+                                    else rsym.index == isym
+            dimLow             btRange, btSet
+            dimMac             btRange, btSet
+            rndx0              As many as there are tq arrays
+            dimLow0
+            dimHigh0
+            ...
+            rndxMax-1
+            dimLowMax-1
+            dimHighMax-1
+            width in bits      if (bit field), width in bits.
+ */
+#define cAuxMax (6 + (idimMax*3))
+
+/* a union of all possible info in the AUX universe */
+typedef union {
+    TIR        ti;             /* type information record */
+    RNDXR      rndx;           /* relative index into symbol table */
+    coff_int   dnLow;          /* low dimension */
+    coff_int   dnHigh;         /* high dimension */
+    coff_int   isym;           /* symbol table index (end of proc) */
+    coff_int   iss;            /* index into string space (not used) */
+    coff_int   width;          /* width for non-default sized struc fields */
+    coff_int   count;          /* count of ranges for variant arm */
+} AUXU, *pAUXU;
+#define cbAUXU sizeof(AUXU)
+#define auxNil ((pAUXU)0)
+#define iauxNil -1
+
+
+/*
+ * Optimization symbols
+ *
+ * Optimization symbols contain some overlap information with the normal
+ * symbol table. In particular, the proc information
+ * is somewhat redundant but necessary to easily find the other information
+ * present.
+ *
+ * All of the offsets are relative to the beginning of the last otProc
+ */
+
+typedef struct {
+    unsigned ot: 8;            /* optimization type */
+    unsigned value: 24;        /* address where we are moving it to */
+    RNDXR      rndx;           /* points to a symbol or opt entry */
+    coff_ulong offset; /* relative offset this occured */
+} OPTR, *pOPTR;
+#define optNil ((pOPTR) 0)
+#define cbOPTR sizeof(OPTR)
+#define ioptNil -1
+
+/*
+ * File Indirect
+ *
+ * When a symbol is referenced across files the following procedure is used:
+ *     1) use the file index to get the File indirect entry.
+ *     2) use the file indirect entry to get the File descriptor.
+ *     3) add the sym index to the base of that file's sym table
+ *
+ */
+
+typedef coff_long RFDT, *pRFDT;
+#define cbRFDT sizeof(RFDT)
+#define rfdNil -1
+
+/*
+ * The file indirect table in the mips loader is known as an array of FITs.
+ * This is done to keep the code in the loader readable in the area where
+ * these tables are merged.  Note this is only a name change.
+ */
+typedef coff_int FIT, *pFIT;
+#define cbFIT  sizeof(FIT)
+#define ifiNil -1
+#define fiNil  ((pFIT) 0)
+
+#ifdef _LANGUAGE_PASCAL
+#define ifdNil -1
+#define ilnNil -1
+#define ipdNil -1
+#define ilineNil -1
+#define isymNil -1
+#define indexNil 16#fffff
+#define issNil -1
+#define issNull 0
+#define itqMax 6
+#define iauxNil -1
+#define ioptNil -1
+#define rfdNil -1
+#define ifiNil -1
+#endif /* _LANGUAGE_PASCAL */
+
+
+/* Dense numbers
+ *
+ * Rather than use file index, symbol index pairs to represent symbols
+ *     and globals, we use dense number so that they can be easily embeded
+ *     in intermediate code and the programs that process them can
+ *     use direct access tabls instead of hash table (which would be
+ *     necesary otherwise because of the sparse name space caused by
+ *     file index, symbol index pairs. Dense number are represented
+ *     by RNDXRs.
+ */
+
+/*
+ * The following table defines the meaning of each SYM field as
+ * a function of the "st". (scD/B == scData OR scBss)
+ *
+ * Note: the value "isymMac" is used by symbols that have the concept
+ * of enclosing a block of related information.         This value is the
+ * isym of the first symbol AFTER the end associated with the primary
+ * symbol. For example if a procedure was at isym==90 and had an
+ * isymMac==155, the associated end would be at isym==154, and the
+ * symbol at 155 would probably (although not necessarily) be the
+ * symbol for the next procedure.  This allows rapid skipping over
+ * internal information of various sorts. "stEnd"s ALWAYS have the
+ * isym of the primary symbol that started the block.
+ *
+
+ST             SC      VALUE           INDEX
+--------       ------  --------        ------
+stFile         scText  address         isymMac
+stLabel                scText  address         ---
+stGlobal       scD/B   address         iaux
+stStatic       scD/B   address         iaux
+stParam                scAbs   offset          iaux
+stLocal                scAbs   offset          iaux
+stProc         scText  address         iaux    (isymMac is first AUX)
+stStaticProc   scText  address         iaux    (isymMac is first AUX)
+
+stMember       scNil   ordinal         ---     (if member of enum)
+        (mipsread thinks the case below has a bit, not byte, offset.)
+stMember       scNil   byte offset     iaux    (if member of struct/union)
+stMember       scBits  bit offset      iaux    (bit field spec)
+
+stBlock                scText  address         isymMac (text block)
+        (the code seems to think that rather than scNil, we see scInfo for
+         the two cases below.)
+stBlock                scNil   cb              isymMac (struct/union member define)
+stBlock                scNil   cMembers        isymMac (enum member define)
+
+        (New types added by SGI to simplify things:)
+stStruct       scInfo  cb              isymMac (struct type define)
+stUnion                scInfo  cb              isymMac (union  type define)
+stEnum         scInfo  cMembers        isymMac (enum   type define)
+
+stEnd          scText  address         isymStart
+stEnd          scNil   -------         isymStart (struct/union/enum)
+
+stTypedef      scNil   -------         iaux
+stRegReloc     sc???   value           old register number
+stForward      sc???   new address     isym to original symbol
+
+stConstant     scInfo  value           --- (scalar)
+stConstant     scInfo  iss             --- (complex, e.g. string)
+
+ *
+ */
+#endif
diff --git a/base/loader/coff_symconst.h b/base/loader/coff_symconst.h
new file mode 100644 (file)
index 0000000..caed413
--- /dev/null
@@ -0,0 +1,172 @@
+/* $Id$ */
+
+/*
+ * Taken from binutils-2.14.90.0.5 include/coff/symconst.h
+ */
+
+/* Declarations of constants for internal format of MIPS ECOFF symbols.
+   Originally contributed by MIPS Computer Systems and Third Eye Software.
+   Changes contributed by Cygnus Support are in the public domain.
+
+   This file is just aggregated with the files that make up the GNU
+   release; it is not considered part of GAS, GDB, or other GNU
+   programs.  */
+
+/*
+ * |-----------------------------------------------------------|
+ * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
+ * | MIPS Computer Systems, Inc. grants reproduction and use   |
+ * | rights to all parties, PROVIDED that this comment is      |
+ * | maintained in the copy.                                   |
+ * |-----------------------------------------------------------|
+ */
+
+/* (C) Copyright 1984 by Third Eye Software, Inc.
+ *
+ * Third Eye Software, Inc. grants reproduction and use rights to
+ * all parties, PROVIDED that this comment is maintained in the copy.
+ *
+ * Third Eye makes no claims about the applicability of this
+ * symbol table to a particular use.
+ */
+
+/* glevels for field in FDR */
+#define GLEVEL_0       2
+#define GLEVEL_1       1
+#define GLEVEL_2       0       /* for upward compat reasons. */
+#define GLEVEL_3       3
+
+/* magic number fo symheader */
+#define magicSym       0x7009
+/* The Alpha uses this value instead, for some reason.  */
+#define magicSym2      0x1992
+
+/* Language codes */
+#define langC          0
+#define langPascal     1
+#define langFortran    2
+#define        langAssembler   3       /* one Assembley inst might map to many mach */
+#define langMachine    4
+#define langNil                5
+#define langAda                6
+#define langPl1                7
+#define langCobol      8
+#define langStdc       9       /* FIXME: Collides with SGI langCplusplus */
+#define langCplusplus  9       /* FIXME: Collides with langStdc */
+#define langCplusplusV2        10      /* SGI addition */
+#define langMax                11      /* maximun allowed 32 -- 5 bits */
+
+/* The following are value definitions for the fields in the SYMR */
+
+/*
+ * Storage Classes
+ */
+
+#define scNil          0
+#define scText         1       /* text symbol */
+#define scData         2       /* initialized data symbol */
+#define scBss          3       /* un-initialized data symbol */
+#define scRegister     4       /* value of symbol is register number */
+#define scAbs          5       /* value of symbol is absolute */
+#define scUndefined    6       /* who knows? */
+#define scCdbLocal     7       /* variable's value is IN se->va.?? */
+#define scBits         8       /* this is a bit field */
+#define scCdbSystem    9       /* variable's value is IN CDB's address space */
+#define scDbx          9       /* overlap dbx internal use */
+#define scRegImage     10      /* register value saved on stack */
+#define scInfo         11      /* symbol contains debugger information */
+#define scUserStruct   12      /* address in struct user for current process */
+#define scSData                13      /* load time only small data */
+#define scSBss         14      /* load time only small common */
+#define scRData                15      /* load time only read only data */
+#define scVar          16      /* Var parameter (fortran,pascal) */
+#define scCommon       17      /* common variable */
+#define scSCommon      18      /* small common */
+#define scVarRegister  19      /* Var parameter in a register */
+#define scVariant      20      /* Variant record */
+#define scSUndefined   21      /* small undefined(external) data */
+#define scInit         22      /* .init section symbol */
+#define scBasedVar     23      /* Fortran or PL/1 ptr based var */
+#define scXData         24      /* exception handling data */
+#define scPData         25      /* Procedure section */
+#define scFini          26      /* .fini section */
+#define scRConst       27      /* .rconst section */
+#define scMax          32
+
+
+/*
+ *   Symbol Types
+ */
+
+#define stNil          0       /* Nuthin' special */
+#define stGlobal       1       /* external symbol */
+#define stStatic       2       /* static */
+#define stParam                3       /* procedure argument */
+#define stLocal                4       /* local variable */
+#define stLabel                5       /* label */
+#define stProc         6       /*     "      "  Procedure */
+#define stBlock                7       /* beginnning of block */
+#define stEnd          8       /* end (of anything) */
+#define stMember       9       /* member (of anything  - struct/union/enum */
+#define stTypedef      10      /* type definition */
+#define stFile         11      /* file name */
+#define stRegReloc     12      /* register relocation */
+#define stForward      13      /* forwarding address */
+#define stStaticProc   14      /* load time only static procs */
+#define stConstant     15      /* const */
+#define stStaParam     16      /* Fortran static parameters */
+    /* These new symbol types have been recently added to SGI machines. */
+#define stStruct       26      /* Beginning of block defining a struct type */
+#define stUnion                27      /* Beginning of block defining a union type */
+#define stEnum         28      /* Beginning of block defining an enum type */
+#define stIndirect     34      /* Indirect type specification */
+    /* Pseudo-symbols - internal to debugger */
+#define stStr          60      /* string */
+#define stNumber       61      /* pure number (ie. 4 NOR 2+2) */
+#define stExpr         62      /* 2+2 vs. 4 */
+#define stType         63      /* post-coersion SER */
+#define stMax          64
+
+/* definitions for fields in TIR */
+
+/* type qualifiers for ti.tq0 -> ti.(itqMax-1) */
+#define tqNil  0       /* bt is what you see */
+#define tqPtr  1       /* pointer */
+#define tqProc 2       /* procedure */
+#define tqArray 3      /* duh */
+#define tqFar  4       /* longer addressing - 8086/8 land */
+#define tqVol  5       /* volatile */
+#define tqConst 6      /* const */
+#define tqMax  8
+
+/* basic types as seen in ti.bt */
+#define btNil          0       /* undefined (also, enum members) */
+#define btAdr          1       /* address - integer same size as pointer */
+#define btChar         2       /* character */
+#define btUChar                3       /* unsigned character */
+#define btShort                4       /* short */
+#define btUShort       5       /* unsigned short */
+#define btInt          6       /* int */
+#define btUInt         7       /* unsigned int */
+#define btLong         8       /* long */
+#define btULong                9       /* unsigned long */
+#define btFloat                10      /* float (real) */
+#define btDouble       11      /* Double (real) */
+#define btStruct       12      /* Structure (Record) */
+#define btUnion                13      /* Union (variant) */
+#define btEnum         14      /* Enumerated */
+#define btTypedef      15      /* defined via a typedef, isymRef points */
+#define btRange                16      /* subrange of int */
+#define btSet          17      /* pascal sets */
+#define btComplex      18      /* fortran complex */
+#define btDComplex     19      /* fortran double complex */
+#define btIndirect     20      /* forward or unnamed typedef */
+#define btFixedDec     21      /* Fixed Decimal */
+#define btFloatDec     22      /* Float Decimal */
+#define btString       23      /* Varying Length Character String */
+#define btBit          24      /* Aligned Bit String */
+#define btPicture      25      /* Picture */
+#define btVoid         26      /* void */
+#define btLongLong     27      /* long long */
+#define btULongLong    28      /* unsigned long long */
+#define btMax          64
diff --git a/base/loader/ecoff_object.cc b/base/loader/ecoff_object.cc
new file mode 100644 (file)
index 0000000..87ad6fd
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "ecoff_object.hh"
+
+#include "functional_memory.hh"
+#include "symtab.hh"
+
+#include "trace.hh"    // for DPRINTF
+
+#include "exec_ecoff.h"
+#include "coff_sym.h"
+#include "coff_symconst.h"
+
+using namespace std;
+
+ObjectFile *
+EcoffObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
+{
+    if (((ecoff_filehdr *)data)->f_magic == ECOFF_MAGIC_ALPHA) {
+        // it's Alpha ECOFF
+        return new EcoffObject(fname, fd, len, data);
+    }
+    else {
+        return NULL;
+    }
+}
+
+
+EcoffObject::EcoffObject(const string &_filename, int _fd,
+                         size_t _len, uint8_t *_data)
+    : ObjectFile(_filename, _fd, _len, _data)
+{
+    execHdr = (ecoff_exechdr *)fileData;
+    fileHdr = &(execHdr->f);
+    aoutHdr = &(execHdr->a);
+
+    entry = aoutHdr->entry;
+
+    text.baseAddr = aoutHdr->text_start;
+    text.size = aoutHdr->tsize;
+
+    data.baseAddr = aoutHdr->data_start;
+    data.size = aoutHdr->dsize;
+
+    bss.baseAddr = aoutHdr->bss_start;
+    bss.size = aoutHdr->bsize;
+
+    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
+             text.baseAddr, text.size, data.baseAddr, data.size,
+             bss.baseAddr, bss.size);
+}
+
+
+bool
+EcoffObject::loadSections(FunctionalMemory *mem, bool loadPhys)
+{
+    Addr textAddr = text.baseAddr;
+    Addr dataAddr = data.baseAddr;
+
+    if (loadPhys) {
+        textAddr &= (ULL(1) << 40) - 1;
+        dataAddr &= (ULL(1) << 40) - 1;
+    }
+
+    // Since we don't really have an MMU and all memory is
+    // zero-filled, there's no need to set up the BSS segment.
+    mem->prot_write(textAddr, fileData + ECOFF_TXTOFF(execHdr), text.size);
+    mem->prot_write(dataAddr, fileData + ECOFF_DATOFF(execHdr), data.size);
+
+    return true;
+}
+
+
+bool
+EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+    if (!symtab)
+        return false;
+
+    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
+        cprintf("wrong magic\n");
+        return false;
+    }
+
+    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
+    if (syms->magic != magicSym2) {
+        cprintf("bad symbol header magic\n");
+        exit(1);
+    }
+
+    ecoff_extsym *ext_syms = (ecoff_extsym *)(fileData + syms->cbExtOffset);
+
+    char *ext_strings = (char *)(fileData + syms->cbSsExtOffset);
+    for (int i = 0; i < syms->iextMax; i++) {
+        ecoff_sym *entry = &(ext_syms[i].asym);
+        if (entry->iss != -1)
+            symtab->insert(entry->value, ext_strings + entry->iss);
+    }
+
+    return true;
+}
+
+bool
+EcoffObject::loadLocalSymbols(SymbolTable *symtab)
+{
+    if (!symtab)
+        return false;
+
+    if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
+        cprintf("wrong magic\n");
+        return false;
+    }
+
+    ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
+    if (syms->magic != magicSym2) {
+        cprintf("bad symbol header magic\n");
+        exit(1);
+    }
+
+    ecoff_sym *local_syms = (ecoff_sym *)(fileData + syms->cbSymOffset);
+    char *local_strings = (char *)(fileData + syms->cbSsOffset);
+    ecoff_fdr *fdesc = (ecoff_fdr *)(fileData + syms->cbFdOffset);
+
+    for (int i = 0; i < syms->ifdMax; i++) {
+        ecoff_sym *entry = (ecoff_sym *)(local_syms + fdesc[i].isymBase);
+        char *strings = (char *)(local_strings + fdesc[i].issBase);
+        for (int j = 0; j < fdesc[i].csym; j++) {
+            if (entry[j].st == stGlobal || entry[j].st == stProc)
+                if (entry[j].iss != -1)
+                    symtab->insert(entry[j].value, strings + entry[j].iss);
+        }
+    }
+
+    for (int i = 0; i < syms->isymMax; i++) {
+        ecoff_sym *entry = &(local_syms[i]);
+        if (entry->st == stProc)
+            symtab->insert(entry->value, local_strings + entry->iss);
+    }
+
+    return true;
+}
diff --git a/base/loader/ecoff_object.hh b/base/loader/ecoff_object.hh
new file mode 100644 (file)
index 0000000..af757cd
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ECOFF_OBJECT_HH__
+#define __ECOFF_OBJECT_HH__
+
+#include "object_file.hh"
+
+// forward decls: avoid including exec_ecoff.h here
+struct ecoff_exechdr;
+struct ecoff_filehdr;
+struct ecoff_aouthdr;
+
+class EcoffObject : public ObjectFile
+{
+  protected:
+    ecoff_exechdr *execHdr;
+    ecoff_filehdr *fileHdr;
+    ecoff_aouthdr *aoutHdr;
+
+    EcoffObject(const std::string &_filename, int _fd,
+                size_t _len, uint8_t *_data);
+
+  public:
+    virtual ~EcoffObject() {}
+
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false);
+    virtual bool loadGlobalSymbols(SymbolTable *symtab);
+    virtual bool loadLocalSymbols(SymbolTable *symtab);
+
+    static ObjectFile *tryFile(const std::string &fname, int fd,
+                               size_t len, uint8_t *data);
+};
+
+#endif // __ECOFF_OBJECT_HH__
diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc
new file mode 100644 (file)
index 0000000..97f50e2
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "elf_object.hh"
+
+#include "functional_memory.hh"
+#include "symtab.hh"
+
+#include "trace.hh"    // for DPRINTF
+
+#include "exec_elf.h"
+
+using namespace std;
+
+ObjectFile *
+ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
+{
+    if (memcmp(((Elf64_Ehdr *)data)->e_ident, ELFMAG, SELFMAG) == 0) {
+        // for now we'll assume it's a 64-bit Alpha binary
+        return new ElfObject(fname, fd, len, data);
+    }
+    else {
+        return NULL;
+    }
+}
+
+
+ElfObject::ElfObject(const string &_filename, int _fd,
+                         size_t _len, uint8_t *_data)
+    : ObjectFile(_filename, _fd, _len, _data)
+{
+    ehdr = (Elf64_Ehdr *)fileData;
+
+    entry = ehdr->e_entry;
+
+    phdr = (Elf64_Phdr *)(fileData + ehdr->e_phoff);
+    assert(sizeof(Elf64_Phdr) == ehdr->e_phentsize);
+
+    bool foundText = false;
+    bool foundData = false;
+    for (int i = 0; i < ehdr->e_phnum; ++i) {
+        Elf64_Phdr *p = &phdr[i];
+
+        // for now we don't care about non-loadable segments
+        if (!(p->p_type & PT_LOAD))
+            continue;
+
+        if (p->p_flags & PF_X) {
+            // executable: must be text
+            assert(!foundText);
+            foundText = true;
+            textPhdrIdx = i;
+            text.baseAddr = p->p_vaddr;
+            text.size = p->p_filesz;
+            assert(p->p_filesz == p->p_memsz);
+        }
+        else {
+            assert(p->p_flags & PF_R);
+            assert(!foundData);
+            foundData = true;
+            dataPhdrIdx = i;
+            data.baseAddr = p->p_vaddr;
+            data.size = p->p_filesz;
+            bss.baseAddr = data.baseAddr + data.size;
+            bss.size = p->p_memsz - p->p_filesz;
+        }
+    }
+
+    assert(foundText && foundData);
+
+    DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
+             text.baseAddr, text.size, data.baseAddr, data.size,
+             bss.baseAddr, bss.size);
+}
+
+
+bool
+ElfObject::loadSections(FunctionalMemory *mem, bool loadPhys)
+{
+    Addr textAddr = text.baseAddr;
+    Addr dataAddr = data.baseAddr;
+
+    if (loadPhys) {
+        textAddr &= (ULL(1) << 40) - 1;
+        dataAddr &= (ULL(1) << 40) - 1;
+    }
+
+    // Since we don't really have an MMU and all memory is
+    // zero-filled, there's no need to set up the BSS segment.
+    if (text.size != 0)
+        mem->prot_write(textAddr, fileData + phdr[textPhdrIdx].p_offset,
+                        text.size);
+    if (data.size != 0)
+        mem->prot_write(dataAddr, fileData + phdr[dataPhdrIdx].p_offset,
+                        data.size);
+
+    return true;
+}
+
+
+bool
+ElfObject::loadGlobalSymbols(SymbolTable *symtab)
+{
+    // symbols not supported yet
+    return false;
+}
+
+bool
+ElfObject::loadLocalSymbols(SymbolTable *symtab)
+{
+    // symbols not supported yet
+    return false;
+}
diff --git a/base/loader/elf_object.hh b/base/loader/elf_object.hh
new file mode 100644 (file)
index 0000000..c90f6eb
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ELF_OBJECT_HH__
+#define __ELF_OBJECT_HH__
+
+#include "object_file.hh"
+
+// forward decls: avoid including exec_elf.hh here
+struct Elf64_Ehdr;
+struct Elf64_Phdr;
+
+class ElfObject : public ObjectFile
+{
+  protected:
+    Elf64_Ehdr *ehdr;
+    Elf64_Phdr *phdr;
+
+    int textPhdrIdx;
+    int dataPhdrIdx;
+
+    ElfObject(const std::string &_filename, int _fd,
+              size_t _len, uint8_t *_data);
+
+  public:
+    virtual ~ElfObject() {}
+
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false);
+    virtual bool loadGlobalSymbols(SymbolTable *symtab);
+    virtual bool loadLocalSymbols(SymbolTable *symtab);
+
+    static ObjectFile *tryFile(const std::string &fname, int fd,
+                               size_t len, uint8_t *data);
+};
+
+#endif // __ELF_OBJECT_HH__
diff --git a/base/loader/exec_aout.h b/base/loader/exec_aout.h
new file mode 100644 (file)
index 0000000..baed30c
--- /dev/null
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+/*
+ * Taken from NetBSD sys/exec_aout.h
+ */
+
+/*     $NetBSD: exec_aout.h,v 1.29 2002/12/10 17:14:31 thorpej Exp $   */
+
+/*
+ * Copyright (c) 1993, 1994 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Christopher G. Demetriou.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_EXEC_AOUT_H_
+#define _SYS_EXEC_AOUT_H_
+
+#ifndef N_PAGSIZ
+#define        N_PAGSIZ(ex)    (AOUT_LDPGSZ)
+#endif
+
+/* a_magic */
+#define        OMAGIC          0407    /* old impure format */
+#define        NMAGIC          0410    /* read-only text */
+#define        ZMAGIC          0413    /* demand load format */
+
+#define        N_ALIGN(ex,x) \
+        (N_GETMAGIC(ex) == ZMAGIC ? \
+        ((x) + AOUT_LDPGSZ - 1) & ~(AOUT_LDPGSZ - 1) : (x))
+
+/* Valid magic number check. */
+#define        N_BADMAG(ex) \
+        (N_GETMAGIC(ex) != NMAGIC && N_GETMAGIC(ex) != OMAGIC && \
+        N_GETMAGIC(ex) != ZMAGIC)
+
+#include "aout_machdep.h"
+
+#endif /* !_SYS_EXEC_AOUT_H_ */
diff --git a/base/loader/exec_ecoff.h b/base/loader/exec_ecoff.h
new file mode 100644 (file)
index 0000000..8c559ab
--- /dev/null
@@ -0,0 +1,111 @@
+/* $Id$ */
+
+/*
+ * Taken from NetBSD sys/exec_ecoff.h
+ */
+
+/*     $NetBSD: exec_ecoff.h,v 1.13 2003/01/18 09:53:18 thorpej Exp $  */
+
+/*
+ * Copyright (c) 1994 Adam Glass
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Adam Glass.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef        _SYS_EXEC_ECOFF_H_
+#define        _SYS_EXEC_ECOFF_H_
+
+#include "ecoff_machdep.h"
+
+struct ecoff_filehdr {
+        coff_ushort f_magic;   /* magic number */
+        coff_ushort f_nscns;   /* # of sections */
+        coff_uint   f_timdat;  /* time and date stamp */
+        coff_ulong  f_symptr;  /* file offset of symbol table */
+        coff_uint   f_nsyms;   /* # of symbol table entries */
+        coff_ushort f_opthdr;  /* sizeof the optional header */
+        coff_ushort f_flags;   /* flags??? */
+};
+
+struct ecoff_aouthdr {
+        coff_ushort magic;
+        coff_ushort vstamp;
+        ECOFF_PAD
+        coff_ulong  tsize;
+        coff_ulong  dsize;
+        coff_ulong  bsize;
+        coff_ulong  entry;
+        coff_ulong  text_start;
+        coff_ulong  data_start;
+        coff_ulong  bss_start;
+        ECOFF_MACHDEP;
+};
+
+struct ecoff_scnhdr {          /* needed for size info */
+        char   s_name[8];      /* name */
+        coff_ulong  s_paddr;   /* physical addr? for ROMing?*/
+        coff_ulong  s_vaddr;   /* virtual addr? */
+        coff_ulong  s_size;            /* size */
+        coff_ulong  s_scnptr;  /* file offset of raw data */
+        coff_ulong  s_relptr;  /* file offset of reloc data */
+        coff_ulong  s_lnnoptr; /* file offset of line data */
+        coff_ushort s_nreloc;  /* # of relocation entries */
+        coff_ushort s_nlnno;   /* # of line entries */
+        coff_uint   s_flags;   /* flags */
+};
+
+struct ecoff_exechdr {
+        struct ecoff_filehdr f;
+        struct ecoff_aouthdr a;
+};
+
+#define ECOFF_HDR_SIZE (sizeof(struct ecoff_exechdr))
+
+#define ECOFF_OMAGIC 0407
+#define ECOFF_NMAGIC 0410
+#define ECOFF_ZMAGIC 0413
+
+#define ECOFF_ROUND(value, by) \
+        (((value) + (by) - 1) & ~((by) - 1))
+
+#define ECOFF_BLOCK_ALIGN(ep, value) \
+        ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_ROUND((value), ECOFF_LDPGSZ) : \
+         (value))
+
+#define ECOFF_TXTOFF(ep) \
+        ((ep)->a.magic == ECOFF_ZMAGIC ? 0 : \
+         ECOFF_ROUND(ECOFF_HDR_SIZE + (ep)->f.f_nscns * \
+                     sizeof(struct ecoff_scnhdr), ECOFF_SEGMENT_ALIGNMENT(ep)))
+
+#define ECOFF_DATOFF(ep) \
+        (ECOFF_BLOCK_ALIGN((ep), ECOFF_TXTOFF(ep) + (ep)->a.tsize))
+
+#define ECOFF_SEGMENT_ALIGN(ep, value) \
+        (ECOFF_ROUND((value), ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_LDPGSZ : \
+         ECOFF_SEGMENT_ALIGNMENT(ep))))
+
+#endif /* !_SYS_EXEC_ECOFF_H_ */
diff --git a/base/loader/object_file.cc b/base/loader/object_file.cc
new file mode 100644 (file)
index 0000000..07b10b5
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <list>
+#include <string>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "cprintf.hh"
+#include "object_file.hh"
+#include "symtab.hh"
+
+#include "ecoff_object.hh"
+#include "aout_object.hh"
+#include "elf_object.hh"
+
+using namespace std;
+
+ObjectFile::ObjectFile(const string &_filename, int _fd,
+                       size_t _len, uint8_t *_data)
+    : filename(_filename), descriptor(_fd), fileData(_data), len(_len)
+{
+}
+
+
+ObjectFile::~ObjectFile()
+{
+    close();
+}
+
+
+void
+ObjectFile::close()
+{
+    if (descriptor >= 0) {
+        ::close(descriptor);
+        descriptor = -1;
+    }
+
+    if (fileData) {
+        ::munmap(fileData, len);
+        fileData = NULL;
+    }
+}
+
+
+ObjectFile *
+createObjectFile(const string &fname)
+{
+    // open the file
+    int fd = open(fname.c_str(), O_RDONLY);
+    if (fd < 0) {
+        return NULL;
+    }
+
+    // find the length of the file by seeking to the end
+    size_t len = (size_t)lseek(fd, 0, SEEK_END);
+
+    // mmap the whole shebang
+    uint8_t *fileData =
+        (uint8_t *)mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
+    if (fileData == MAP_FAILED) {
+        close(fd);
+        return NULL;
+    }
+
+    ObjectFile *fileObj = NULL;
+
+    // figure out what we have here
+    if ((fileObj = EcoffObject::tryFile(fname, fd, len, fileData)) != NULL) {
+        return fileObj;
+    }
+
+    if ((fileObj = AoutObject::tryFile(fname, fd, len, fileData)) != NULL) {
+        return fileObj;
+    }
+
+    if ((fileObj = ElfObject::tryFile(fname, fd, len, fileData)) != NULL) {
+        return fileObj;
+    }
+
+    // don't know what it is
+    close(fd);
+    munmap(fileData, len);
+    return NULL;
+}
diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh
new file mode 100644 (file)
index 0000000..1e37b7b
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __OBJECT_FILE_HH__
+#define __OBJECT_FILE_HH__
+
+#include "isa_traits.hh"       // for Addr
+
+class FunctionalMemory;
+class SymbolTable;
+
+class ObjectFile
+{
+  protected:
+    const std::string filename;
+    int descriptor;
+    uint8_t *fileData;
+    size_t len;
+
+    ObjectFile(const std::string &_filename, int _fd,
+               size_t _len, uint8_t *_data);
+
+  public:
+    virtual ~ObjectFile();
+
+    void close();
+
+    virtual bool loadSections(FunctionalMemory *mem,
+                              bool loadPhys = false) = 0;
+    virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
+    virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
+
+  protected:
+
+    struct Section {
+        Addr baseAddr;
+        size_t size;
+    };
+
+    Addr entry;
+    Addr globalPtr;
+
+    Section text;
+    Section data;
+    Section bss;
+
+  public:
+    Addr entryPoint() const { return entry; }
+    Addr globalPointer() const { return globalPtr; }
+
+    Addr textBase() const { return text.baseAddr; }
+    Addr dataBase() const { return data.baseAddr; }
+    Addr bssBase() const { return bss.baseAddr; }
+
+    size_t textSize() const { return text.size; }
+    size_t dataSize() const { return data.size; }
+    size_t bssSize() const { return bss.size; }
+};
+
+ObjectFile *createObjectFile(const std::string &fname);
+
+
+#endif // __OBJECT_FILE_HH__
diff --git a/base/loader/symtab.cc b/base/loader/symtab.cc
new file mode 100644 (file)
index 0000000..7beee18
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "host.hh"
+#include "misc.hh"
+#include "str.hh"
+#include "symtab.hh"
+
+using namespace std;
+
+bool
+SymbolTable::insert(Addr address, string symbol)
+{
+    if (!addrTable.insert(make_pair(address, symbol)).second)
+        return false;
+
+    if (!symbolTable.insert(make_pair(symbol, address)).second)
+        return false;
+
+    return true;
+}
+
+
+bool
+SymbolTable::load(const string &filename)
+{
+    string buffer;
+    ifstream file(filename.c_str());
+
+    if (!file) {
+        cerr << "Can't open symbol table file " << filename << endl;
+        fatal("file error");
+    }
+
+    while (!file.eof()) {
+        getline(file, buffer);
+        if (buffer.empty())
+            continue;
+
+        int idx = buffer.find(',');
+        if (idx == string::npos)
+            return false;
+
+        string address = buffer.substr(0, idx);
+        eat_white(address);
+        if (address.empty())
+            return false;
+
+        string symbol = buffer.substr(idx + 1);
+        eat_white(symbol);
+        if (symbol.empty())
+            return false;
+
+        Addr addr;
+        if (!to_number(address, addr))
+            return false;
+
+        if (!insert(addr, symbol))
+            return false;
+    }
+
+    file.close();
+
+    return true;
+}
+
+bool
+SymbolTable::findSymbol(Addr address, string &symbol) const
+{
+    ATable::const_iterator i = addrTable.find(address);
+    if (i == addrTable.end())
+        return false;
+
+    symbol = (*i).second;
+    return true;
+}
+
+bool
+SymbolTable::findAddress(const string &symbol, Addr &address) const
+{
+    STable::const_iterator i = symbolTable.find(symbol);
+    if (i == symbolTable.end())
+        return false;
+
+    address = (*i).second;
+    return true;
+}
+
+string
+SymbolTable::find(Addr addr) const
+{
+    string s;
+    findSymbol(addr, s);
+    return s;
+}
+
+Addr
+SymbolTable::find(const string &symbol) const
+{
+    Addr a = 0;
+    findAddress(symbol, a);
+    return a;
+}
diff --git a/base/loader/symtab.hh b/base/loader/symtab.hh
new file mode 100644 (file)
index 0000000..073325e
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SYMTAB_HH__
+#define __SYMTAB_HH__
+
+#include "hashmap.hh"
+#include "isa_traits.hh"       // for Addr
+
+class SymbolTable
+{
+  private:
+    typedef m5::hash_map<Addr, std::string> ATable;
+    typedef m5::hash_map<std::string, Addr> STable;
+
+    ATable addrTable;
+    STable symbolTable;
+
+  public:
+    SymbolTable() {}
+    SymbolTable(const std::string &file) { load(file); }
+    ~SymbolTable() {}
+
+    bool insert(Addr address, std::string symbol);
+    bool load(const std::string &file);
+
+    bool findSymbol(Addr address, std::string &symbol) const;
+    bool findAddress(const std::string &symbol, Addr &address) const;
+
+    std::string find(Addr addr) const;
+    Addr find(const std::string &symbol) const;
+};
+
+#endif // __SYMTAB_HH__
diff --git a/base/object_file.cc b/base/object_file.cc
deleted file mode 100644 (file)
index 07b10b5..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <list>
-#include <string>
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "cprintf.hh"
-#include "object_file.hh"
-#include "symtab.hh"
-
-#include "ecoff_object.hh"
-#include "aout_object.hh"
-#include "elf_object.hh"
-
-using namespace std;
-
-ObjectFile::ObjectFile(const string &_filename, int _fd,
-                       size_t _len, uint8_t *_data)
-    : filename(_filename), descriptor(_fd), fileData(_data), len(_len)
-{
-}
-
-
-ObjectFile::~ObjectFile()
-{
-    close();
-}
-
-
-void
-ObjectFile::close()
-{
-    if (descriptor >= 0) {
-        ::close(descriptor);
-        descriptor = -1;
-    }
-
-    if (fileData) {
-        ::munmap(fileData, len);
-        fileData = NULL;
-    }
-}
-
-
-ObjectFile *
-createObjectFile(const string &fname)
-{
-    // open the file
-    int fd = open(fname.c_str(), O_RDONLY);
-    if (fd < 0) {
-        return NULL;
-    }
-
-    // find the length of the file by seeking to the end
-    size_t len = (size_t)lseek(fd, 0, SEEK_END);
-
-    // mmap the whole shebang
-    uint8_t *fileData =
-        (uint8_t *)mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
-    if (fileData == MAP_FAILED) {
-        close(fd);
-        return NULL;
-    }
-
-    ObjectFile *fileObj = NULL;
-
-    // figure out what we have here
-    if ((fileObj = EcoffObject::tryFile(fname, fd, len, fileData)) != NULL) {
-        return fileObj;
-    }
-
-    if ((fileObj = AoutObject::tryFile(fname, fd, len, fileData)) != NULL) {
-        return fileObj;
-    }
-
-    if ((fileObj = ElfObject::tryFile(fname, fd, len, fileData)) != NULL) {
-        return fileObj;
-    }
-
-    // don't know what it is
-    close(fd);
-    munmap(fileData, len);
-    return NULL;
-}
diff --git a/base/object_file.hh b/base/object_file.hh
deleted file mode 100644 (file)
index 1e37b7b..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __OBJECT_FILE_HH__
-#define __OBJECT_FILE_HH__
-
-#include "isa_traits.hh"       // for Addr
-
-class FunctionalMemory;
-class SymbolTable;
-
-class ObjectFile
-{
-  protected:
-    const std::string filename;
-    int descriptor;
-    uint8_t *fileData;
-    size_t len;
-
-    ObjectFile(const std::string &_filename, int _fd,
-               size_t _len, uint8_t *_data);
-
-  public:
-    virtual ~ObjectFile();
-
-    void close();
-
-    virtual bool loadSections(FunctionalMemory *mem,
-                              bool loadPhys = false) = 0;
-    virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
-    virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
-
-  protected:
-
-    struct Section {
-        Addr baseAddr;
-        size_t size;
-    };
-
-    Addr entry;
-    Addr globalPtr;
-
-    Section text;
-    Section data;
-    Section bss;
-
-  public:
-    Addr entryPoint() const { return entry; }
-    Addr globalPointer() const { return globalPtr; }
-
-    Addr textBase() const { return text.baseAddr; }
-    Addr dataBase() const { return data.baseAddr; }
-    Addr bssBase() const { return bss.baseAddr; }
-
-    size_t textSize() const { return text.size; }
-    size_t dataSize() const { return data.size; }
-    size_t bssSize() const { return bss.size; }
-};
-
-ObjectFile *createObjectFile(const std::string &fname);
-
-
-#endif // __OBJECT_FILE_HH__
diff --git a/base/predictor.hh b/base/predictor.hh
new file mode 100644 (file)
index 0000000..7c446f2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//
+//  Abstract base class for a generic predictor
+//
+//
+
+#ifndef __PREDICTOR_HH__
+#define __PREDICTOR_HH__
+
+struct stat_sdb_t;
+
+class GenericPredictor {
+
+  public:
+    virtual void clear() = 0;
+
+    virtual unsigned predict(unsigned long _index) = 0;
+    virtual unsigned predict(unsigned long _index, unsigned &pdata) = 0;
+
+    virtual unsigned peek(unsigned long _index) = 0;
+
+    virtual void record(unsigned long _index, unsigned _actual_value,
+                        unsigned _pred_value) = 0;
+    virtual void record(unsigned long _index, unsigned _actual_value,
+                        unsigned _pred_value, unsigned _pdata) = 0;
+
+    virtual unsigned value(unsigned long _index) = 0;
+
+    virtual void regStats() = 0;
+    virtual void regFormulas() = 0;
+
+    virtual ~GenericPredictor() {};
+};
+
+#endif //  __PREDICTOR_HH__
diff --git a/base/sat_counter.cc b/base/sat_counter.cc
new file mode 100644 (file)
index 0000000..dc365f0
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sstream>
+
+#include "sat_counter.hh"
+
+#include "statistics.hh"
+#include "sim_stats.hh"
+
+
+using namespace std;
+
+
+SaturatingCounterPred::SaturatingCounterPred(string p_name,
+                                             string z_name,
+                                             string o_name,
+                                             unsigned _index_bits,
+                                             unsigned _counter_bits,
+                                             unsigned _zero_change,
+                                             unsigned _one_change,
+                                             unsigned _thresh,
+                                             unsigned _init_value)
+{
+    pred_name    = p_name;
+    zero_name    = z_name;
+    one_name     = o_name;
+
+    index_bits   = _index_bits;
+    counter_bits = _counter_bits;
+    zero_change  = _zero_change;
+    one_change   = _one_change;
+    thresh       = _thresh;
+    init_value   = _init_value;
+
+    max_index = (1 << index_bits) - 1;
+    max_value = (1 << counter_bits) - 1;
+
+    table = new unsigned[max_index + 1];
+
+    //  Initialize with the right parameters & clear the counter
+    for (int i = 0; i <= max_index; ++i)
+        table[i] = init_value;
+}
+
+void SaturatingCounterPred::regStats()
+{
+    using namespace Statistics;
+    stringstream name, description;
+
+    //
+    //  Number of predictions
+    //
+    name << pred_name << ":" << zero_name << ":preds";
+    description << "number of predictions of " << zero_name;
+    predicted_zero
+        .name(name.str())
+        .desc(description.str())
+        ;
+    description.str("");
+    name.str("");
+
+    name << pred_name << ":" << one_name << ":preds";
+    description << "number of predictions of " << one_name;
+    predicted_one
+        .name(name.str())
+        .desc(description.str())
+        ;
+    description.str("");
+    name.str("");
+
+    //
+    //  Count the number of correct predictions
+    //
+    name << pred_name << ":" << zero_name << ":corr_preds";
+    description << "number of correct " << zero_name << " preds";
+    correct_pred_zero
+        .name(name.str())
+        .desc(description.str())
+        ;
+    description.str("");
+    name.str("");
+
+    name << pred_name << ":" << one_name << ":corr_preds";
+    description << "number of correct " << one_name << " preds";
+    correct_pred_one
+        .name(name.str())
+        .desc(description.str())
+        ;
+    description.str("");
+    name.str("");
+
+    //
+    //  Number of predictor updates
+    //
+    name << pred_name << ":" << zero_name << ":updates";
+    description << "number of actual " << zero_name << "s";
+    record_zero
+        .name(name.str())
+        .desc(description.str())
+        ;
+    description.str("");
+    name.str("");
+
+    name << pred_name << ":" << one_name << ":updates";
+    description << "number of actual " << one_name << "s";
+    record_one
+        .name(name.str())
+        .desc(description.str())
+        ;
+    description.str("");
+    name.str("");
+}
+
+void SaturatingCounterPred::regFormulas()
+{
+    using namespace Statistics;
+    stringstream name, description;
+
+    //
+    //  Number of predictions
+    //
+    name << pred_name << ":predictions";
+    preds_total
+        .name(name.str())
+        .desc("total number of predictions made")
+        ;
+    preds_total = predicted_zero + predicted_one;
+    name.str("");
+
+    //
+    //  Fraction of all predictions that are one or zero
+    //
+    name << pred_name << ":" << zero_name << ":pred_frac";
+    description << "fraction of all preds that were " << zero_name;
+    pred_frac_zero
+        .name(name.str())
+        .desc(description.str())
+        ;
+    pred_frac_zero = 100 * predicted_zero / preds_total;
+    description.str("");
+    name.str("");
+
+    name << pred_name << ":" << one_name << ":pred_frac";
+    description << "fraction of all preds that were " << one_name;
+    pred_frac_one
+        .name(name.str())
+        .desc(description.str())
+        ;
+    pred_frac_one = 100 * predicted_one / preds_total;
+    description.str("");
+    name.str("");
+
+
+    //
+    //  Count the number of correct predictions
+    //
+    name << pred_name << ":correct_preds";
+    correct_total
+        .name(name.str())
+        .desc("total correct predictions made")
+        ;
+    correct_total = correct_pred_one + correct_pred_zero;
+    name.str("");
+
+    //
+    //  Number of predictor updates
+    //
+    name << pred_name << ":updates";
+    updates_total
+        .name(name.str())
+        .desc("total number of updates")
+        ;
+    updates_total = record_zero + record_one;
+    name.str("");
+
+    //
+    //  Prediction accuracy rates
+    //
+    name << pred_name << ":pred_rate";
+    pred_rate
+        .name(name.str())
+        .desc("correct fraction of all preds")
+        ;
+    pred_rate = correct_total / updates_total;
+    name.str("");
+
+    name << pred_name << ":" << zero_name << ":pred_rate";
+    description << "fraction of " << zero_name << " preds that were correct";
+    frac_correct_zero
+        .name(name.str())
+        .desc(description.str())
+        ;
+    frac_correct_zero = 100 * correct_pred_zero /
+        (correct_pred_zero + record_one - correct_pred_one);
+    description.str("");
+    name.str("");
+
+    name << pred_name << ":" << one_name << ":pred_rate";
+    description << "fraction of " << one_name << " preds that were correct";
+    frac_correct_one
+        .name(name.str())
+        .desc(description.str())
+        ;
+    frac_correct_one = 100 * correct_pred_one /
+        (correct_pred_one + record_zero - correct_pred_zero);
+    description.str("");
+    name.str("");
+
+    //
+    //  Coverage
+    //
+    name << pred_name << ":" << zero_name << ":coverage";
+    description << "fraction of " << zero_name
+                << "s that were predicted correctly";
+    coverage_zero
+        .name(name.str())
+        .desc(description.str())
+        ;
+    coverage_zero = 100 * correct_pred_zero / record_zero;
+    description.str("");
+    name.str("");
+
+    name << pred_name << ":" << one_name << ":coverage";
+    description << "fraction of " << one_name
+                << "s that were predicted correctly";
+    coverage_one
+        .name(name.str())
+        .desc(description.str())
+        ;
+    coverage_one = 100 * correct_pred_one / record_one;
+    description.str("");
+    name.str("");
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/base/sat_counter.hh b/base/sat_counter.hh
new file mode 100644 (file)
index 0000000..18eab35
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SAT_COUNTER_HH__
+#define __SAT_COUNTER_HH__
+
+#include <string>
+
+#include "predictor.hh"
+
+#include "statistics.hh"
+#include "sim_stats.hh"
+
+struct stat_sdb_t;
+
+//
+//
+//  A simple saturating counter predictor
+//
+//
+class SaturatingCounterPred : public GenericPredictor
+{
+  private:
+    std::string   pred_name;
+    std::string   zero_name;
+    std::string   one_name;
+
+    unsigned index_bits;
+    unsigned counter_bits;
+    unsigned zero_change;
+    unsigned one_change;
+    unsigned thresh;
+    unsigned init_value;
+
+    unsigned max_value;       // maximum counter value
+
+    unsigned long max_index;  // also the index mask value
+    unsigned *table;
+
+    //  Statistics
+    Statistics::Scalar<> predicted_one;      // Total predictions of one, preds_one
+    Statistics::Scalar<> predicted_zero;     // Total predictions of zero, preds_zero
+    Statistics::Scalar<> correct_pred_one;   // Total correct predictions of one, correct_one
+    Statistics::Scalar<> correct_pred_zero;  // Total correct predictions of zero, correct_zero
+
+    Statistics::Scalar<> record_zero;        //updates_zero
+    Statistics::Scalar<> record_one;         //updates_one
+
+    Statistics::Formula preds_total;
+    Statistics::Formula pred_frac_zero;
+    Statistics::Formula pred_frac_one;
+    Statistics::Formula correct_total;
+    Statistics::Formula updates_total;
+    Statistics::Formula pred_rate;
+    Statistics::Formula frac_correct_zero;
+    Statistics::Formula frac_correct_one;
+    Statistics::Formula coverage_zero;
+    Statistics::Formula coverage_one;
+
+  private:
+    bool pred_one(unsigned &counter)  { return counter >  thresh; }
+    bool pred_zero(unsigned &counter) { return counter <= thresh; }
+
+    void update_one(unsigned &counter) {
+
+        if (one_change)
+            counter += one_change;
+        else
+            counter = 0;
+
+        // check for wrap
+        if (counter > max_value)
+            counter = max_value;
+    }
+
+    void update_zero(unsigned &counter) {
+        if (zero_change) {
+            // check for wrap
+            if (counter < zero_change)
+                counter = 0;
+            else
+                counter -= zero_change;
+        } else
+            counter = 0;
+    }
+
+
+  public:
+
+    SaturatingCounterPred(std::string p_name,
+                          std::string z_name, std::string o_name,
+                          unsigned _index_bits, unsigned _counter_bits = 2,
+                          unsigned _zero_change = 1, unsigned _one_change = 1,
+                          unsigned _thresh = 1, unsigned _init_value = 0);
+
+    void clear() {
+        for (int i = 0; i <= max_index; ++i)
+            table[i] = init_value;
+    }
+
+    //  Record the ACTUAL result... and indicate whether the prediction
+    //  corresponding to this event was correct
+    void record(unsigned long _index, unsigned _val, unsigned _predicted,
+                unsigned _pdata)
+    {
+        record(_index, _val, _predicted);
+    }
+
+    void record(unsigned long _index, unsigned _val, unsigned _predicted) {
+        unsigned long index = _index & max_index;
+
+        if (_val) {
+            update_one(table[index]);
+            ++record_one;
+
+            if (_predicted)
+                ++correct_pred_one;
+        } else {
+            update_zero(table[index]);
+            ++record_zero;
+
+            if (!_predicted)
+                ++correct_pred_zero;
+        }
+    }
+
+    unsigned value(unsigned long _index) {
+        unsigned long index = _index & max_index;
+
+        return table[index];
+    }
+
+
+    unsigned predict(unsigned long _index, unsigned &pdata) {
+        return predict(_index);
+    }
+
+    unsigned predict(unsigned long _index) {
+        unsigned long index = _index & max_index;
+
+        if (pred_one(table[index])) {
+            ++predicted_one;
+            return 1;
+        }
+
+        ++predicted_zero;
+        return 0;
+    }
+
+    //  No internal state is changed here
+    unsigned peek(unsigned long _index) {
+        unsigned long index = _index & max_index;
+
+        if (pred_one(table[index]))
+            return 1;
+
+        return 0;
+    }
+
+
+    //=======================================================
+    void regStats();
+    void regFormulas();
+};
+
+
+#endif // __SAT_COUNTER_HH__
diff --git a/base/symtab.cc b/base/symtab.cc
deleted file mode 100644 (file)
index 7beee18..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <vector>
-
-#include "host.hh"
-#include "misc.hh"
-#include "str.hh"
-#include "symtab.hh"
-
-using namespace std;
-
-bool
-SymbolTable::insert(Addr address, string symbol)
-{
-    if (!addrTable.insert(make_pair(address, symbol)).second)
-        return false;
-
-    if (!symbolTable.insert(make_pair(symbol, address)).second)
-        return false;
-
-    return true;
-}
-
-
-bool
-SymbolTable::load(const string &filename)
-{
-    string buffer;
-    ifstream file(filename.c_str());
-
-    if (!file) {
-        cerr << "Can't open symbol table file " << filename << endl;
-        fatal("file error");
-    }
-
-    while (!file.eof()) {
-        getline(file, buffer);
-        if (buffer.empty())
-            continue;
-
-        int idx = buffer.find(',');
-        if (idx == string::npos)
-            return false;
-
-        string address = buffer.substr(0, idx);
-        eat_white(address);
-        if (address.empty())
-            return false;
-
-        string symbol = buffer.substr(idx + 1);
-        eat_white(symbol);
-        if (symbol.empty())
-            return false;
-
-        Addr addr;
-        if (!to_number(address, addr))
-            return false;
-
-        if (!insert(addr, symbol))
-            return false;
-    }
-
-    file.close();
-
-    return true;
-}
-
-bool
-SymbolTable::findSymbol(Addr address, string &symbol) const
-{
-    ATable::const_iterator i = addrTable.find(address);
-    if (i == addrTable.end())
-        return false;
-
-    symbol = (*i).second;
-    return true;
-}
-
-bool
-SymbolTable::findAddress(const string &symbol, Addr &address) const
-{
-    STable::const_iterator i = symbolTable.find(symbol);
-    if (i == symbolTable.end())
-        return false;
-
-    address = (*i).second;
-    return true;
-}
-
-string
-SymbolTable::find(Addr addr) const
-{
-    string s;
-    findSymbol(addr, s);
-    return s;
-}
-
-Addr
-SymbolTable::find(const string &symbol) const
-{
-    Addr a = 0;
-    findAddress(symbol, a);
-    return a;
-}
diff --git a/base/symtab.hh b/base/symtab.hh
deleted file mode 100644 (file)
index 073325e..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __SYMTAB_HH__
-#define __SYMTAB_HH__
-
-#include "hashmap.hh"
-#include "isa_traits.hh"       // for Addr
-
-class SymbolTable
-{
-  private:
-    typedef m5::hash_map<Addr, std::string> ATable;
-    typedef m5::hash_map<std::string, Addr> STable;
-
-    ATable addrTable;
-    STable symbolTable;
-
-  public:
-    SymbolTable() {}
-    SymbolTable(const std::string &file) { load(file); }
-    ~SymbolTable() {}
-
-    bool insert(Addr address, std::string symbol);
-    bool load(const std::string &file);
-
-    bool findSymbol(Addr address, std::string &symbol) const;
-    bool findAddress(const std::string &symbol, Addr &address) const;
-
-    std::string find(Addr addr) const;
-    Addr find(const std::string &symbol) const;
-};
-
-#endif // __SYMTAB_HH__
diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc
new file mode 100644 (file)
index 0000000..06b2ec6
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+#include "base_cpu.hh"
+#include "cprintf.hh"
+#include "exec_context.hh"
+#include "misc.hh"
+#include "sim_events.hh"
+
+using namespace std;
+
+vector<BaseCPU *> BaseCPU::cpuList;
+
+// This variable reflects the max number of threads in any CPU.  Be
+// careful to only use it once all the CPUs that you care about have
+// been initialized
+int maxThreadsPerCPU = 1;
+
+#ifdef FULL_SYSTEM
+BaseCPU::BaseCPU(const string &_name, int _number_of_threads,
+                 Counter max_insts_any_thread,
+                 Counter max_insts_all_threads,
+                 System *_system, int num, Tick freq)
+    : SimObject(_name), number(num), frequency(freq),
+      number_of_threads(_number_of_threads), system(_system)
+#else
+BaseCPU::BaseCPU(const string &_name, int _number_of_threads,
+                 Counter max_insts_any_thread,
+                 Counter max_insts_all_threads)
+    : SimObject(_name), number_of_threads(_number_of_threads)
+#endif
+{
+    // add self to global list of CPUs
+    cpuList.push_back(this);
+
+    if (number_of_threads > maxThreadsPerCPU)
+        maxThreadsPerCPU = number_of_threads;
+
+    // allocate per-thread instruction-based event queues
+    comInsnEventQueue = new (EventQueue *)[number_of_threads];
+    for (int i = 0; i < number_of_threads; ++i)
+        comInsnEventQueue[i] = new EventQueue("instruction-based event queue");
+
+    //
+    // set up instruction-count-based termination events, if any
+    //
+    if (max_insts_any_thread != 0)
+        for (int i = 0; i < number_of_threads; ++i)
+            new SimExitEvent(comInsnEventQueue[i], max_insts_any_thread,
+                "a thread reached the max instruction count");
+
+    if (max_insts_all_threads != 0) {
+        // allocate & initialize shared downcounter: each event will
+        // decrement this when triggered; simulation will terminate
+        // when counter reaches 0
+        int *counter = new int;
+        *counter = number_of_threads;
+        for (int i = 0; i < number_of_threads; ++i)
+            new CountedExitEvent(comInsnEventQueue[i],
+                "all threads reached the max instruction count",
+                max_insts_all_threads, *counter);
+    }
+
+#ifdef FULL_SYSTEM
+    memset(interrupts, 0, sizeof(interrupts));
+    intstatus = 0;
+#endif
+}
+
+void
+BaseCPU::regStats()
+{
+    int size = contexts.size();
+    if (size > 1) {
+        for (int i = 0; i < size; ++i) {
+            stringstream namestr;
+            ccprintf(namestr, "%s.ctx%d", name(), i);
+            contexts[i]->regStats(namestr.str());
+        }
+    } else if (size == 1)
+        contexts[0]->regStats(name());
+}
+
+#ifdef FULL_SYSTEM
+void
+BaseCPU::post_interrupt(int int_num, int index)
+{
+    DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
+
+    if (int_num < 0 || int_num >= NumInterruptLevels)
+        panic("int_num out of bounds\n");
+
+    if (index < 0 || index >= sizeof(uint8_t) * 8)
+        panic("int_num out of bounds\n");
+
+    AlphaISA::check_interrupts = 1;
+    interrupts[int_num] |= 1 << index;
+    intstatus |= (ULL(1) << int_num);
+}
+
+void
+BaseCPU::clear_interrupt(int int_num, int index)
+{
+    DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
+
+    if (int_num < 0 || int_num >= NumInterruptLevels)
+        panic("int_num out of bounds\n");
+
+    if (index < 0 || index >= sizeof(uint8_t) * 8)
+        panic("int_num out of bounds\n");
+
+    interrupts[int_num] &= ~(1 << index);
+    if (interrupts[int_num] == 0)
+        intstatus &= ~(ULL(1) << int_num);
+}
+
+void
+BaseCPU::clear_interrupts()
+{
+    DPRINTF(Interrupt, "Interrupts all cleared\n");
+
+    memset(interrupts, 0, sizeof(interrupts));
+    intstatus = 0;
+}
+
+#endif // FULL_SYSTEM
+
+DEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh
new file mode 100644 (file)
index 0000000..745220d
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BASE_CPU_HH__
+#define __BASE_CPU_HH__
+
+#include <vector>
+
+#include "eventq.hh"
+#include "sim_object.hh"
+
+#include "isa_traits.hh"       // for Addr
+
+#ifdef FULL_SYSTEM
+class System;
+#endif
+
+class BranchPred;
+class ExecContext;
+
+class BaseCPU : public SimObject
+{
+#ifdef FULL_SYSTEM
+  protected:
+    int number;
+    Tick frequency;
+    uint8_t interrupts[NumInterruptLevels];
+    uint64_t intstatus;
+
+  public:
+    virtual void post_interrupt(int int_num, int index);
+    virtual void clear_interrupt(int int_num, int index);
+    virtual void clear_interrupts();
+
+    bool check_interrupt(int int_num) const {
+        if (int_num > NumInterruptLevels)
+            panic("int_num out of bounds\n");
+
+        return interrupts[int_num] != 0;
+    }
+
+    bool check_interrupts() const { return intstatus != 0; }
+    uint64_t intr_status() const { return intstatus; }
+
+    Tick getFreq() const { return frequency; }
+#endif
+
+  protected:
+    std::vector<ExecContext *> contexts;
+
+  public:
+    virtual void execCtxStatusChg() {}
+
+  public:
+
+#ifdef FULL_SYSTEM
+    BaseCPU(const std::string &_name, int _number_of_threads,
+            Counter max_insts_any_thread, Counter max_insts_all_threads,
+            System *_system,
+            int num, Tick freq);
+#else
+    BaseCPU(const std::string &_name, int _number_of_threads,
+            Counter max_insts_any_thread = 0,
+            Counter max_insts_all_threads = 0);
+#endif
+
+    virtual ~BaseCPU() {}
+
+    virtual void regStats();
+
+    /// Number of threads we're actually simulating (<= SMT_MAX_THREADS).
+    /// This is a constant for the duration of the simulation.
+    int number_of_threads;
+
+    /// Vector of per-thread instruction-based event queues.  Used for
+    /// scheduling events based on number of instructions committed by
+    /// a particular thread.
+    EventQueue **comInsnEventQueue;
+
+#ifdef FULL_SYSTEM
+    System *system;
+#endif
+
+    virtual bool filterThisInstructionPrefetch(int thread_number,
+        short asid, Addr prefetchTarget) const { return true; }
+
+    /// Return pointer to CPU's branch predictor (NULL if none).
+    virtual BranchPred *getBranchPred() { return NULL; };
+
+  private:
+    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
+
+  public:
+    static int numSimulatedCPUs() { return cpuList.size(); }
+};
+
+#endif // __BASE_CPU_HH__
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc
new file mode 100644 (file)
index 0000000..c81d172
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "base_cpu.hh"
+#include "exec_context.hh"
+
+#ifdef FULL_SYSTEM
+#include "system.hh"
+#else
+#include "prog.hh"
+#endif
+
+using namespace std;
+
+// constructor
+#ifdef FULL_SYSTEM
+ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
+                         AlphaItb *_itb, AlphaDtb *_dtb,
+                         FunctionalMemory *_mem, int _cpu_id)
+    : kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num), mem(_mem),
+      itb(_itb), dtb(_dtb), cpu_id(_cpu_id), system(_sys),
+      memCtrl(_sys->memCtrl), physmem(_sys->physmem)
+{
+    memset(&regs, 0, sizeof(RegFile));
+    _status = Active;
+    func_exe_insn = 0;
+    storeCondFailures = 0;
+    system->registerExecContext(this);
+}
+#else
+ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
+                         Process *_process, int _asid)
+    : cpu(_cpu), thread_num(_thread_num), process(_process), asid (_asid)
+{
+
+    // Register with process object. Our 'active' will be set by the
+    // process iff we're the initial context.  Others are reserved for
+    // dynamically created threads.
+    process->registerExecContext(this);
+
+    mem = process->getMemory();
+
+    func_exe_insn = 0;
+    storeCondFailures = 0;
+}
+
+ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
+                         FunctionalMemory *_mem, int _asid)
+    : cpu(_cpu), thread_num(_thread_num), process(NULL), mem(_mem),
+      asid(_asid)
+{
+}
+#endif
+
+void
+ExecContext::setStatus(Status new_status)
+{
+#ifdef FULL_SYSTEM
+    if (status() == new_status)
+        return;
+
+    // Don't change the status from active if there are pending interrupts
+    if (new_status == Suspended && cpu->check_interrupts()) {
+        assert(status() == Active);
+        return;
+    }
+#endif
+
+    _status = new_status;
+    cpu->execCtxStatusChg();
+}
+
+void
+ExecContext::regStats(const string &name)
+{
+#ifdef FULL_SYSTEM
+    kernelStats.regStats(name + ".kern");
+#endif
+}
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
new file mode 100644 (file)
index 0000000..988673a
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __EXEC_CONTEXT_HH__
+#define __EXEC_CONTEXT_HH__
+
+#include "host.hh"
+#include "mem_req.hh"
+
+// forward declaration: see functional_memory.hh
+class FunctionalMemory;
+class PhysicalMemory;
+class BaseCPU;
+
+#ifdef FULL_SYSTEM
+
+#include "alpha_memory.hh"
+class MemoryController;
+
+#include "kernel_stats.hh"
+#include "system.hh"
+
+#else // !FULL_SYSTEM
+
+#include "prog.hh"
+
+#endif // FULL_SYSTEM
+
+//
+// The ExecContext object represents a functional context for
+// instruction execution.  It incorporates everything required for
+// architecture-level functional simulation of a single thread.
+//
+
+class ExecContext
+{
+  public:
+    enum Status { Unallocated, Active, Suspended, Halted };
+
+  private:
+    Status _status;
+
+  public:
+    Status status() const { return _status; }
+    void setStatus(Status new_status);
+
+#ifdef FULL_SYSTEM
+  public:
+    KernelStats kernelStats;
+#endif
+
+  public:
+    RegFile regs;      // correct-path register context
+
+    // pointer to CPU associated with this context
+    BaseCPU *cpu;
+
+    // Index of hardware thread context on the CPU that this represents.
+    int thread_num;
+
+#ifdef FULL_SYSTEM
+
+    FunctionalMemory *mem;
+    AlphaItb *itb;
+    AlphaDtb *dtb;
+    int cpu_id;
+    System *system;
+
+    // the following two fields are redundant, since we can always
+    // look them up through the system pointer, but we'll leave them
+    // here for now for convenience
+    MemoryController *memCtrl;
+    PhysicalMemory *physmem;
+
+#else
+    Process *process;
+
+    FunctionalMemory *mem;     // functional storage for process address space
+
+    // Address space ID.  Note that this is used for TIMING cache
+    // simulation only; all functional memory accesses should use
+    // one of the FunctionalMemory pointers above.
+    short asid;
+
+#endif
+
+
+    /*
+     * number of executed instructions, for matching with syscall trace
+     * points in EIO files.
+     */
+    Counter func_exe_insn;
+
+    //
+    // Count failed store conditionals so we can warn of apparent
+    // application deadlock situations.
+    unsigned storeCondFailures;
+
+    // constructor: initialize context from given process structure
+#ifdef FULL_SYSTEM
+    ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
+                AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_dem,
+                int _cpu_id);
+#else
+    ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
+    ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
+                int _asid);
+#endif
+    virtual ~ExecContext() {}
+
+    void regStats(const std::string &name);
+
+#ifdef FULL_SYSTEM
+    bool validInstAddr(Addr addr) { return true; }
+    bool validDataAddr(Addr addr) { return true; }
+    int getInstAsid() { return ITB_ASN_ASN(regs.ipr[TheISA::IPR_ITB_ASN]); }
+    int getDataAsid() { return DTB_ASN_ASN(regs.ipr[TheISA::IPR_DTB_ASN]); }
+
+    Fault translateInstReq(MemReqPtr req)
+    {
+        return itb->translate(req);
+    }
+
+    Fault translateDataReadReq(MemReqPtr req)
+    {
+        return dtb->translate(req, false);
+    }
+
+    Fault translateDataWriteReq(MemReqPtr req)
+    {
+        return dtb->translate(req, true);
+    }
+
+
+#else
+    bool validInstAddr(Addr addr)
+    { return process->validInstAddr(addr); }
+
+    bool validDataAddr(Addr addr)
+    { return process->validDataAddr(addr); }
+
+    int getInstAsid() { return asid; }
+    int getDataAsid() { return asid; }
+
+    Fault dummyTranslation(MemReqPtr req)
+    {
+#if 0
+        assert((req->vaddr >> 48 & 0xffff) == 0);
+#endif
+
+        // put the asid in the upper 16 bits of the paddr
+        req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
+        req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
+        return No_Fault;
+    }
+    Fault translateInstReq(MemReqPtr req)
+    {
+        return dummyTranslation(req);
+    }
+    Fault translateDataReadReq(MemReqPtr req)
+    {
+        return dummyTranslation(req);
+    }
+    Fault translateDataWriteReq(MemReqPtr req)
+    {
+        return dummyTranslation(req);
+    }
+
+#endif
+
+    template <class T>
+    Fault read(MemReqPtr req, T& data)
+    {
+#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
+        if (req->flags & LOCKED) {
+            MiscRegFile *cregs = &req->xc->regs.miscRegs;
+            cregs->lock_addr = req->paddr;
+            cregs->lock_flag = true;
+        }
+#endif
+        return mem->read(req, data);
+    }
+
+    template <class T>
+    Fault write(MemReqPtr req, T& data)
+    {
+#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
+
+        MiscRegFile *cregs;
+
+        // If this is a store conditional, act appropriately
+        if (req->flags & LOCKED) {
+            cregs = &req->xc->regs.miscRegs;
+
+            if (req->flags & UNCACHEABLE) {
+                // Don't update result register (see machine.def)
+                req->result = 2;
+                req->xc->storeCondFailures = 0;//Needed? [RGD]
+            } else {
+                req->result = cregs->lock_flag;
+                if (!cregs->lock_flag ||
+                    ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) {
+                    cregs->lock_flag = false;
+                    if (((++req->xc->storeCondFailures) % 100000) == 0) {
+                        std::cerr << "Warning: "
+                                  << req->xc->storeCondFailures
+                                  << " consecutive store conditional failures "
+                                  << "on cpu " << req->xc->cpu_id
+                                  << std::endl;
+                    }
+                    return No_Fault;
+                }
+                else req->xc->storeCondFailures = 0;
+            }
+        }
+
+        // Need to clear any locked flags on other proccessors for this
+        // address
+        // Only do this for succsful Store Conditionals and all other
+        // stores (WH64?)
+        // Unsuccesful Store Conditionals would have returned above,
+        // and wouldn't fall through
+        for(int i = 0; i < system->num_cpus; i++){
+            cregs = &system->xc_array[i]->regs.miscRegs;
+            if((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) {
+                cregs->lock_flag = false;
+            }
+        }
+
+#endif
+        return mem->write(req, data);
+    }
+
+    virtual bool misspeculating();
+
+
+    //
+    // New accessors for new decoder.
+    //
+    uint64_t readIntReg(int reg_idx)
+    {
+        return regs.intRegFile[reg_idx];
+    }
+
+    float readFloatRegSingle(int reg_idx)
+    {
+        return (float)regs.floatRegFile.d[reg_idx];
+    }
+
+    double readFloatRegDouble(int reg_idx)
+    {
+        return regs.floatRegFile.d[reg_idx];
+    }
+
+    uint64_t readFloatRegInt(int reg_idx)
+    {
+        return regs.floatRegFile.q[reg_idx];
+    }
+
+    void setIntReg(int reg_idx, uint64_t val)
+    {
+        regs.intRegFile[reg_idx] = val;
+    }
+
+    void setFloatRegSingle(int reg_idx, float val)
+    {
+        regs.floatRegFile.d[reg_idx] = (double)val;
+    }
+
+    void setFloatRegDouble(int reg_idx, double val)
+    {
+        regs.floatRegFile.d[reg_idx] = val;
+    }
+
+    void setFloatRegInt(int reg_idx, uint64_t val)
+    {
+        regs.floatRegFile.q[reg_idx] = val;
+    }
+
+    uint64_t readPC()
+    {
+        return regs.pc;
+    }
+
+    void setNextPC(uint64_t val)
+    {
+        regs.npc = val;
+    }
+
+    uint64_t readUniq()
+    {
+        return regs.miscRegs.uniq;
+    }
+
+    void setUniq(uint64_t val)
+    {
+        regs.miscRegs.uniq = val;
+    }
+
+    uint64_t readFpcr()
+    {
+        return regs.miscRegs.fpcr;
+    }
+
+    void setFpcr(uint64_t val)
+    {
+        regs.miscRegs.fpcr = val;
+    }
+
+#ifdef FULL_SYSTEM
+    uint64_t readIpr(int idx, Fault &fault);
+    Fault setIpr(int idx, uint64_t val);
+    Fault hwrei();
+    void ev5_trap(Fault fault);
+    bool simPalCheck(int palFunc);
+#endif
+
+#ifndef FULL_SYSTEM
+    void syscall()
+    {
+        process->syscall(this);
+    }
+#endif
+};
+
+
+// for non-speculative execution context, spec_mode is always false
+inline bool
+ExecContext::misspeculating()
+{
+    return false;
+}
+
+#endif // __EXEC_CONTEXT_HH__
diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc
new file mode 100644 (file)
index 0000000..4c5d148
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fstream>
+#include <iomanip>
+
+#include "dyn_inst.hh"
+#include "spec_state.hh"
+#include "issue.hh"
+#include "exetrace.hh"
+#include "exec_context.hh"
+#include "symtab.hh"
+#include "base_cpu.hh"
+#include "static_inst.hh"
+
+using namespace std;
+
+
+////////////////////////////////////////////////////////////////////////
+//
+//  Methods for the InstRecord object
+//
+
+
+const SymbolTable *debugSymbolTable = NULL;
+
+void
+Trace::InstRecord::dump(ostream &outs)
+{
+    if (flags[PRINT_CYCLE])
+        ccprintf(outs, "%7d: ", cycle);
+
+    outs << cpu->name() << " ";
+
+    if (flags[TRACE_MISSPEC])
+        outs << (misspeculating ? "-" : "+") << " ";
+
+    if (flags[PRINT_THREAD_NUM])
+        outs << "T" << thread << " : ";
+
+    outs << "0x" << hex << PC << " : ";
+
+    //
+    //  Print decoded instruction
+    //
+
+#if defined(__GNUC__) && (__GNUC__ < 3)
+    // There's a bug in gcc 2.x library that prevents setw()
+    // from working properly on strings
+    string mc(staticInst->disassemble(PC, debugSymbolTable));
+    while (mc.length() < 25)
+        mc += " ";
+    outs << mc;
+#else
+    outs << setw(25) << staticInst->disassemble(PC, debugSymbolTable);
+#endif
+
+    outs << " : ";
+
+    if (flags[PRINT_OP_CLASS]) {
+        outs << opClassStrings[staticInst->opClass()] << " : ";
+    }
+
+    if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
+        outs << " D=";
+#if 0
+        if (data_status == DataDouble)
+            ccprintf(outs, "%f", data.as_double);
+        else
+            ccprintf(outs, "%#018x", data.as_int);
+#else
+        ccprintf(outs, "%#018x", data.as_int);
+#endif
+    }
+
+    if (flags[PRINT_EFF_ADDR] && addr_valid)
+        outs << " A=0x" << hex << addr;
+
+    if (flags[PRINT_INT_REGS] && regs_valid) {
+        for (int i = 0; i < 32;)
+            for (int j = i + 1; i <= j; i++)
+                ccprintf(outs, "r%02d = %#018x%s", i, iregs->regs[i],
+                         ((i == j) ? "\n" : "    "));
+        outs << "\n";
+    }
+
+    if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
+        outs << "  FetchSeq=" << dec << fetch_seq;
+
+    if (flags[PRINT_CP_SEQ] && cp_seq_valid)
+        outs << "  CPSeq=" << dec << cp_seq;
+
+    //
+    //  End of line...
+    //
+    outs << endl;
+    outs.flush();
+}
+
+
+vector<bool> Trace::InstRecord::flags(NUM_BITS);
+
+////////////////////////////////////////////////////////////////////////
+//
+// Parameter space for per-cycle execution address tracing options.
+// Derive from ParamContext so we can override checkParams() function.
+//
+class ExecutionTraceParamContext : public ParamContext
+{
+  public:
+    ExecutionTraceParamContext(const string &_iniSection)
+        : ParamContext(_iniSection)
+        {
+        }
+
+    void checkParams();        // defined at bottom of file
+};
+
+ExecutionTraceParamContext exeTraceParams("exetrace");
+
+Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
+                           "capture speculative instructions", false);
+
+Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
+                                  "print cycle number", true);
+Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
+                                  "print op class", true);
+Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
+                                  "print thread number", true);
+Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
+                                  "print effective address", true);
+Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
+                                  "print result data", true);
+Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
+                                  "print all integer regs", false);
+Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
+                                  "print fetch sequence number", false);
+Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
+                                  "print correct-path sequence number", false);
+
+//
+// Helper function for ExecutionTraceParamContext::checkParams() just
+// to get us into the InstRecord namespace
+//
+void
+Trace::InstRecord::setParams()
+{
+    flags[TRACE_MISSPEC]     = exe_trace_spec;
+
+    flags[PRINT_CYCLE]       = exe_trace_print_cycle;
+    flags[PRINT_OP_CLASS]    = exe_trace_print_opclass;
+    flags[PRINT_THREAD_NUM]  = exe_trace_print_thread;
+    flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
+    flags[PRINT_EFF_ADDR]    = exe_trace_print_data;
+    flags[PRINT_INT_REGS]    = exe_trace_print_iregs;
+    flags[PRINT_FETCH_SEQ]   = exe_trace_print_fetchseq;
+    flags[PRINT_CP_SEQ]      = exe_trace_print_cp_seq;
+}
+
+void
+ExecutionTraceParamContext::checkParams()
+{
+    Trace::InstRecord::setParams();
+}
+
diff --git a/cpu/exetrace.hh b/cpu/exetrace.hh
new file mode 100644 (file)
index 0000000..2eb7753
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __EXETRACE_HH__
+#define __EXETRACE_HH__
+
+#include <fstream>
+#include <vector>
+
+#include "host.hh"
+#include "inst_seq.hh" // for InstSeqNum
+#include "trace.hh"
+#include "exec_context.hh"
+#include "static_inst.hh"
+
+class BaseCPU;
+
+
+namespace Trace {
+
+#if 0
+    static const FlagVec ALL =                 ULL(0x1);
+    static const FlagVec FULL =                        ULL(0x2);
+    static const FlagVec SYMBOLS =             ULL(0x4);
+    static const FlagVec EXTENDED =            ULL(0x8);
+    static const FlagVec BRANCH_TAKEN =        ULL(0x10);
+    static const FlagVec BRANCH_NOTTAKEN =     ULL(0x20);
+    static const FlagVec CALLPAL =             ULL(0x40);
+    static const FlagVec SPECULATIVE =         ULL(0x100);
+    static const FlagVec OMIT_COUNT =          ULL(0x200);
+    static const FlagVec INCLUDE_THREAD_NUM =  ULL(0x400);
+#endif
+
+class InstRecord : public Record
+{
+  protected:
+
+    // The following fields are initialized by the constructor and
+    // thus guaranteed to be valid.
+    BaseCPU *cpu;
+    // need to make this ref-counted so it doesn't go away before we
+    // dump the record
+    StaticInstPtr<TheISA> staticInst;
+    Addr PC;
+    bool misspeculating;
+    unsigned thread;
+
+    // The remaining fields are only valid for particular instruction
+    // types (e.g, addresses for memory ops) or when particular
+    // options are enabled (e.g., tracing full register contents).
+    // Each data field has an associated valid flag to indicate
+    // whether the data field is valid.
+    Addr addr;
+    bool addr_valid;
+
+    union {
+        uint64_t as_int;
+        double as_double;
+    } data;
+    enum {
+        DataInvalid = 0,
+        DataInt8 = 1,  // set to equal number of bytes
+        DataInt16 = 2,
+        DataInt32 = 4,
+        DataInt64 = 8,
+        DataDouble = 3
+    } data_status;
+
+    InstSeqNum fetch_seq;
+    bool fetch_seq_valid;
+
+    InstSeqNum cp_seq;
+    bool cp_seq_valid;
+
+    struct iRegFile {
+        IntRegFile regs;
+    };
+    iRegFile *iregs;
+    bool regs_valid;
+
+  public:
+    InstRecord(Tick _cycle, BaseCPU *_cpu, StaticInstPtr<TheISA> _staticInst,
+               Addr _pc, bool spec, unsigned _thread)
+        : Record(_cycle), cpu(_cpu), staticInst(_staticInst), PC(_pc),
+          misspeculating(spec), thread(_thread)
+    {
+        data_status = DataInvalid;
+        addr_valid = false;
+        regs_valid = false;
+
+        fetch_seq_valid = false;
+        cp_seq_valid = false;
+    }
+
+    virtual ~InstRecord() { }
+
+    virtual void dump(std::ostream &outs);
+
+    void setAddr(Addr a) { addr = a; addr_valid = true; }
+
+    void setData(uint64_t d) { data.as_int = d; data_status = DataInt64; }
+    void setData(uint32_t d) { data.as_int = d; data_status = DataInt32; }
+    void setData(uint16_t d) { data.as_int = d; data_status = DataInt16; }
+    void setData(uint8_t d) { data.as_int = d; data_status = DataInt8; }
+
+    void setData(int64_t d) { setData((uint64_t)d); }
+    void setData(int32_t d) { setData((uint32_t)d); }
+    void setData(int16_t d) { setData((uint16_t)d); }
+    void setData(int8_t d)  { setData((uint8_t)d); }
+
+    void setData(double d) { data.as_double = d; data_status = DataDouble; }
+
+    void setFetchSeq(InstSeqNum seq)
+    { fetch_seq = seq; fetch_seq_valid = true; }
+
+    void setCPSeq(InstSeqNum seq)
+    { cp_seq = seq; cp_seq_valid = true; }
+
+    void setRegs(const IntRegFile &regs);
+
+    void finalize() { theLog.append(this); }
+
+    enum InstExecFlagBits {
+        TRACE_MISSPEC = 0,
+        PRINT_CYCLE,
+        PRINT_OP_CLASS,
+        PRINT_THREAD_NUM,
+        PRINT_RESULT_DATA,
+        PRINT_EFF_ADDR,
+        PRINT_INT_REGS,
+        PRINT_FETCH_SEQ,
+        PRINT_CP_SEQ,
+        NUM_BITS
+    };
+
+    static std::vector<bool> flags;
+
+    static void setParams();
+
+    static bool traceMisspec() { return flags[TRACE_MISSPEC]; }
+};
+
+
+inline void
+InstRecord::setRegs(const IntRegFile &regs)
+{
+    if (!iregs)
+      iregs = new iRegFile;
+
+    memcpy(&iregs->regs, regs, sizeof(IntRegFile));
+    regs_valid = true;
+}
+
+inline
+InstRecord *
+getInstRecord(Tick cycle, ExecContext *xc, BaseCPU *cpu,
+              const StaticInstPtr<TheISA> staticInst,
+              Addr pc, int thread = 0)
+{
+    if (DTRACE(InstExec) &&
+        (InstRecord::traceMisspec() || !xc->misspeculating())) {
+        return new InstRecord(cycle, cpu, staticInst, pc,
+                              xc->misspeculating(), thread);
+    }
+
+    return NULL;
+}
+
+
+}
+
+#endif // __EXETRACE_HH__
diff --git a/cpu/full_cpu/op_class.hh b/cpu/full_cpu/op_class.hh
new file mode 100644 (file)
index 0000000..67ccaab
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __OP_CLASS_HH__
+#define __OP_CLASS_HH__
+
+/**
+ * @file
+ * Definition of operation classes.
+ */
+
+/**
+ * Instruction operation classes.  These classes are used for
+ * assigning instructions to functional units.
+ */
+enum OpClass {
+    No_OpClass = 0,    /* inst does not use a functional unit */
+    IntALU,            /* integer ALU */
+    IntMULT,           /* integer multiplier */
+    IntDIV,            /* integer divider */
+    FloatADD,          /* floating point adder/subtractor */
+    FloatCMP,          /* floating point comparator */
+    FloatCVT,          /* floating point<->integer converter */
+    FloatMULT,         /* floating point multiplier */
+    FloatDIV,          /* floating point divider */
+    FloatSQRT,         /* floating point square root */
+    RdPort,            /* memory read port */
+    WrPort,            /* memory write port */
+    LvqPort,           /* load value queue read port (redundant threading) */
+    IPrefPort,
+    Num_OpClasses      /* total functional unit classes */
+};
+
+/**
+ * Array mapping OpClass enum values to strings.
+ */
+extern const char *opClassStrings[];
+
+#endif // __OP_CLASS_HH__
diff --git a/cpu/full_cpu/smt.hh b/cpu/full_cpu/smt.hh
new file mode 100644 (file)
index 0000000..f9c1e46
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * Defines SMT_MAX_CPUS and SMT_MAX_THREADS.
+ */
+
+#ifndef __SMT_HH__
+#define __SMT_HH__
+
+#ifndef SMT_MAX_CPUS
+/** The maximum number of cpus in any one system. */
+#define SMT_MAX_CPUS 4
+#endif
+
+#ifndef SMT_MAX_THREADS
+/** The number of TPUs in any processor. */
+#define SMT_MAX_THREADS 4
+#endif
+
+/**
+ * The maximum number of active threads across all cpus. Used to
+ * initialize per-thread statistics in the cache.
+ *
+ * NB: Be careful to only use it once all the CPUs that you care about
+ *     have been initialized
+ */
+extern int maxThreadsPerCPU;
+
+/**
+ * Changes the status and priority of the thread with the given number.
+ * @param thread_number The thread to change.
+ * @param activate The new active status.
+ * @param priority The new priority.
+ */
+void change_thread_state(int thread_number, int activate, int priority);
+
+#endif // __SMT_HH__
diff --git a/cpu/inst_seq.hh b/cpu/inst_seq.hh
new file mode 100644 (file)
index 0000000..9c3898f
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __STD_TYPES_HH__
+#define __STD_TYPES_HH__
+
+// inst sequence type, used to order instructions in the ready list,
+// if this rolls over the ready list order temporarily will get messed
+// up, but execution will continue and complete correctly
+typedef unsigned long long InstSeqNum;
+
+// inst tag type, used to tag an operation instance in the IQ
+typedef unsigned int InstTag;
+
+#endif // __STD_TYPES_HH__
diff --git a/cpu/intr_control.cc b/cpu/intr_control.cc
new file mode 100644 (file)
index 0000000..7ad32a2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+#include <vector>
+
+#include "base_cpu.hh"
+#include "intr_control.hh"
+#include "sim_object.hh"
+
+using namespace std;
+
+IntrControl::IntrControl(const string &name, BaseCPU *c)
+    : SimObject(name), cpu(c)
+{}
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
+
+    SimObjectParam<BaseCPU *> cpu;
+
+END_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(IntrControl)
+
+    INIT_PARAM(cpu, "the processor")
+
+END_INIT_SIM_OBJECT_PARAMS(IntrControl)
+
+CREATE_SIM_OBJECT(IntrControl)
+{
+    return new IntrControl(getInstanceName(), cpu);
+}
+
+REGISTER_SIM_OBJECT("IntrControl", IntrControl)
diff --git a/cpu/intr_control.hh b/cpu/intr_control.hh
new file mode 100644 (file)
index 0000000..660d6d7
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INTR_CONTROL_HH__
+#define __INTR_CONTROL_HH__
+
+#include "misc.hh"
+#include "base_cpu.hh"
+#include "sim_object.hh"
+
+class IntrControl : public SimObject
+{
+  public:
+    BaseCPU *cpu;
+    IntrControl(const std::string &name, BaseCPU *c);
+
+    void clear(int int_num, int index = 0);
+    void post(int int_num, int index = 0);
+};
+
+inline void
+IntrControl::post(int int_num, int index)
+{ cpu->post_interrupt(int_num, index); }
+
+inline void
+IntrControl::clear(int int_num, int index)
+{ cpu->clear_interrupt(int_num, index); }
+
+#endif // __INTR_CONTROL_HH__
+
+
+
+
+
+
+
diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc
new file mode 100644 (file)
index 0000000..70b6fbf
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded
+
+#include <string>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+
+#include "memtest.hh"
+#include "misc.hh"
+#include "sim_events.hh"
+#include "main_memory.hh"
+#include "base_cache.hh"
+
+#include "statistics.hh"
+#include "sim_stats.hh"
+
+using namespace std;
+
+MemTest::MemTest(const string &name,
+                 MemInterface *_cache_interface,
+                 FunctionalMemory *main_mem,
+                 FunctionalMemory *check_mem,
+                 unsigned _memorySize,
+                 unsigned _percentReads,
+                 unsigned _percentUncacheable,
+                 unsigned _maxReads,
+                 unsigned _progressInterval,
+                 Addr _traceAddr)
+    : BaseCPU(name, 1),
+      tickEvent(this),
+      cacheInterface(_cache_interface),
+      mainMem(main_mem),
+      checkMem(check_mem),
+      size(_memorySize),
+      percentReads(_percentReads),
+      percentUncacheable(_percentUncacheable),
+      maxReads(_maxReads),
+      progressInterval(_progressInterval),
+      nextProgressMessage(_progressInterval)
+{
+    vector<string> cmd;
+    cmd.push_back("/bin/ls");
+    vector<string> null_vec;
+    xc = new ExecContext(this ,0,mainMem,0);
+
+    blockSize = cacheInterface->getBlockSize();
+    blockAddrMask = blockSize - 1;
+    traceBlockAddr = blockAddr(_traceAddr);
+
+    //setup data storage with interesting values
+    uint8_t *data1 = new uint8_t[size];
+    uint8_t *data2 = new uint8_t[size];
+    uint8_t *data3 = new uint8_t[size];
+    memset(data1, 1, size);
+    memset(data2, 2, size);
+    memset(data3, 3, size);
+    curTick = 0;
+
+    baseAddr1 = 0x100000;
+    baseAddr2 = 0x400000;
+    uncacheAddr = 0x800000;
+
+    // set up intial memory contents here
+    mainMem->prot_write(baseAddr1, data1, size);
+    checkMem->prot_write(baseAddr1, data1, size);
+    mainMem->prot_write(baseAddr2, data2, size);
+    checkMem->prot_write(baseAddr2, data2, size);
+    mainMem->prot_write(uncacheAddr, data3, size);
+    checkMem->prot_write(uncacheAddr, data3, size);
+
+    delete [] data1;
+    delete [] data2;
+    delete [] data3;
+
+    // set up counters
+    noResponseCycles = 0;
+    numReads = 0;
+    numWrites = 0;
+    tickEvent.schedule(0);
+}
+
+static void
+printData(ostream &os, uint8_t *data, int nbytes)
+{
+    os << hex << setfill('0');
+    // assume little-endian: print bytes from highest address to lowest
+    for (uint8_t *dp = data + nbytes - 1; dp >= data; --dp) {
+        os << setw(2) << (unsigned)*dp;
+    }
+    os << dec;
+}
+
+void
+MemTest::completeRequest(MemReqPtr req, uint8_t *data)
+{
+    switch (req->cmd) {
+      case Read:
+        if (memcmp(req->data, data, req->size) != 0) {
+            cerr << name() << ": on read of 0x" << hex << req->paddr
+                 << " @ cycle " << dec << curTick
+                 << ", cache returns 0x";
+            printData(cerr, req->data, req->size);
+            cerr << ", expected 0x";
+            printData(cerr, data, req->size);
+            cerr << endl;
+            fatal("");
+        }
+
+        numReads++;
+
+        if (numReads.val() == nextProgressMessage) {
+            cerr << name() << ": completed " << numReads.val()
+                 << " read accesses @ " << curTick << endl;
+            nextProgressMessage += progressInterval;
+        }
+
+        if (numReads.val() == maxReads) {
+            stringstream stream;
+            stream << name() << " reached max read count (" << maxReads
+                   << ")" << endl;
+
+            new SimExitEvent(stream.str());
+        }
+        break;
+
+      case Write:
+        numWrites++;
+        break;
+
+
+      default:
+        panic("invalid command");
+    }
+
+    if (blockAddr(req->paddr) == traceBlockAddr) {
+        cerr << name() << ": completed "
+             << (req->cmd.isWrite() ? "write" : "read") << " access of "
+             << req->size << " bytes at address 0x"
+             << hex << req->paddr << ", value = 0x";
+        printData(cerr, req->data, req->size);
+        cerr << endl;
+    }
+
+    noResponseCycles = 0;
+    delete [] data;
+}
+
+
+void
+MemTest::regStats()
+{
+    using namespace Statistics;
+
+    numReads
+        .name(name() + ".num_reads")
+        .desc("number of read accesses completed")
+        ;
+
+    numWrites
+        .name(name() + ".num_writes")
+        .desc("number of write accesses completed")
+        ;
+
+    numCopies
+        .name(name() + ".num_copies")
+        .desc("number of copy accesses completed")
+        ;
+}
+
+void
+MemTest::tick()
+{
+    if (!tickEvent.scheduled())
+        tickEvent.schedule(curTick + 1);
+
+    if (++noResponseCycles >= 5000) {
+        cerr << name() << ": deadlocked at cycle " << curTick << endl;
+        fatal("");
+    }
+
+    if (cacheInterface->isBlocked()) {
+        return;
+    }
+
+    //make new request
+    unsigned cmd = rand() % 100;
+    unsigned offset1 = random() % size;
+    unsigned base = random() % 2;
+    uint64_t data = random();
+    unsigned access_size = random() % 4;
+    unsigned cacheable = rand() % 100;
+
+    MemReqPtr req = new MemReq();
+
+    if (cacheable < percentUncacheable) {
+        req->flags |= UNCACHEABLE;
+        req->paddr = uncacheAddr + offset1;
+    } else {
+        req->paddr = ((base) ? baseAddr1 : baseAddr2) + offset1;
+    }
+
+    req->size = 1 << access_size;
+    req->data = new uint8_t[req->size];
+    req->paddr &= ~(req->size - 1);
+    req->time = curTick;
+    req->xc = xc;
+
+    if (cmd < percentReads) {
+        // read
+        req->cmd = Read;
+        uint8_t *result = new uint8_t[8];
+        checkMem->access(Read, req->paddr, result, req->size);
+        if (blockAddr(req->paddr) == traceBlockAddr) {
+            cerr << name() << ": initiating read of "
+                 << req->size << " bytes from addr 0x"
+                 << hex << req->paddr << " at cycle "
+                 << dec << curTick << endl;
+        }
+
+        req->completionEvent = new MemCompleteEvent(req, result, this);
+        cacheInterface->access(req);
+    } else {
+        // write
+        req->cmd = Write;
+        memcpy(req->data, &data, req->size);
+        checkMem->access(Write, req->paddr, req->data, req->size);
+        if (blockAddr(req->paddr) == traceBlockAddr) {
+            cerr << name() << ": initiating write of "
+                 << req->size << " bytes (value = 0x";
+            printData(cerr, req->data, req->size);
+            cerr << ") to addr 0x"
+                 << hex << req->paddr << " at cycle "
+                 << dec << curTick << endl;
+        }
+        req->completionEvent = new MemCompleteEvent(req, NULL, this);
+        cacheInterface->access(req);
+    }
+}
+
+
+void
+MemCompleteEvent::process()
+{
+    tester->completeRequest(req, data);
+    delete this;
+}
+
+
+const char *
+MemCompleteEvent::description()
+{
+    return "memory access completion";
+}
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
+
+    SimObjectParam<BaseCache *> cache;
+    SimObjectParam<FunctionalMemory *> main_mem;
+    SimObjectParam<FunctionalMemory *> check_mem;
+    Param<unsigned> memory_size;
+    Param<unsigned> percent_reads;
+    Param<unsigned> percent_uncacheable;
+    Param<unsigned> max_reads;
+    Param<unsigned> progress_interval;
+    Param<Addr> trace_addr;
+
+END_DECLARE_SIM_OBJECT_PARAMS(MemTest)
+
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest)
+
+    INIT_PARAM(cache, "L1 cache"),
+    INIT_PARAM(main_mem, "hierarchical memory"),
+    INIT_PARAM(check_mem, "check memory"),
+    INIT_PARAM_DFLT(memory_size, "memory size", 65536),
+    INIT_PARAM_DFLT(percent_reads, "target read percentage", 65),
+    INIT_PARAM_DFLT(percent_uncacheable, "target uncacheable percentage", 10),
+    INIT_PARAM_DFLT(max_reads, "number of reads to simulate", 0),
+    INIT_PARAM_DFLT(progress_interval,
+                    "progress report interval (in accesses)", 1000000),
+    INIT_PARAM_DFLT(trace_addr, "address to trace", 0)
+
+END_INIT_SIM_OBJECT_PARAMS(MemTest)
+
+
+CREATE_SIM_OBJECT(MemTest)
+{
+    return new MemTest(getInstanceName(), cache->getInterface(), main_mem,
+                       check_mem,
+                       memory_size, percent_reads,
+                       percent_uncacheable, max_reads, progress_interval,
+                       trace_addr);
+}
+
+REGISTER_SIM_OBJECT("MemTest", MemTest)
diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh
new file mode 100644 (file)
index 0000000..aa652ab
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MEMTEST_HH__
+#define __MEMTEST_HH__
+
+#include "sim_object.hh"
+#include "mem_interface.hh"
+#include "functional_memory.hh"
+#include "base_cpu.hh"
+#include "exec_context.hh"
+
+#include "statistics.hh"
+#include "sim_stats.hh"
+
+class MemTest : public BaseCPU
+{
+  public:
+
+    MemTest(const std::string &name,
+            MemInterface *_cache_interface,
+            FunctionalMemory *main_mem,
+            FunctionalMemory *check_mem,
+            unsigned _memorySize,
+            unsigned _percentReads,
+            unsigned _percentUncacheable,
+            unsigned _maxReads,
+            unsigned _progressInterval,
+            Addr _traceAddr);
+
+    // register statistics
+    virtual void regStats();
+    // main simulation loop (one cycle)
+    void tick();
+
+  protected:
+    class TickEvent : public Event
+    {
+      private:
+        MemTest *cpu;
+      public:
+        TickEvent(MemTest *c)
+            : Event(&mainEventQueue, 100), cpu(c) {}
+        void process() {cpu->tick();}
+        virtual const char *description() { return "tick event"; }
+    };
+
+    TickEvent tickEvent;
+
+    MemInterface *cacheInterface;
+    FunctionalMemory *mainMem;
+    FunctionalMemory *checkMem;
+    ExecContext *xc;
+
+    unsigned size;             // size of testing memory region
+
+    unsigned percentReads;     // target percentage of read accesses
+    unsigned percentUncacheable;
+
+    Tick maxReads;             // max # of reads to perform (then quit)
+
+    unsigned blockSize;
+
+    Addr blockAddrMask;
+
+    Addr blockAddr(Addr addr)
+    {
+        return (addr & ~blockAddrMask);
+    }
+
+    Addr traceBlockAddr;
+
+    Addr baseAddr1;            // fix this to option
+    Addr baseAddr2;            // fix this to option
+    Addr uncacheAddr;
+
+    unsigned progressInterval; // frequency of progress reports
+    Tick nextProgressMessage;  // access # for next progress report
+
+    Tick noResponseCycles;
+
+    Statistics::Scalar<long long int> numReads;
+    Statistics::Scalar<long long int> numWrites;
+    Statistics::Scalar<long long int> numCopies;
+
+    // called by MemCompleteEvent::process()
+    void completeRequest(MemReqPtr req, uint8_t *data);
+
+    friend class MemCompleteEvent;
+};
+
+
+class MemCompleteEvent : public Event
+{
+    MemReqPtr req;
+    uint8_t *data;
+    MemTest *tester;
+
+  public:
+
+    MemCompleteEvent(MemReqPtr _req, uint8_t *_data, MemTest *_tester)
+        : Event(&mainEventQueue),
+          req(_req), data(_data), tester(_tester)
+    {
+    }
+
+    void process();
+
+    virtual const char *description();
+};
+
+#endif // __MEMTEST_HH__
+
+
+
diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc
new file mode 100644 (file)
index 0000000..4de4251
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <algorithm>
+#include <map>
+#include <string>
+#include <utility>
+
+#include "debug.hh"
+#include "exec_context.hh"
+#include "pc_event.hh"
+#include "trace.hh"
+#include "universe.hh"
+
+#ifdef FULL_SYSTEM
+#include "arguments.hh"
+#include "pmap.h"
+#include "kernel.hh"
+#include "memory_control.hh"
+#include "cpu.hh"
+#include "system.hh"
+#include "bpred.hh"
+#endif
+
+using namespace std;
+
+PCEventQueue::PCEventQueue()
+{}
+
+PCEventQueue::~PCEventQueue()
+{}
+
+bool
+PCEventQueue::remove(PCEvent *event)
+{
+    int removed = 0;
+    range_t range = equal_range(event);
+    for (iterator i = range.first; i != range.second; ++i) {
+        if (*i == event) {
+            DPRINTF(PCEvent, "PC based event removed at %#x: %s\n",
+                    event->pc(), event->descr());
+            pc_map.erase(i);
+            ++removed;
+        }
+    }
+
+    return removed > 0;
+}
+
+bool
+PCEventQueue::schedule(PCEvent *event)
+{
+    pc_map.push_back(event);
+    sort(pc_map.begin(), pc_map.end(), MapCompare());
+
+    DPRINTF(PCEvent, "PC based event scheduled for %#x: %s\n",
+            event->pc(), event->descr());
+
+    return true;
+}
+
+bool
+PCEventQueue::service(ExecContext *xc)
+{
+    Addr pc = xc->regs.pc;
+    int serviced = 0;
+    range_t range = equal_range(pc);
+    for (iterator i = range.first; i != range.second; ++i) {
+        // Make sure that the pc wasn't changed as the side effect of
+        // another event.  This for example, prevents two invocations
+        // of the SkipFuncEvent.  Maybe we should have separate PC
+        // event queues for each processor?
+        if (pc != xc->regs.pc)
+            continue;
+
+        DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n",
+                (*i)->pc(), (*i)->descr());
+
+        (*i)->process(xc);
+        ++serviced;
+    }
+
+    return serviced > 0;
+}
+
+void
+PCEventQueue::dump() const
+{
+    const_iterator i = pc_map.begin();
+    const_iterator e = pc_map.end();
+
+    for (; i != e; ++i)
+        cprintf("%d: event at %#x: %s\n", curTick, (*i)->pc(),
+                (*i)->descr());
+}
+
+PCEventQueue::range_t
+PCEventQueue::equal_range(Addr pc)
+{
+    return std::equal_range(pc_map.begin(), pc_map.end(), pc, MapCompare());
+}
+
+#ifdef FULL_SYSTEM
+void
+SkipFuncEvent::process(ExecContext *xc)
+{
+    Addr newpc = xc->regs.intRegFile[ReturnAddressReg];
+
+    DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description,
+            xc->regs.pc, newpc);
+
+    xc->regs.pc = newpc;
+    xc->regs.npc = xc->regs.pc + sizeof(MachInst);
+
+    BranchPred *bp = xc->cpu->getBranchPred();
+    if (bp != NULL) {
+        bp->popRAS(xc->thread_num);
+    }
+}
+
+void
+BadAddrEvent::process(ExecContext *xc)
+{
+    // The following gross hack is the equivalent function to the
+    // annotation for vmunix::badaddr in:
+    // simos/simulation/apps/tcl/osf/tlaser.tcl
+
+    uint64_t a0 = xc->regs.intRegFile[ArgumentReg0];
+
+    if (a0 < ALPHA_K0SEG_BASE || a0 >= ALPHA_K1SEG_BASE ||
+        xc->memCtrl->badaddr(ALPHA_K0SEG_TO_PHYS(a0) & PA_IMPL_MASK)) {
+
+        DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0);
+        xc->regs.intRegFile[ReturnValueReg] = 0x1;
+        SkipFuncEvent::process(xc);
+    }
+    else
+        DPRINTF(BADADDR, "badaddr arg=%#x good\n", a0);
+}
+
+void
+PrintfEvent::process(ExecContext *xc)
+{
+    if (DTRACE(Printf)) {
+        DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
+
+        AlphaArguments args(xc);
+        Kernel::Printf(args);
+    }
+}
+
+void
+DebugPrintfEvent::process(ExecContext *xc)
+{
+    if (DTRACE(DebugPrintf)) {
+        if (!raw)
+            DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
+
+        AlphaArguments args(xc);
+        Kernel::Printf(args);
+    }
+}
+
+void
+DumpMbufEvent::process(ExecContext *xc)
+{
+    if (DTRACE(DebugPrintf)) {
+        AlphaArguments args(xc);
+        Kernel::DumpMbuf(args);
+    }
+}
+#endif
+
+BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del)
+    : PCEvent(q, desc), remove(del)
+{
+}
+
+void
+BreakPCEvent::process(ExecContext *xc)
+{
+    debug_break();
+    if (remove)
+        delete this;
+}
+
+#ifdef FULL_SYSTEM
+extern "C"
+void
+sched_break_pc_sys(System *sys, Addr addr)
+{
+    PCEvent *event = new BreakPCEvent(&sys->pcEventQueue, "debug break", true);
+    event->schedule(addr);
+}
+
+extern "C"
+void
+sched_break_pc(Addr addr)
+{
+     for (vector<System *>::iterator sysi = System::systemList.begin();
+          sysi != System::systemList.end(); ++sysi) {
+         sched_break_pc_sys(*sysi, addr);
+    }
+
+}
+#endif
diff --git a/cpu/pc_event.hh b/cpu/pc_event.hh
new file mode 100644 (file)
index 0000000..24442f5
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PC_EVENT_HH__
+#define __PC_EVENT_HH__
+
+#include <vector>
+
+#include "mem_req.hh"
+
+class ExecContext;
+class PCEventQueue;
+
+class PCEvent
+{
+  protected:
+    static const Addr badpc = MemReq::inval_addr;
+
+  protected:
+    std::string description;
+    PCEventQueue *queue;
+    Addr evpc;
+
+  public:
+    PCEvent() : queue(0), evpc(badpc) { }
+
+    PCEvent(const std::string &desc)
+        : description(desc), queue(0), evpc(badpc) { }
+
+    PCEvent(PCEventQueue *q, Addr pc = badpc) : queue(q), evpc(pc) { }
+
+    PCEvent(PCEventQueue *q, const std::string &desc, Addr pc = badpc)
+        : description(desc), queue(q), evpc(pc) { }
+
+    virtual ~PCEvent() { if (queue) remove(); }
+
+    std::string descr() const { return description; }
+    Addr pc() const { return evpc; }
+
+    bool remove();
+    bool schedule();
+    bool schedule(Addr pc);
+    bool schedule(PCEventQueue *q, Addr pc);
+    virtual void process(ExecContext *xc) = 0;
+};
+
+class PCEventQueue
+{
+  protected:
+    typedef PCEvent * record_t;
+    class MapCompare {
+      public:
+        bool operator()(const record_t &l, const record_t &r) const {
+            return l->pc() < r->pc();
+        }
+        bool operator()(const record_t &l, Addr pc) const {
+            return l->pc() < pc;
+        }
+        bool operator()(Addr pc, const record_t &r) const {
+            return pc < r->pc();
+        }
+    };
+    typedef std::vector<record_t> map_t;
+
+  public:
+    typedef map_t::iterator iterator;
+    typedef map_t::const_iterator const_iterator;
+
+  protected:
+    typedef std::pair<iterator, iterator> range_t;
+    typedef std::pair<const_iterator, const_iterator> const_range_t;
+
+  protected:
+    map_t pc_map;
+
+  public:
+    PCEventQueue();
+    ~PCEventQueue();
+
+    bool remove(PCEvent *event);
+    bool schedule(PCEvent *event);
+    bool service(ExecContext *xc);
+
+    range_t equal_range(Addr pc);
+    range_t equal_range(PCEvent *event) { return equal_range(event->pc()); }
+
+    void dump() const;
+};
+
+inline bool
+PCEvent::remove()
+{
+    if (!queue)
+        panic("cannot remove an uninitialized event;");
+
+    return queue->remove(this);
+}
+
+inline bool
+PCEvent::schedule()
+{
+    if (!queue || evpc == badpc)
+        panic("cannot schedule an uninitialized event;");
+
+    return queue->schedule(this);
+}
+
+inline bool
+PCEvent::schedule(Addr pc)
+{
+    if (evpc != badpc)
+        panic("cannot switch PC");
+    evpc = pc;
+
+    return schedule();
+}
+
+inline bool
+PCEvent::schedule(PCEventQueue *q, Addr pc)
+{
+    if (queue)
+        panic("cannot switch event queues");
+
+    if (evpc != badpc)
+        panic("cannot switch addresses");
+
+    queue = q;
+    evpc = pc;
+
+    return schedule();
+}
+
+
+#ifdef FULL_SYSTEM
+class SkipFuncEvent : public PCEvent
+{
+  public:
+    SkipFuncEvent(PCEventQueue *q, const std::string &desc)
+        : PCEvent(q, desc) {}
+    virtual void process(ExecContext *xc);
+};
+
+class BadAddrEvent : public SkipFuncEvent
+{
+  public:
+    BadAddrEvent(PCEventQueue *q, const std::string &desc)
+        : SkipFuncEvent(q, desc) {}
+    virtual void process(ExecContext *xc);
+};
+
+class PrintfEvent : public PCEvent
+{
+  public:
+    PrintfEvent(PCEventQueue *q, const std::string &desc)
+        : PCEvent(q, desc) {}
+    virtual void process(ExecContext *xc);
+};
+
+class DebugPrintfEvent : public PCEvent
+{
+  private:
+    bool raw;
+
+  public:
+    DebugPrintfEvent(PCEventQueue *q, const std::string &desc, bool r = false)
+        : PCEvent(q, desc), raw(r) {}
+    virtual void process(ExecContext *xc);
+};
+
+class DumpMbufEvent : public PCEvent
+{
+  public:
+    DumpMbufEvent(PCEventQueue *q, const std::string &desc)
+        : PCEvent(q, desc) {}
+    virtual void process(ExecContext *xc);
+};
+#endif
+
+class BreakPCEvent : public PCEvent
+{
+  protected:
+    bool remove;
+
+  public:
+    BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del = false);
+    virtual void process(ExecContext *xc);
+};
+
+
+#endif // __PC_EVENT_HH__
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
new file mode 100644 (file)
index 0000000..41a6123
--- /dev/null
@@ -0,0 +1,746 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <iostream>
+#include <iomanip>
+#include <list>
+#include <sstream>
+#include <string>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "host.hh"
+#include "cprintf.hh"
+#include "misc.hh"
+#include "smt.hh"
+
+#include "annotation.hh"
+#include "exec_context.hh"
+#include "base_cpu.hh"
+#include "debug.hh"
+#include "simple_cpu.hh"
+#include "inifile.hh"
+#include "mem_interface.hh"
+#include "base_mem.hh"
+#include "static_inst.hh"
+
+#ifdef FULL_SYSTEM
+#include "memory_control.hh"
+#include "physical_memory.hh"
+#include "alpha_memory.hh"
+#include "system.hh"
+#else // !FULL_SYSTEM
+#include "functional_memory.hh"
+#include "prog.hh"
+#include "eio.hh"
+#endif // FULL_SYSTEM
+
+#include "exetrace.hh"
+#include "trace.hh"
+#include "sim_events.hh"
+#include "pollevent.hh"
+#include "sim_object.hh"
+#include "sim_stats.hh"
+
+#include "range.hh"
+#include "symtab.hh"
+
+#ifdef FULL_SYSTEM
+#include "vtophys.hh"
+#include "pciareg.h"
+#include "remote_gdb.hh"
+#include "alpha_access.h"
+#endif
+
+
+using namespace std;
+
+SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
+    : Event(&mainEventQueue),
+      cpu(_cpu)
+{
+}
+
+void SimpleCPU::CacheCompletionEvent::process()
+{
+    cpu->processCacheCompletion();
+}
+
+const char *
+SimpleCPU::CacheCompletionEvent::description()
+{
+    return "cache completion event";
+}
+
+#ifdef FULL_SYSTEM
+SimpleCPU::SimpleCPU(const string &_name,
+                     System *_system,
+                     Counter max_insts_any_thread,
+                     Counter max_insts_all_threads,
+                     AlphaItb *itb, AlphaDtb *dtb,
+                     FunctionalMemory *mem,
+                     MemInterface *icache_interface,
+                     MemInterface *dcache_interface,
+                     int cpu_id, Tick freq)
+    : BaseCPU(_name, /* number_of_threads */ 1,
+              max_insts_any_thread, max_insts_all_threads,
+              _system, cpu_id, freq),
+#else
+SimpleCPU::SimpleCPU(const string &_name, Process *_process,
+                     Counter max_insts_any_thread,
+                     Counter max_insts_all_threads,
+                     MemInterface *icache_interface,
+                     MemInterface *dcache_interface)
+    : BaseCPU(_name, /* number_of_threads */ 1,
+              max_insts_any_thread, max_insts_all_threads),
+#endif
+      tickEvent(this), xc(NULL), cacheCompletionEvent(this)
+{
+#ifdef FULL_SYSTEM
+    xc = new ExecContext(this, 0, system, itb, dtb, mem, cpu_id);
+
+    _status = Running;
+    if (cpu_id != 0) {
+
+       xc->setStatus(ExecContext::Unallocated);
+
+       //Open a GDB debug session on port (7000 + the cpu_id)
+       (new GDBListener(new RemoteGDB(system, xc), 7000 + cpu_id))->listen();
+
+       AlphaISA::init(system->physmem, &xc->regs);
+
+       fault = Reset_Fault;
+
+       IntReg *ipr = xc->regs.ipr;
+       ipr[TheISA::IPR_MCSR] = 0x6;
+
+       AlphaISA::swap_palshadow(&xc->regs, true);
+
+       xc->regs.pc =
+           ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault];
+       xc->regs.npc = xc->regs.pc + sizeof(MachInst);
+
+       _status = Idle;
+    }
+    else {
+      system->initBootContext(xc);
+
+      // Reset the system
+      //
+      AlphaISA::init(system->physmem, &xc->regs);
+
+      fault = Reset_Fault;
+
+      IntReg *ipr = xc->regs.ipr;
+      ipr[TheISA::IPR_MCSR] = 0x6;
+
+      AlphaISA::swap_palshadow(&xc->regs, true);
+
+      xc->regs.pc = ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault];
+      xc->regs.npc = xc->regs.pc + sizeof(MachInst);
+
+       _status = Running;
+       tickEvent.schedule(0);
+    }
+
+#else
+    xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0);
+    fault = No_Fault;
+    if (xc->status() == ExecContext::Active) {
+        _status = Running;
+       tickEvent.schedule(0);
+    } else
+        _status = Idle;
+#endif // !FULL_SYSTEM
+
+    icacheInterface = icache_interface;
+    dcacheInterface = dcache_interface;
+
+    memReq = new MemReq();
+    memReq->xc = xc;
+    memReq->asid = 0;
+
+    numInst = 0;
+    last_idle = 0;
+    lastIcacheStall = 0;
+    lastDcacheStall = 0;
+
+    contexts.push_back(xc);
+}
+
+SimpleCPU::~SimpleCPU()
+{
+}
+
+void
+SimpleCPU::regStats()
+{
+    BaseCPU::regStats();
+
+    numInsts
+        .name(name() + ".num_insts")
+        .desc("Number of instructions executed")
+        ;
+
+    numMemRefs
+        .name(name() + ".num_refs")
+        .desc("Number of memory references")
+        ;
+
+    idleCycles
+        .name(name() + ".idle_cycles")
+        .desc("Number of idle cycles")
+        ;
+
+    idleFraction
+        .name(name() + ".idle_fraction")
+        .desc("Percentage of idle cycles")
+        ;
+
+    icacheStallCycles
+        .name(name() + ".icache_stall_cycles")
+        .desc("ICache total stall cycles")
+        .prereq(icacheStallCycles)
+        ;
+
+    dcacheStallCycles
+        .name(name() + ".dcache_stall_cycles")
+        .desc("DCache total stall cycles")
+        .prereq(dcacheStallCycles)
+        ;
+
+    idleFraction = idleCycles / simTicks;
+
+    numInsts = Statistics::scalar(numInst);
+    simInsts += numInsts;
+}
+
+void
+SimpleCPU::serialize()
+{
+    nameOut();
+
+#ifdef FULL_SYSTEM
+#if 0
+    // do we need this anymore?? egh
+    childOut("itb", xc->itb);
+    childOut("dtb", xc->dtb);
+    childOut("physmem", physmem);
+#endif
+#endif
+
+    for (int i = 0; i < NumIntRegs; i++) {
+        stringstream buf;
+        ccprintf(buf, "R%02d", i);
+        paramOut(buf.str(), xc->regs.intRegFile[i]);
+    }
+    for (int i = 0; i < NumFloatRegs; i++) {
+        stringstream buf;
+        ccprintf(buf, "F%02d", i);
+        paramOut(buf.str(), xc->regs.floatRegFile.d[i]);
+    }
+    // CPUTraitsType::serializeSpecialRegs(getProxy(), xc->regs);
+}
+
+void
+SimpleCPU::unserialize(IniFile &db, const string &category, ConfigNode *node)
+{
+    string data;
+
+    for (int i = 0; i < NumIntRegs; i++) {
+        stringstream buf;
+        ccprintf(buf, "R%02d", i);
+        db.findDefault(category, buf.str(), data);
+        to_number(data,xc->regs.intRegFile[i]);
+    }
+    for (int i = 0; i < NumFloatRegs; i++) {
+        stringstream buf;
+        ccprintf(buf, "F%02d", i);
+        db.findDefault(category, buf.str(), data);
+        xc->regs.floatRegFile.d[i] = strtod(data.c_str(),NULL);
+    }
+
+    // Read in Special registers
+
+    // CPUTraitsType::unserializeSpecialRegs(db,category,node,xc->regs);
+}
+
+void
+change_thread_state(int thread_number, int activate, int priority)
+{
+}
+
+// precise architected memory state accessor macros
+template <class T>
+Fault
+SimpleCPU::read(Addr addr, T& data, unsigned flags)
+{
+    memReq->reset(addr, sizeof(T), flags);
+
+    // translate to physical address
+    Fault fault = xc->translateDataReadReq(memReq);
+
+    // do functional access
+    if (fault == No_Fault)
+        fault = xc->read(memReq, data);
+
+    if (traceData) {
+        traceData->setAddr(addr);
+        if (fault == No_Fault)
+            traceData->setData(data);
+    }
+
+    // if we have a cache, do cache access too
+    if (fault == No_Fault && dcacheInterface) {
+        memReq->cmd = Read;
+        memReq->completionEvent = NULL;
+        memReq->time = curTick;
+        memReq->flags &= ~UNCACHEABLE;
+        MemAccessResult result = dcacheInterface->access(memReq);
+
+        // Ugly hack to get an event scheduled *only* if the access is
+        // a miss.  We really should add first-class support for this
+        // at some point.
+        if (result != MA_HIT && dcacheInterface->doEvents) {
+            memReq->completionEvent = &cacheCompletionEvent;
+            setStatus(DcacheMissStall);
+        }
+    }
+
+    return fault;
+}
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+template
+Fault
+SimpleCPU::read(Addr addr, uint64_t& data, unsigned flags);
+
+template
+Fault
+SimpleCPU::read(Addr addr, uint32_t& data, unsigned flags);
+
+template
+Fault
+SimpleCPU::read(Addr addr, uint16_t& data, unsigned flags);
+
+template
+Fault
+SimpleCPU::read(Addr addr, uint8_t& data, unsigned flags);
+
+#endif //DOXYGEN_SHOULD_SKIP_THIS
+
+template<>
+Fault
+SimpleCPU::read(Addr addr, double& data, unsigned flags)
+{
+    return read(addr, *(uint64_t*)&data, flags);
+}
+
+template<>
+Fault
+SimpleCPU::read(Addr addr, float& data, unsigned flags)
+{
+    return read(addr, *(uint32_t*)&data, flags);
+}
+
+
+template<>
+Fault
+SimpleCPU::read(Addr addr, int32_t& data, unsigned flags)
+{
+    return read(addr, (uint32_t&)data, flags);
+}
+
+
+template <class T>
+Fault
+SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
+{
+    if (traceData) {
+        traceData->setAddr(addr);
+        traceData->setData(data);
+    }
+
+    memReq->reset(addr, sizeof(T), flags);
+
+    // translate to physical address
+    Fault fault = xc->translateDataWriteReq(memReq);
+
+    // do functional access
+    if (fault == No_Fault)
+        fault = xc->write(memReq, data);
+
+    if (fault == No_Fault && dcacheInterface) {
+        memReq->cmd = Write;
+        memReq->data = (uint8_t *)&data;
+        memReq->completionEvent = NULL;
+        memReq->time = curTick;
+        memReq->flags &= ~UNCACHEABLE;
+        MemAccessResult result = dcacheInterface->access(memReq);
+
+        // Ugly hack to get an event scheduled *only* if the access is
+        // a miss.  We really should add first-class support for this
+        // at some point.
+        if (result != MA_HIT && dcacheInterface->doEvents) {
+            memReq->completionEvent = &cacheCompletionEvent;
+            setStatus(DcacheMissStall);
+        }
+    }
+
+    if (res && (fault == No_Fault))
+        *res = memReq->result;
+
+    return fault;
+}
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template
+Fault
+SimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);
+
+template
+Fault
+SimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);
+
+template
+Fault
+SimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);
+
+template
+Fault
+SimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);
+
+#endif //DOXYGEN_SHOULD_SKIP_THIS
+
+template<>
+Fault
+SimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
+{
+    return write(*(uint64_t*)&data, addr, flags, res);
+}
+
+template<>
+Fault
+SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
+{
+    return write(*(uint32_t*)&data, addr, flags, res);
+}
+
+
+template<>
+Fault
+SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
+{
+    return write((uint32_t)data, addr, flags, res);
+}
+
+
+#ifdef FULL_SYSTEM
+Addr
+SimpleCPU::dbg_vtophys(Addr addr)
+{
+    return vtophys(xc, addr);
+}
+#endif // FULL_SYSTEM
+
+Tick save_cycle = 0;
+
+
+void
+SimpleCPU::processCacheCompletion()
+{
+    switch (status()) {
+      case IcacheMissStall:
+        icacheStallCycles += curTick - lastIcacheStall;
+        setStatus(IcacheMissComplete);
+        break;
+      case DcacheMissStall:
+        dcacheStallCycles += curTick - lastDcacheStall;
+        setStatus(Running);
+        break;
+      default:
+        panic("SimpleCPU::processCacheCompletion: bad state");
+        break;
+    }
+}
+
+#ifdef FULL_SYSTEM
+void
+SimpleCPU::post_interrupt(int int_num, int index)
+{
+    BaseCPU::post_interrupt(int_num, index);
+
+    if (xc->status() == ExecContext::Suspended) {
+                DPRINTF(IPI,"Suspended Processor awoke\n");
+        xc->setStatus(ExecContext::Active);
+        Annotate::Resume(xc);
+    }
+}
+#endif // FULL_SYSTEM
+
+/* start simulation, program loaded, processor precise state initialized */
+void
+SimpleCPU::tick()
+{
+    traceData = NULL;
+
+#ifdef FULL_SYSTEM
+    if (fault == No_Fault && AlphaISA::check_interrupts &&
+        xc->cpu->check_interrupts() &&
+        !PC_PAL(xc->regs.pc) &&
+        status() != IcacheMissComplete) {
+        int ipl = 0;
+        int summary = 0;
+        AlphaISA::check_interrupts = 0;
+        IntReg *ipr = xc->regs.ipr;
+
+        if (xc->regs.ipr[TheISA::IPR_SIRR]) {
+            for (int i = TheISA::INTLEVEL_SOFTWARE_MIN;
+                 i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) {
+                if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) {
+                    // See table 4-19 of 21164 hardware reference
+                    ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1;
+                    summary |= (ULL(1) << i);
+                }
+            }
+        }
+
+        uint64_t interrupts = xc->cpu->intr_status();
+        for(int i = TheISA::INTLEVEL_EXTERNAL_MIN;
+            i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) {
+            if (interrupts & (ULL(1) << i)) {
+                // See table 4-19 of 21164 hardware reference
+                ipl = i;
+                summary |= (ULL(1) << i);
+            }
+        }
+
+        if (ipr[TheISA::IPR_ASTRR])
+            panic("asynchronous traps not implemented\n");
+
+        if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) {
+            ipr[TheISA::IPR_ISR] = summary;
+            ipr[TheISA::IPR_INTID] = ipl;
+            xc->ev5_trap(Interrupt_Fault);
+
+            DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
+                    ipr[TheISA::IPR_IPLR], ipl, summary);
+        }
+    }
+#endif
+
+    // maintain $r0 semantics
+    xc->regs.intRegFile[ZeroReg] = 0;
+#ifdef TARGET_ALPHA
+    xc->regs.floatRegFile.d[ZeroReg] = 0.0;
+#endif // TARGET_ALPHA
+
+    if (status() == IcacheMissComplete) {
+        // We've already fetched an instruction and were stalled on an
+        // I-cache miss.  No need to fetch it again.
+
+        setStatus(Running);
+    }
+    else {
+        // Try to fetch an instruction
+
+        // set up memory request for instruction fetch
+#ifdef FULL_SYSTEM
+#define IFETCH_FLAGS(pc)       ((pc) & 1) ? PHYSICAL : 0
+#else
+#define IFETCH_FLAGS(pc)       0
+#endif
+
+        memReq->cmd = Read;
+        memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),
+                     IFETCH_FLAGS(xc->regs.pc));
+
+        fault = xc->translateInstReq(memReq);
+
+        if (fault == No_Fault)
+            fault = xc->mem->read(memReq, inst);
+
+        if (icacheInterface && fault == No_Fault) {
+            memReq->completionEvent = NULL;
+
+            memReq->time = curTick;
+            memReq->flags &= ~UNCACHEABLE;
+            MemAccessResult result = icacheInterface->access(memReq);
+
+            // Ugly hack to get an event scheduled *only* if the access is
+            // a miss.  We really should add first-class support for this
+            // at some point.
+            if (result != MA_HIT && icacheInterface->doEvents) {
+                memReq->completionEvent = &cacheCompletionEvent;
+                setStatus(IcacheMissStall);
+                return;
+            }
+        }
+    }
+
+    // If we've got a valid instruction (i.e., no fault on instruction
+    // fetch), then execute it.
+    if (fault == No_Fault) {
+
+        // keep an instruction count
+        numInst++;
+
+        // check for instruction-count-based events
+        comInsnEventQueue[0]->serviceEvents(numInst);
+
+        // decode the instruction
+        StaticInstPtr<TheISA> si(inst);
+
+        traceData = Trace::getInstRecord(curTick, xc, this, si,
+                                         xc->regs.pc);
+
+#ifdef FULL_SYSTEM
+        xc->regs.opcode = (inst >> 26) & 0x3f;
+        xc->regs.ra = (inst >> 21) & 0x1f;
+#endif // FULL_SYSTEM
+
+        xc->func_exe_insn++;
+
+        fault = si->execute(this, xc, traceData);
+
+        if (si->isMemRef()) {
+            numMemRefs++;
+        }
+
+        if (traceData)
+            traceData->finalize();
+
+    }  // if (fault == No_Fault)
+
+    if (fault != No_Fault) {
+#ifdef FULL_SYSTEM
+        xc->ev5_trap(fault);
+#else // !FULL_SYSTEM
+        fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc);
+#endif // FULL_SYSTEM
+    }
+    else {
+        // go to the next instruction
+        xc->regs.pc = xc->regs.npc;
+        xc->regs.npc += sizeof(MachInst);
+    }
+
+#ifdef FULL_SYSTEM
+    Addr oldpc;
+    do {
+        oldpc = xc->regs.pc;
+        system->pcEventQueue.service(xc);
+    } while (oldpc != xc->regs.pc);
+#endif
+
+    assert(status() == Running ||
+           status() == Idle ||
+           status() == DcacheMissStall);
+
+    if (status() == Running && !tickEvent.scheduled())
+        tickEvent.schedule(curTick + 1);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+//
+//  SimpleCPU Simulation Object
+//
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
+
+    Param<Counter> max_insts_any_thread;
+    Param<Counter> max_insts_all_threads;
+
+#ifdef FULL_SYSTEM
+    SimObjectParam<AlphaItb *> itb;
+    SimObjectParam<AlphaDtb *> dtb;
+    SimObjectParam<FunctionalMemory *> mem;
+    SimObjectParam<System *> system;
+    Param<int> cpu_id;
+    Param<int> mult;
+#else
+    SimObjectParam<Process *> workload;
+#endif // FULL_SYSTEM
+
+    SimObjectParam<BaseMem *> icache;
+    SimObjectParam<BaseMem *> dcache;
+
+END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
+
+    INIT_PARAM_DFLT(max_insts_any_thread,
+                    "terminate when any thread reaches this insn count",
+                    0),
+    INIT_PARAM_DFLT(max_insts_all_threads,
+                    "terminate when all threads have reached this insn count",
+                    0),
+
+#ifdef FULL_SYSTEM
+    INIT_PARAM(itb, "Instruction TLB"),
+    INIT_PARAM(dtb, "Data TLB"),
+    INIT_PARAM(mem, "memory"),
+    INIT_PARAM(system, "system object"),
+    INIT_PARAM_DFLT(cpu_id, "CPU identification number", 0),
+    INIT_PARAM_DFLT(mult, "system clock multiplier", 1),
+#else
+    INIT_PARAM(workload, "processes to run"),
+#endif // FULL_SYSTEM
+
+    INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL),
+    INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL)
+
+END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
+
+
+CREATE_SIM_OBJECT(SimpleCPU)
+{
+#ifdef FULL_SYSTEM
+    if (mult != 1)
+        panic("processor clock multiplier must be 1\n");
+
+    return new SimpleCPU(getInstanceName(), system,
+                         max_insts_any_thread, max_insts_all_threads,
+                         itb, dtb, mem,
+                         (icache) ? icache->getInterface() : NULL,
+                         (dcache) ? dcache->getInterface() : NULL,
+                         cpu_id, ticksPerSecond * mult);
+#else
+
+    return new SimpleCPU(getInstanceName(), workload,
+                         max_insts_any_thread, max_insts_all_threads,
+                         icache->getInterface(), dcache->getInterface());
+
+#endif // FULL_SYSTEM
+}
+
+REGISTER_SIM_OBJECT("SimpleCPU", SimpleCPU)
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
new file mode 100644 (file)
index 0000000..c5671eb
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SIMPLE_CPU_HH__
+#define __SIMPLE_CPU_HH__
+
+#include "base_cpu.hh"
+#include "eventq.hh"
+#include "symtab.hh"
+#include "pc_event.hh"
+#include "statistics.hh"
+
+
+// forward declarations
+#ifdef FULL_SYSTEM
+class Processor;
+class Kernel;
+class AlphaItb;
+class AlphaDtb;
+class PhysicalMemory;
+
+class RemoteGDB;
+class GDBListener;
+#endif // FULL_SYSTEM
+
+class MemInterface;
+class IniFile;
+
+namespace Trace {
+    class InstRecord;
+}
+
+class SimpleCPU : public BaseCPU
+{
+  public:
+    // main simulation loop (one cycle)
+    void tick();
+
+  private:
+    class TickEvent : public Event
+    {
+      private:
+        SimpleCPU *cpu;
+
+      public:
+        TickEvent(SimpleCPU *c)
+            : Event(&mainEventQueue, 100), cpu(c) { }
+        void process() { cpu->tick(); }
+        virtual const char *description() { return "tick event"; }
+    };
+
+    TickEvent tickEvent;
+
+  private:
+    Trace::InstRecord *traceData;
+    template<typename T>
+    void trace_data(T data) {
+      if (traceData) {
+        traceData->setData(data);
+      }
+    };
+
+  public:
+    //
+    enum Status {
+        Running,
+        Idle,
+        IcacheMissStall,
+        IcacheMissComplete,
+        DcacheMissStall
+    };
+
+  private:
+    Status _status;
+
+  public:
+    void post_interrupt(int int_num, int index);
+
+    void zero_fill_64(Addr addr) {
+      static int warned = 0;
+      if (!warned) {
+        warn ("WH64 is not implemented");
+        warned = 1;
+      }
+    };
+
+#ifdef FULL_SYSTEM
+
+    SimpleCPU(const std::string &_name,
+              System *_system,
+              Counter max_insts_any_thread, Counter max_insts_all_threads,
+              AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem,
+              MemInterface *icache_interface, MemInterface *dcache_interface,
+              int cpu_id, Tick freq);
+
+#else
+
+    SimpleCPU(const std::string &_name, Process *_process,
+              Counter max_insts_any_thread,
+              Counter max_insts_all_threads,
+              MemInterface *icache_interface, MemInterface *dcache_interface);
+
+#endif
+
+    virtual ~SimpleCPU();
+
+    // execution context
+    ExecContext *xc;
+
+#ifdef FULL_SYSTEM
+    Addr dbg_vtophys(Addr addr);
+
+    bool interval_stats;
+#endif
+
+    // L1 instruction cache
+    MemInterface *icacheInterface;
+
+    // L1 data cache
+    MemInterface *dcacheInterface;
+
+    // current instruction
+    MachInst inst;
+
+    // current fault status
+    Fault fault;
+
+    // Refcounted pointer to the one memory request.
+    MemReqPtr memReq;
+
+    class CacheCompletionEvent : public Event
+    {
+      private:
+        SimpleCPU *cpu;
+
+      public:
+        CacheCompletionEvent(SimpleCPU *_cpu);
+
+        virtual void process();
+        virtual const char *description();
+    };
+
+    CacheCompletionEvent cacheCompletionEvent;
+
+    Status status() const { return _status; }
+    virtual void execCtxStatusChg() {
+        if (xc) {
+            if (xc->status() == ExecContext::Active)
+                setStatus(Running);
+            else
+                setStatus(Idle);
+        }
+    }
+
+    void setStatus(Status new_status) {
+        Status old_status = status();
+        _status = new_status;
+
+        switch (status()) {
+          case IcacheMissStall:
+            assert(old_status == Running);
+            lastIcacheStall = curTick;
+            if (tickEvent.scheduled())
+                tickEvent.squash();
+            break;
+
+          case IcacheMissComplete:
+            assert(old_status == IcacheMissStall);
+            if (tickEvent.squashed())
+                tickEvent.reschedule(curTick + 1);
+            else if (!tickEvent.scheduled())
+                tickEvent.schedule(curTick + 1);
+            break;
+
+          case DcacheMissStall:
+            assert(old_status == Running);
+            lastDcacheStall = curTick;
+            if (tickEvent.scheduled())
+                tickEvent.squash();
+            break;
+
+          case Idle:
+            assert(old_status == Running);
+            last_idle = curTick;
+            if (tickEvent.scheduled())
+                tickEvent.squash();
+            break;
+
+          case Running:
+            assert(old_status == Idle ||
+                   old_status == DcacheMissStall ||
+                   old_status == IcacheMissComplete);
+            if (old_status == Idle)
+                idleCycles += curTick - last_idle;
+
+            if (tickEvent.squashed())
+                tickEvent.reschedule(curTick + 1);
+            else if (!tickEvent.scheduled())
+                tickEvent.schedule(curTick + 1);
+            break;
+
+          default:
+            panic("can't get here");
+        }
+    }
+
+    // statistics
+    void regStats();
+
+    // number of simulated instructions
+    Counter numInst;
+    Statistics::Formula numInsts;
+
+    // number of simulated memory references
+    Statistics::Scalar<> numMemRefs;
+
+    // number of idle cycles
+    Statistics::Scalar<> idleCycles;
+    Statistics::Formula idleFraction;
+    Counter last_idle;
+
+    // number of cycles stalled for I-cache misses
+    Statistics::Scalar<> icacheStallCycles;
+    Counter lastIcacheStall;
+
+    // number of cycles stalled for D-cache misses
+    Statistics::Scalar<> dcacheStallCycles;
+    Counter lastDcacheStall;
+
+    void processCacheCompletion();
+
+    virtual void serialize();
+    virtual void unserialize(IniFile &db, const std::string &category,
+                             ConfigNode *node);
+
+    template <class T>
+    Fault read(Addr addr, T& data, unsigned flags);
+
+    template <class T>
+    Fault write(T data, Addr addr, unsigned flags,
+                        uint64_t *res);
+
+    Fault prefetch(Addr addr, unsigned flags)
+    {
+        // need to do this...
+        return No_Fault;
+    }
+
+    void writeHint(Addr addr, int size)
+    {
+        // need to do this...
+    }
+};
+
+#endif // __SIMPLE_CPU_HH__
diff --git a/cpu/static_inst.cc b/cpu/static_inst.cc
new file mode 100644 (file)
index 0000000..cf25d5f
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <iostream>
+#include "static_inst.hh"
+#include "universe.hh"
+
+template <class ISA>
+StaticInstPtr<ISA> StaticInst<ISA>::nullStaticInstPtr;
+
+template <class ISA>
+typename StaticInst<ISA>::DecodeCache StaticInst<ISA>::decodeCache;
+
+// Define the decode cache hash map.
+template StaticInst<AlphaISA>::DecodeCache
+StaticInst<AlphaISA>::decodeCache;
+
+template <class ISA>
+void
+StaticInst<ISA>::dumpDecodeCacheStats()
+{
+    using namespace std;
+
+    cerr << "Decode hash table stats @ " << curTick << ":" << endl;
+    cerr << "\tnum entries = " << decodeCache.size() << endl;
+    cerr << "\tnum buckets = " << decodeCache.bucket_count() << endl;
+    vector<int> hist(100, 0);
+    int max_hist = 0;
+    for (int i = 0; i < decodeCache.bucket_count(); ++i) {
+        int count = decodeCache.elems_in_bucket(i);
+        if (count > max_hist)
+            max_hist = count;
+        hist[count]++;
+    }
+    for (int i = 0; i <= max_hist; ++i) {
+        cerr << "\tbuckets of size " << i << " = " << hist[i] << endl;
+    }
+}
+
+
+template StaticInstPtr<AlphaISA>
+StaticInst<AlphaISA>::nullStaticInstPtr;
+
+template <class ISA>
+bool
+StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt)
+{
+    if (isDirectCtrl()) {
+        tgt = branchTarget(pc);
+        return true;
+    }
+
+    if (isIndirectCtrl()) {
+        tgt = branchTarget(xc);
+        return true;
+    }
+
+    return false;
+}
+
+
+// force instantiation of template function(s) above
+template StaticInst<AlphaISA>;
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
new file mode 100644 (file)
index 0000000..b8f9cc0
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __STATIC_INST_HH__
+#define __STATIC_INST_HH__
+
+#include <bitset>
+#include <string>
+
+#include "host.hh"
+#include "hashmap.hh"
+#include "refcnt.hh"
+
+#include "op_class.hh"
+#include "isa_traits.hh"
+
+// forward declarations
+class ExecContext;
+class SpecExecContext;
+class SimpleCPU;
+class CPU;
+class DynInst;
+class SymbolTable;
+
+namespace Trace {
+    class InstRecord;
+}
+
+/**
+ * Base, ISA-independent static instruction class.
+ *
+ * The main component of this class is the vector of flags and the
+ * associated methods for reading them.  Any object that can rely
+ * solely on these flags can process instructions without being
+ * recompiled for multiple ISAs.
+ */
+class StaticInstBase : public RefCounted
+{
+  protected:
+
+    /// Set of boolean static instruction properties.
+    ///
+    /// Notes:
+    /// - The IsInteger and IsFloating flags are based on the class of
+    /// registers accessed by the instruction.  Although most
+    /// instructions will have exactly one of these two flags set, it
+    /// is possible for an instruction to have neither (e.g., direct
+    /// unconditional branches, memory barriers) or both (e.g., an
+    /// FP/int conversion).
+    /// - If IsMemRef is set, then exactly one of IsLoad or IsStore
+    /// will be set.  Prefetches are marked as IsLoad, even if they
+    /// prefetch exclusive copies.
+    /// - If IsControl is set, then exactly one of IsDirectControl or
+    /// IsIndirect Control will be set, and exactly one of
+    /// IsCondControl or IsUncondControl will be set.
+    ///
+    enum Flags {
+        IsNop,         ///< Is a no-op (no effect at all).
+
+        IsInteger,     ///< References integer regs.
+        IsFloating,    ///< References FP regs.
+
+        IsMemRef,      ///< References memory (load, store, or prefetch).
+        IsLoad,                ///< Reads from memory (load or prefetch).
+        IsStore,       ///< Writes to memory.
+        IsInstPrefetch,        ///< Instruction-cache prefetch.
+        IsDataPrefetch,        ///< Data-cache prefetch.
+
+        IsControl,             ///< Control transfer instruction.
+        IsDirectControl,       ///< PC relative control transfer.
+        IsIndirectControl,     ///< Register indirect control transfer.
+        IsCondControl,         ///< Conditional control transfer.
+        IsUncondControl,       ///< Unconditional control transfer.
+        IsCall,                        ///< Subroutine call.
+        IsReturn,              ///< Subroutine return.
+
+        IsThreadSync,          ///< Thread synchronization operation.
+
+        NumFlags
+    };
+
+    /// Flag values for this instruction.
+    std::bitset<NumFlags> flags;
+
+    /// See opClass().
+    OpClass _opClass;
+
+    /// See numSrcRegs().
+    int8_t _numSrcRegs;
+
+    /// See numDestRegs().
+    int8_t _numDestRegs;
+
+    /// The following are used to track physical register usage
+    /// for machines with separate int & FP reg files.
+    //@{
+    int8_t _numFPDestRegs;
+    int8_t _numIntDestRegs;
+    //@}
+
+    /// Constructor.
+    /// It's important to initialize everything here to a sane
+    /// default, since the decoder generally only overrides
+    /// the fields that are meaningful for the particular
+    /// instruction.
+    StaticInstBase(OpClass __opClass)
+        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
+          _numFPDestRegs(0), _numIntDestRegs(0)
+    {
+    }
+
+  public:
+
+    /// @name Register information.
+    /// The sum of numFPDestRegs() and numIntDestRegs() equals
+    /// numDestRegs().  The former two functions are used to track
+    /// physical register usage for machines with separate int & FP
+    /// reg files.
+    //@{
+    /// Number of source registers.
+    int8_t numSrcRegs()  const { return _numSrcRegs; }
+    /// Number of destination registers.
+    int8_t numDestRegs() const { return _numDestRegs; }
+    /// Number of floating-point destination regs.
+    int8_t numFPDestRegs()  const { return _numFPDestRegs; }
+    /// Number of integer destination regs.
+    int8_t numIntDestRegs() const { return _numIntDestRegs; }
+    //@}
+
+    /// @name Flag accessors.
+    /// These functions are used to access the values of the various
+    /// instruction property flags.  See StaticInstBase::Flags for descriptions
+    /// of the individual flags.
+    //@{
+
+    bool isNop()         const { return flags[IsNop]; }
+
+    bool isMemRef()              const { return flags[IsMemRef]; }
+    bool isLoad()        const { return flags[IsLoad]; }
+    bool isStore()       const { return flags[IsStore]; }
+    bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
+    bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
+
+    bool isInteger()     const { return flags[IsInteger]; }
+    bool isFloating()    const { return flags[IsFloating]; }
+
+    bool isControl()     const { return flags[IsControl]; }
+    bool isCall()        const { return flags[IsCall]; }
+    bool isReturn()      const { return flags[IsReturn]; }
+    bool isDirectCtrl()          const { return flags[IsDirectControl]; }
+    bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
+    bool isCondCtrl()    const { return flags[IsCondControl]; }
+    bool isUncondCtrl()          const { return flags[IsUncondControl]; }
+
+    bool isThreadSync()   const { return flags[IsThreadSync]; }
+    //@}
+
+    /// Operation class.  Used to select appropriate function unit in issue.
+    OpClass opClass()     const { return _opClass; }
+};
+
+
+// forward declaration
+template <class ISA>
+class StaticInstPtr;
+
+/**
+ * Generic yet ISA-dependent static instruction class.
+ *
+ * This class builds on StaticInstBase, defining fields and interfaces
+ * that are generic across all ISAs but that differ in details
+ * according to the specific ISA being used.
+ */
+template <class ISA>
+class StaticInst : public StaticInstBase
+{
+  public:
+
+    /// Binary machine instruction type.
+    typedef typename ISA::MachInst MachInst;
+    /// Memory address type.
+    typedef typename ISA::Addr    Addr;
+    /// Logical register index type.
+    typedef typename ISA::RegIndex RegIndex;
+
+    enum {
+        MaxInstSrcRegs = ISA::MaxInstSrcRegs,  //< Max source regs
+        MaxInstDestRegs = ISA::MaxInstDestRegs,        //< Max dest regs
+    };
+
+
+    /// Return logical index (architectural reg num) of i'th destination reg.
+    /// Only the entries from 0 through numDestRegs()-1 are valid.
+    RegIndex destRegIdx(int i) { return _destRegIdx[i]; }
+
+    /// Return logical index (architectural reg num) of i'th source reg.
+    /// Only the entries from 0 through numSrcRegs()-1 are valid.
+    RegIndex srcRegIdx(int i)  { return _srcRegIdx[i]; }
+
+    /// Pointer to a statically allocated "null" instruction object.
+    /// Used to give eaCompInst() and memAccInst() something to return
+    /// when called on non-memory instructions.
+    static StaticInstPtr<ISA> nullStaticInstPtr;
+
+    /**
+     * Memory references only: returns "fake" instruction representing
+     * the effective address part of the memory operation.  Used to
+     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
+     * just the EA computation.
+     */
+    virtual StaticInstPtr<ISA> eaCompInst() { return nullStaticInstPtr; }
+
+    /**
+     * Memory references only: returns "fake" instruction representing
+     * the memory access part of the memory operation.  Used to
+     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
+     * just the memory access (not the EA computation).
+     */
+    virtual StaticInstPtr<ISA> memAccInst() { return nullStaticInstPtr; }
+
+    /// The binary machine instruction.
+    const MachInst machInst;
+
+  protected:
+
+    /// See destRegIdx().
+    RegIndex _destRegIdx[MaxInstDestRegs];
+    /// See srcRegIdx().
+    RegIndex _srcRegIdx[MaxInstSrcRegs];
+
+    /**
+     * Base mnemonic (e.g., "add").  Used by generateDisassembly()
+     * methods.  Also useful to readily identify instructions from
+     * within the debugger when #cachedDisassembly has not been
+     * initialized.
+     */
+    const char *mnemonic;
+
+    /**
+     * String representation of disassembly (lazily evaluated via
+     * disassemble()).
+     */
+    std::string *cachedDisassembly;
+
+    /**
+     * Internal function to generate disassembly string.
+     */
+    virtual std::string generateDisassembly(Addr pc,
+                                            const SymbolTable *symtab) = 0;
+
+    /// Constructor.
+    StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass)
+        : StaticInstBase(__opClass),
+          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
+    {
+    }
+
+  public:
+
+    virtual ~StaticInst()
+    {
+        if (cachedDisassembly)
+            delete cachedDisassembly;
+    }
+
+    /**
+     * Execute this instruction under SimpleCPU model.
+     */
+    virtual Fault execute(SimpleCPU *cpu, ExecContext *xc,
+                          Trace::InstRecord *traceData) = 0;
+
+    /**
+     * Execute this instruction under detailed CPU model.
+     */
+    virtual Fault execute(CPU *cpu, SpecExecContext *xc, DynInst *dynInst,
+                          Trace::InstRecord *traceData) = 0;
+
+    /**
+     * Return the target address for a PC-relative branch.
+     * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
+     * should be true).
+     */
+    virtual Addr branchTarget(Addr branchPC)
+    {
+        panic("StaticInst::branchTarget() called on instruction "
+              "that is not a PC-relative branch.");
+    }
+
+    /**
+     * Return the target address for an indirect branch (jump).
+     * The register value is read from the supplied execution context.
+     * Invalid if not an indirect branch (i.e. isIndirectCtrl()
+     * should be true).
+     */
+    virtual Addr branchTarget(ExecContext *xc)
+    {
+        panic("StaticInst::branchTarget() called on instruction "
+              "that is not an indirect branch.");
+    }
+
+    /**
+     * Return true if the instruction is a control transfer, and if so,
+     * return the target address as well.
+     */
+    bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt);
+
+    /**
+     * Return string representation of disassembled instruction.
+     * The default version of this function will call the internal
+     * virtual generateDisassembly() function to get the string,
+     * then cache it in #cachedDisassembly.  If the disassembly
+     * should not be cached, this function should be overridden directly.
+     */
+    virtual const std::string &disassemble(Addr pc,
+                                           const SymbolTable *symtab = 0)
+    {
+        if (!cachedDisassembly)
+            cachedDisassembly =
+                new std::string(generateDisassembly(pc, symtab));
+
+        return *cachedDisassembly;
+    }
+
+    /// Decoded instruction cache type.
+    /// For now we're using a generic hash_map; this seems to work
+    /// pretty well.
+    typedef m5::hash_map<MachInst, StaticInstPtr<ISA> > DecodeCache;
+
+    /// A cache of decoded instruction objects.
+    static DecodeCache decodeCache;
+
+    /**
+     * Dump some basic stats on the decode cache hash map.
+     * Only gets called if DECODE_CACHE_HASH_STATS is defined.
+     */
+    static void dumpDecodeCacheStats();
+
+    /// Decode a machine instruction.
+    /// @param mach_inst The binary instruction to decode.
+    /// @retval A pointer to the corresponding StaticInst object.
+    static
+    StaticInstPtr<ISA> decode(MachInst mach_inst)
+    {
+#ifdef DECODE_CACHE_HASH_STATS
+        // Simple stats on decode hash_map.  Turns out the default
+        // hash function is as good as anything I could come up with.
+        const int dump_every_n = 10000000;
+        static int decodes_til_dump = dump_every_n;
+
+        if (--decodes_til_dump == 0) {
+            dumpDecodeCacheStats();
+            decodes_til_dump = dump_every_n;
+        }
+#endif
+
+        typename DecodeCache::iterator iter = decodeCache.find(mach_inst);
+        if (iter != decodeCache.end()) {
+            return iter->second;
+        }
+
+        StaticInstPtr<ISA> si = ISA::decodeInst(mach_inst);
+        decodeCache[mach_inst] = si;
+        return si;
+    }
+};
+
+typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
+
+/// Reference-counted pointer to a StaticInst object.
+/// This type should be used instead of "StaticInst<ISA> *" so that
+/// StaticInst objects can be properly reference-counted.
+template <class ISA>
+class StaticInstPtr : public RefCountingPtr<StaticInst<ISA> >
+{
+  public:
+    /// Constructor.
+    StaticInstPtr()
+        : RefCountingPtr<StaticInst<ISA> >()
+    {
+    }
+
+    /// Conversion from "StaticInst<ISA> *".
+    StaticInstPtr(StaticInst<ISA> *p)
+        : RefCountingPtr<StaticInst<ISA> >(p)
+    {
+    }
+
+    /// Copy constructor.
+    StaticInstPtr(const StaticInstPtr &r)
+        : RefCountingPtr<StaticInst<ISA> >(r)
+    {
+    }
+
+    /// Construct directly from machine instruction.
+    /// Calls StaticInst<ISA>::decode().
+    StaticInstPtr(typename ISA::MachInst mach_inst)
+        : RefCountingPtr<StaticInst<ISA> >(StaticInst<ISA>::decode(mach_inst))
+    {
+    }
+
+    /// Convert to pointer to StaticInstBase class.
+    operator const StaticInstBasePtr()
+    {
+        return get();
+    }
+};
+
+#endif // __STATIC_INST_HH__
diff --git a/sim/base_cpu.cc b/sim/base_cpu.cc
deleted file mode 100644 (file)
index 06b2ec6..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <sstream>
-#include <iostream>
-
-#include "base_cpu.hh"
-#include "cprintf.hh"
-#include "exec_context.hh"
-#include "misc.hh"
-#include "sim_events.hh"
-
-using namespace std;
-
-vector<BaseCPU *> BaseCPU::cpuList;
-
-// This variable reflects the max number of threads in any CPU.  Be
-// careful to only use it once all the CPUs that you care about have
-// been initialized
-int maxThreadsPerCPU = 1;
-
-#ifdef FULL_SYSTEM
-BaseCPU::BaseCPU(const string &_name, int _number_of_threads,
-                 Counter max_insts_any_thread,
-                 Counter max_insts_all_threads,
-                 System *_system, int num, Tick freq)
-    : SimObject(_name), number(num), frequency(freq),
-      number_of_threads(_number_of_threads), system(_system)
-#else
-BaseCPU::BaseCPU(const string &_name, int _number_of_threads,
-                 Counter max_insts_any_thread,
-                 Counter max_insts_all_threads)
-    : SimObject(_name), number_of_threads(_number_of_threads)
-#endif
-{
-    // add self to global list of CPUs
-    cpuList.push_back(this);
-
-    if (number_of_threads > maxThreadsPerCPU)
-        maxThreadsPerCPU = number_of_threads;
-
-    // allocate per-thread instruction-based event queues
-    comInsnEventQueue = new (EventQueue *)[number_of_threads];
-    for (int i = 0; i < number_of_threads; ++i)
-        comInsnEventQueue[i] = new EventQueue("instruction-based event queue");
-
-    //
-    // set up instruction-count-based termination events, if any
-    //
-    if (max_insts_any_thread != 0)
-        for (int i = 0; i < number_of_threads; ++i)
-            new SimExitEvent(comInsnEventQueue[i], max_insts_any_thread,
-                "a thread reached the max instruction count");
-
-    if (max_insts_all_threads != 0) {
-        // allocate & initialize shared downcounter: each event will
-        // decrement this when triggered; simulation will terminate
-        // when counter reaches 0
-        int *counter = new int;
-        *counter = number_of_threads;
-        for (int i = 0; i < number_of_threads; ++i)
-            new CountedExitEvent(comInsnEventQueue[i],
-                "all threads reached the max instruction count",
-                max_insts_all_threads, *counter);
-    }
-
-#ifdef FULL_SYSTEM
-    memset(interrupts, 0, sizeof(interrupts));
-    intstatus = 0;
-#endif
-}
-
-void
-BaseCPU::regStats()
-{
-    int size = contexts.size();
-    if (size > 1) {
-        for (int i = 0; i < size; ++i) {
-            stringstream namestr;
-            ccprintf(namestr, "%s.ctx%d", name(), i);
-            contexts[i]->regStats(namestr.str());
-        }
-    } else if (size == 1)
-        contexts[0]->regStats(name());
-}
-
-#ifdef FULL_SYSTEM
-void
-BaseCPU::post_interrupt(int int_num, int index)
-{
-    DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
-
-    if (int_num < 0 || int_num >= NumInterruptLevels)
-        panic("int_num out of bounds\n");
-
-    if (index < 0 || index >= sizeof(uint8_t) * 8)
-        panic("int_num out of bounds\n");
-
-    AlphaISA::check_interrupts = 1;
-    interrupts[int_num] |= 1 << index;
-    intstatus |= (ULL(1) << int_num);
-}
-
-void
-BaseCPU::clear_interrupt(int int_num, int index)
-{
-    DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
-
-    if (int_num < 0 || int_num >= NumInterruptLevels)
-        panic("int_num out of bounds\n");
-
-    if (index < 0 || index >= sizeof(uint8_t) * 8)
-        panic("int_num out of bounds\n");
-
-    interrupts[int_num] &= ~(1 << index);
-    if (interrupts[int_num] == 0)
-        intstatus &= ~(ULL(1) << int_num);
-}
-
-void
-BaseCPU::clear_interrupts()
-{
-    DPRINTF(Interrupt, "Interrupts all cleared\n");
-
-    memset(interrupts, 0, sizeof(interrupts));
-    intstatus = 0;
-}
-
-#endif // FULL_SYSTEM
-
-DEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
diff --git a/sim/base_cpu.hh b/sim/base_cpu.hh
deleted file mode 100644 (file)
index 745220d..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __BASE_CPU_HH__
-#define __BASE_CPU_HH__
-
-#include <vector>
-
-#include "eventq.hh"
-#include "sim_object.hh"
-
-#include "isa_traits.hh"       // for Addr
-
-#ifdef FULL_SYSTEM
-class System;
-#endif
-
-class BranchPred;
-class ExecContext;
-
-class BaseCPU : public SimObject
-{
-#ifdef FULL_SYSTEM
-  protected:
-    int number;
-    Tick frequency;
-    uint8_t interrupts[NumInterruptLevels];
-    uint64_t intstatus;
-
-  public:
-    virtual void post_interrupt(int int_num, int index);
-    virtual void clear_interrupt(int int_num, int index);
-    virtual void clear_interrupts();
-
-    bool check_interrupt(int int_num) const {
-        if (int_num > NumInterruptLevels)
-            panic("int_num out of bounds\n");
-
-        return interrupts[int_num] != 0;
-    }
-
-    bool check_interrupts() const { return intstatus != 0; }
-    uint64_t intr_status() const { return intstatus; }
-
-    Tick getFreq() const { return frequency; }
-#endif
-
-  protected:
-    std::vector<ExecContext *> contexts;
-
-  public:
-    virtual void execCtxStatusChg() {}
-
-  public:
-
-#ifdef FULL_SYSTEM
-    BaseCPU(const std::string &_name, int _number_of_threads,
-            Counter max_insts_any_thread, Counter max_insts_all_threads,
-            System *_system,
-            int num, Tick freq);
-#else
-    BaseCPU(const std::string &_name, int _number_of_threads,
-            Counter max_insts_any_thread = 0,
-            Counter max_insts_all_threads = 0);
-#endif
-
-    virtual ~BaseCPU() {}
-
-    virtual void regStats();
-
-    /// Number of threads we're actually simulating (<= SMT_MAX_THREADS).
-    /// This is a constant for the duration of the simulation.
-    int number_of_threads;
-
-    /// Vector of per-thread instruction-based event queues.  Used for
-    /// scheduling events based on number of instructions committed by
-    /// a particular thread.
-    EventQueue **comInsnEventQueue;
-
-#ifdef FULL_SYSTEM
-    System *system;
-#endif
-
-    virtual bool filterThisInstructionPrefetch(int thread_number,
-        short asid, Addr prefetchTarget) const { return true; }
-
-    /// Return pointer to CPU's branch predictor (NULL if none).
-    virtual BranchPred *getBranchPred() { return NULL; };
-
-  private:
-    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
-
-  public:
-    static int numSimulatedCPUs() { return cpuList.size(); }
-};
-
-#endif // __BASE_CPU_HH__
diff --git a/sim/cache/lzss_compression.cc b/sim/cache/lzss_compression.cc
deleted file mode 100644 (file)
index a193321..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @file
- * LZSSCompression definitions.
- */
-
-#include <assert.h>
-
-#include "lzss_compression.hh"
-
-#include "misc.hh" //for fatal
-
-int
-LZSSCompression::findSubString(uint8_t *src, int front, int back, int size)
-{
-    int subSize = 0;
-    int max_length = 2048;
-    if (size - back < max_length) {
-        max_length = size - back;
-    }
-    for (int i = 0; i < max_length; ++i) {
-        if (src[front+i] != src[back+i]) {
-            return subSize;
-        }
-        ++subSize;
-    }
-    return subSize;
-}
-
-int
-LZSSCompression::emitByte(uint8_t *dest, uint8_t byte)
-{
-    if ((byte >> 5 & 0x7) == 0 || (byte >> 5 & 0x7) == 7) {
-        // If the top 3 bits are the same, emit 00<6bits>
-        dest[0] = byte & 0x3f;
-        return 1;
-    } else {
-        // emit 01XXXXXX <8 bits>
-        dest[0] = 0x40;
-        dest[1] = byte;
-        return 2;
-    }
-}
-
-void
-LZSSCompression::emitString(uint8_t *dest, uint16_t P, uint16_t L)
-{
-    // Emit 1<7P> <5P><3L> <8L>
-    dest[0] = 1<<7 | (P >> 5 & 0x7f);
-    dest[1] = ((P & 0x1f) << 3) | (L>>8 & 0x3);
-    dest[2] = L & 0xFF;
-}
-
-int
-LZSSCompression::compress(uint8_t *dest, uint8_t *src, int size)
-{
-    if (size > 4096) {
-        fatal("Compression can only handle block sizes of 4096 bytes or less");
-    }
-
-    // Encode the first byte.
-    int dest_index = emitByte(dest, src[0]);
-    int i = 1;
-    // A 11 bit field
-    uint16_t L;
-    // A 12 bit field
-    uint16_t P = 0;
-
-    while (i < size && dest_index < size) {
-        L = 0;
-
-        if (dest_index+3 >= size) {
-            dest_index = size;
-            continue;
-        }
-
-        if (i == size - 1) {
-            // Output the character
-            dest_index += emitByte(&dest[dest_index], src[i]);
-            ++i;
-            continue;
-        }
-        for (int j = 0; j < i; ++j) {
-            int sub_size = findSubString(src, j, i, size);
-            if (sub_size >= L) {
-                L = sub_size;
-                P = j;
-            }
-        }
-        if (L > 1) {
-            // Output the string reference
-            emitString(&dest[dest_index], P, L);
-            dest_index += 3;
-            i = i+L;
-        } else {
-            // Output the character
-            dest_index += emitByte(&dest[dest_index], src[i]);
-            ++i;
-        }
-    }
-
-    if (dest_index >= size) {
-        // Have expansion instead of compression, just copy.
-        memcpy(dest,src,size);
-        return size;
-    }
-    return dest_index;
-}
-
-int
-LZSSCompression::uncompress(uint8_t *dest, uint8_t *src, int size)
-{
-    int index = 0;
-    int i = 0;
-    while (i < size) {
-        if (src[i] & 1<<7 ) {
-            // We have a string
-            // Extract P
-            int start = (src[i] & 0x3f)<<5 | ((src[i+1] >> 3) & 0x1f);
-            // Extract L
-            int len = (src[i+1] & 0x07)<<8 | src[i+2];
-            i += 3;
-            for (int j = start; j < start+len; ++j) {
-                dest[index++] = dest[j];
-            }
-        } else {
-            // We have a character
-            if (src[i] & 1<<6) {
-                // Value is in the next byte
-                dest[index++] = src[i+1];
-                i += 2;
-            } else {
-                // just extend the lower 6 bits
-                dest[index++] = (src[i] & 0x3f) | ((src[i] & 1<<5) ? 0xC0 : 0);
-                ++i;
-            }
-        }
-    }
-    return index;
-}
diff --git a/sim/cache/lzss_compression.hh b/sim/cache/lzss_compression.hh
deleted file mode 100644 (file)
index 5fb47d3..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __LZSS_COMPRESSION_HH__
-#define __LZSS_COMPRESSION_HH__
-
-/** @file
- * LZSSCompression declarations.
- */
-
-#include "host.hh" // for uint8_t
-
-/**
- * Simple LZSS compression scheme.
- */
-class LZSSCompression
-{
-    /**
-     * Finds the longest substrings that start at the given offsets.
-     * @param src The source block that we search for substrings.
-     * @param front The smaller offset.
-     * @param back The larger offset.
-     * @param size The size of the source block.
-     * @return The size of the longest substring.
-     */
-    int findSubString(uint8_t *src, int front, int back, int size);
-
-    /**
-     * Emit an encoded byte to the compressed data array. If the 2 high
-     * order bits can be signed extended, use 1 byte encoding, if not use 2
-     * bytes.
-     * @param dest The compressed data.
-     * @param byte The byte to emit.
-     * @return The number of bytes used to encode.
-     */
-    int emitByte(uint8_t *dest, uint8_t byte);
-
-    /**
-     * Emit a string reference to the compressed data array. A string reference
-     * always uses 3 bytes. 1 flag bit, 12 bits for the starting position, and
-     * 11 bits for the length of the string. This allows compression of 4096
-     * byte blocks with string lengths of up to 2048 bytes.
-     * @param dest The compressed data.
-     * @param P The starting position in the uncompressed data.
-     * @param L The length in bytes of the string.
-     */
-    void emitString(uint8_t *dest, uint16_t P, uint16_t L);
-
-  public:
-    /**
-     * Compresses the source block and stores it in the destination block. If
-     * the compressed block grows to larger than the source block, it aborts
-     * and just performs a copy.
-     * @param dest The destination block.
-     * @param src The block to be compressed.
-     * @param size The size of the source block.
-     * @return The size of the compressed block.
-     *
-     * @pre Destination has enough storage to hold the compressed block.
-     */
-    int compress(uint8_t *dest, uint8_t *src, int size);
-
-    /**
-     * Unompresses the source block and stores it in the destination block.
-     * @param dest The destination block.
-     * @param src The block to be uncompressed.
-     * @param size The size of the source block.
-     * @return The size of the uncompressed block.
-     *
-     * @pre Destination has enough storage to hold the uncompressed block.
-     */
-    int uncompress(uint8_t *dest, uint8_t *src, int size);
-};
-
-#endif //__LZSS_COMPRESSION_HH__
diff --git a/sim/cache/null_compression.hh b/sim/cache/null_compression.hh
deleted file mode 100644 (file)
index d2bc76e..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __NULL_COMPRESSION_HH__
-#define __NULL_COMPRESSION_HH__
-
-/**
- * @file
- * This file defines a doNothing compression algorithm.
- */
-
-/**
- * A dummy compression class to use when no data compression is desired.
- */
-class NullCompression
-{
-  public:
-    /**
-     * Uncompress the data, causes a fatal since no data should be compressed.
-     * @param dest The output buffer.
-     * @param src  The compressed data.
-     * @param size The number of bytes in src.
-     *
-     * @retval The size of the uncompressed data.
-     */
-    static int uncompress(uint8_t * dest, uint8_t *src, int size)
-    {
-        fatal("Can't uncompress data");
-    }
-
-    /**
-     * Compress the data, just returns the source data.
-     * @param dest The output buffer.
-     * @param src  The data to be compressed.
-     * @param size The number of bytes in src.
-     *
-     * @retval The size of the compressed data.
-     */
-
-    static int compress(uint8_t *dest, uint8_t *src, int size)
-    {
-        memcpy(dest,src,size);
-        return size;
-    }
-};
-
-#endif //__NULL_COMPRESSION_HH__
diff --git a/sim/exec_context.cc b/sim/exec_context.cc
deleted file mode 100644 (file)
index c81d172..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "base_cpu.hh"
-#include "exec_context.hh"
-
-#ifdef FULL_SYSTEM
-#include "system.hh"
-#else
-#include "prog.hh"
-#endif
-
-using namespace std;
-
-// constructor
-#ifdef FULL_SYSTEM
-ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
-                         AlphaItb *_itb, AlphaDtb *_dtb,
-                         FunctionalMemory *_mem, int _cpu_id)
-    : kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num), mem(_mem),
-      itb(_itb), dtb(_dtb), cpu_id(_cpu_id), system(_sys),
-      memCtrl(_sys->memCtrl), physmem(_sys->physmem)
-{
-    memset(&regs, 0, sizeof(RegFile));
-    _status = Active;
-    func_exe_insn = 0;
-    storeCondFailures = 0;
-    system->registerExecContext(this);
-}
-#else
-ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
-                         Process *_process, int _asid)
-    : cpu(_cpu), thread_num(_thread_num), process(_process), asid (_asid)
-{
-
-    // Register with process object. Our 'active' will be set by the
-    // process iff we're the initial context.  Others are reserved for
-    // dynamically created threads.
-    process->registerExecContext(this);
-
-    mem = process->getMemory();
-
-    func_exe_insn = 0;
-    storeCondFailures = 0;
-}
-
-ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
-                         FunctionalMemory *_mem, int _asid)
-    : cpu(_cpu), thread_num(_thread_num), process(NULL), mem(_mem),
-      asid(_asid)
-{
-}
-#endif
-
-void
-ExecContext::setStatus(Status new_status)
-{
-#ifdef FULL_SYSTEM
-    if (status() == new_status)
-        return;
-
-    // Don't change the status from active if there are pending interrupts
-    if (new_status == Suspended && cpu->check_interrupts()) {
-        assert(status() == Active);
-        return;
-    }
-#endif
-
-    _status = new_status;
-    cpu->execCtxStatusChg();
-}
-
-void
-ExecContext::regStats(const string &name)
-{
-#ifdef FULL_SYSTEM
-    kernelStats.regStats(name + ".kern");
-#endif
-}
diff --git a/sim/exec_context.hh b/sim/exec_context.hh
deleted file mode 100644 (file)
index 988673a..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __EXEC_CONTEXT_HH__
-#define __EXEC_CONTEXT_HH__
-
-#include "host.hh"
-#include "mem_req.hh"
-
-// forward declaration: see functional_memory.hh
-class FunctionalMemory;
-class PhysicalMemory;
-class BaseCPU;
-
-#ifdef FULL_SYSTEM
-
-#include "alpha_memory.hh"
-class MemoryController;
-
-#include "kernel_stats.hh"
-#include "system.hh"
-
-#else // !FULL_SYSTEM
-
-#include "prog.hh"
-
-#endif // FULL_SYSTEM
-
-//
-// The ExecContext object represents a functional context for
-// instruction execution.  It incorporates everything required for
-// architecture-level functional simulation of a single thread.
-//
-
-class ExecContext
-{
-  public:
-    enum Status { Unallocated, Active, Suspended, Halted };
-
-  private:
-    Status _status;
-
-  public:
-    Status status() const { return _status; }
-    void setStatus(Status new_status);
-
-#ifdef FULL_SYSTEM
-  public:
-    KernelStats kernelStats;
-#endif
-
-  public:
-    RegFile regs;      // correct-path register context
-
-    // pointer to CPU associated with this context
-    BaseCPU *cpu;
-
-    // Index of hardware thread context on the CPU that this represents.
-    int thread_num;
-
-#ifdef FULL_SYSTEM
-
-    FunctionalMemory *mem;
-    AlphaItb *itb;
-    AlphaDtb *dtb;
-    int cpu_id;
-    System *system;
-
-    // the following two fields are redundant, since we can always
-    // look them up through the system pointer, but we'll leave them
-    // here for now for convenience
-    MemoryController *memCtrl;
-    PhysicalMemory *physmem;
-
-#else
-    Process *process;
-
-    FunctionalMemory *mem;     // functional storage for process address space
-
-    // Address space ID.  Note that this is used for TIMING cache
-    // simulation only; all functional memory accesses should use
-    // one of the FunctionalMemory pointers above.
-    short asid;
-
-#endif
-
-
-    /*
-     * number of executed instructions, for matching with syscall trace
-     * points in EIO files.
-     */
-    Counter func_exe_insn;
-
-    //
-    // Count failed store conditionals so we can warn of apparent
-    // application deadlock situations.
-    unsigned storeCondFailures;
-
-    // constructor: initialize context from given process structure
-#ifdef FULL_SYSTEM
-    ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
-                AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_dem,
-                int _cpu_id);
-#else
-    ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
-    ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
-                int _asid);
-#endif
-    virtual ~ExecContext() {}
-
-    void regStats(const std::string &name);
-
-#ifdef FULL_SYSTEM
-    bool validInstAddr(Addr addr) { return true; }
-    bool validDataAddr(Addr addr) { return true; }
-    int getInstAsid() { return ITB_ASN_ASN(regs.ipr[TheISA::IPR_ITB_ASN]); }
-    int getDataAsid() { return DTB_ASN_ASN(regs.ipr[TheISA::IPR_DTB_ASN]); }
-
-    Fault translateInstReq(MemReqPtr req)
-    {
-        return itb->translate(req);
-    }
-
-    Fault translateDataReadReq(MemReqPtr req)
-    {
-        return dtb->translate(req, false);
-    }
-
-    Fault translateDataWriteReq(MemReqPtr req)
-    {
-        return dtb->translate(req, true);
-    }
-
-
-#else
-    bool validInstAddr(Addr addr)
-    { return process->validInstAddr(addr); }
-
-    bool validDataAddr(Addr addr)
-    { return process->validDataAddr(addr); }
-
-    int getInstAsid() { return asid; }
-    int getDataAsid() { return asid; }
-
-    Fault dummyTranslation(MemReqPtr req)
-    {
-#if 0
-        assert((req->vaddr >> 48 & 0xffff) == 0);
-#endif
-
-        // put the asid in the upper 16 bits of the paddr
-        req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
-        req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
-        return No_Fault;
-    }
-    Fault translateInstReq(MemReqPtr req)
-    {
-        return dummyTranslation(req);
-    }
-    Fault translateDataReadReq(MemReqPtr req)
-    {
-        return dummyTranslation(req);
-    }
-    Fault translateDataWriteReq(MemReqPtr req)
-    {
-        return dummyTranslation(req);
-    }
-
-#endif
-
-    template <class T>
-    Fault read(MemReqPtr req, T& data)
-    {
-#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
-        if (req->flags & LOCKED) {
-            MiscRegFile *cregs = &req->xc->regs.miscRegs;
-            cregs->lock_addr = req->paddr;
-            cregs->lock_flag = true;
-        }
-#endif
-        return mem->read(req, data);
-    }
-
-    template <class T>
-    Fault write(MemReqPtr req, T& data)
-    {
-#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
-
-        MiscRegFile *cregs;
-
-        // If this is a store conditional, act appropriately
-        if (req->flags & LOCKED) {
-            cregs = &req->xc->regs.miscRegs;
-
-            if (req->flags & UNCACHEABLE) {
-                // Don't update result register (see machine.def)
-                req->result = 2;
-                req->xc->storeCondFailures = 0;//Needed? [RGD]
-            } else {
-                req->result = cregs->lock_flag;
-                if (!cregs->lock_flag ||
-                    ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) {
-                    cregs->lock_flag = false;
-                    if (((++req->xc->storeCondFailures) % 100000) == 0) {
-                        std::cerr << "Warning: "
-                                  << req->xc->storeCondFailures
-                                  << " consecutive store conditional failures "
-                                  << "on cpu " << req->xc->cpu_id
-                                  << std::endl;
-                    }
-                    return No_Fault;
-                }
-                else req->xc->storeCondFailures = 0;
-            }
-        }
-
-        // Need to clear any locked flags on other proccessors for this
-        // address
-        // Only do this for succsful Store Conditionals and all other
-        // stores (WH64?)
-        // Unsuccesful Store Conditionals would have returned above,
-        // and wouldn't fall through
-        for(int i = 0; i < system->num_cpus; i++){
-            cregs = &system->xc_array[i]->regs.miscRegs;
-            if((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) {
-                cregs->lock_flag = false;
-            }
-        }
-
-#endif
-        return mem->write(req, data);
-    }
-
-    virtual bool misspeculating();
-
-
-    //
-    // New accessors for new decoder.
-    //
-    uint64_t readIntReg(int reg_idx)
-    {
-        return regs.intRegFile[reg_idx];
-    }
-
-    float readFloatRegSingle(int reg_idx)
-    {
-        return (float)regs.floatRegFile.d[reg_idx];
-    }
-
-    double readFloatRegDouble(int reg_idx)
-    {
-        return regs.floatRegFile.d[reg_idx];
-    }
-
-    uint64_t readFloatRegInt(int reg_idx)
-    {
-        return regs.floatRegFile.q[reg_idx];
-    }
-
-    void setIntReg(int reg_idx, uint64_t val)
-    {
-        regs.intRegFile[reg_idx] = val;
-    }
-
-    void setFloatRegSingle(int reg_idx, float val)
-    {
-        regs.floatRegFile.d[reg_idx] = (double)val;
-    }
-
-    void setFloatRegDouble(int reg_idx, double val)
-    {
-        regs.floatRegFile.d[reg_idx] = val;
-    }
-
-    void setFloatRegInt(int reg_idx, uint64_t val)
-    {
-        regs.floatRegFile.q[reg_idx] = val;
-    }
-
-    uint64_t readPC()
-    {
-        return regs.pc;
-    }
-
-    void setNextPC(uint64_t val)
-    {
-        regs.npc = val;
-    }
-
-    uint64_t readUniq()
-    {
-        return regs.miscRegs.uniq;
-    }
-
-    void setUniq(uint64_t val)
-    {
-        regs.miscRegs.uniq = val;
-    }
-
-    uint64_t readFpcr()
-    {
-        return regs.miscRegs.fpcr;
-    }
-
-    void setFpcr(uint64_t val)
-    {
-        regs.miscRegs.fpcr = val;
-    }
-
-#ifdef FULL_SYSTEM
-    uint64_t readIpr(int idx, Fault &fault);
-    Fault setIpr(int idx, uint64_t val);
-    Fault hwrei();
-    void ev5_trap(Fault fault);
-    bool simPalCheck(int palFunc);
-#endif
-
-#ifndef FULL_SYSTEM
-    void syscall()
-    {
-        process->syscall(this);
-    }
-#endif
-};
-
-
-// for non-speculative execution context, spec_mode is always false
-inline bool
-ExecContext::misspeculating()
-{
-    return false;
-}
-
-#endif // __EXEC_CONTEXT_HH__
diff --git a/sim/exetrace.cc b/sim/exetrace.cc
deleted file mode 100644 (file)
index 4c5d148..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fstream>
-#include <iomanip>
-
-#include "dyn_inst.hh"
-#include "spec_state.hh"
-#include "issue.hh"
-#include "exetrace.hh"
-#include "exec_context.hh"
-#include "symtab.hh"
-#include "base_cpu.hh"
-#include "static_inst.hh"
-
-using namespace std;
-
-
-////////////////////////////////////////////////////////////////////////
-//
-//  Methods for the InstRecord object
-//
-
-
-const SymbolTable *debugSymbolTable = NULL;
-
-void
-Trace::InstRecord::dump(ostream &outs)
-{
-    if (flags[PRINT_CYCLE])
-        ccprintf(outs, "%7d: ", cycle);
-
-    outs << cpu->name() << " ";
-
-    if (flags[TRACE_MISSPEC])
-        outs << (misspeculating ? "-" : "+") << " ";
-
-    if (flags[PRINT_THREAD_NUM])
-        outs << "T" << thread << " : ";
-
-    outs << "0x" << hex << PC << " : ";
-
-    //
-    //  Print decoded instruction
-    //
-
-#if defined(__GNUC__) && (__GNUC__ < 3)
-    // There's a bug in gcc 2.x library that prevents setw()
-    // from working properly on strings
-    string mc(staticInst->disassemble(PC, debugSymbolTable));
-    while (mc.length() < 25)
-        mc += " ";
-    outs << mc;
-#else
-    outs << setw(25) << staticInst->disassemble(PC, debugSymbolTable);
-#endif
-
-    outs << " : ";
-
-    if (flags[PRINT_OP_CLASS]) {
-        outs << opClassStrings[staticInst->opClass()] << " : ";
-    }
-
-    if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) {
-        outs << " D=";
-#if 0
-        if (data_status == DataDouble)
-            ccprintf(outs, "%f", data.as_double);
-        else
-            ccprintf(outs, "%#018x", data.as_int);
-#else
-        ccprintf(outs, "%#018x", data.as_int);
-#endif
-    }
-
-    if (flags[PRINT_EFF_ADDR] && addr_valid)
-        outs << " A=0x" << hex << addr;
-
-    if (flags[PRINT_INT_REGS] && regs_valid) {
-        for (int i = 0; i < 32;)
-            for (int j = i + 1; i <= j; i++)
-                ccprintf(outs, "r%02d = %#018x%s", i, iregs->regs[i],
-                         ((i == j) ? "\n" : "    "));
-        outs << "\n";
-    }
-
-    if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
-        outs << "  FetchSeq=" << dec << fetch_seq;
-
-    if (flags[PRINT_CP_SEQ] && cp_seq_valid)
-        outs << "  CPSeq=" << dec << cp_seq;
-
-    //
-    //  End of line...
-    //
-    outs << endl;
-    outs.flush();
-}
-
-
-vector<bool> Trace::InstRecord::flags(NUM_BITS);
-
-////////////////////////////////////////////////////////////////////////
-//
-// Parameter space for per-cycle execution address tracing options.
-// Derive from ParamContext so we can override checkParams() function.
-//
-class ExecutionTraceParamContext : public ParamContext
-{
-  public:
-    ExecutionTraceParamContext(const string &_iniSection)
-        : ParamContext(_iniSection)
-        {
-        }
-
-    void checkParams();        // defined at bottom of file
-};
-
-ExecutionTraceParamContext exeTraceParams("exetrace");
-
-Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
-                           "capture speculative instructions", false);
-
-Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
-                                  "print cycle number", true);
-Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
-                                  "print op class", true);
-Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
-                                  "print thread number", true);
-Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
-                                  "print effective address", true);
-Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
-                                  "print result data", true);
-Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
-                                  "print all integer regs", false);
-Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
-                                  "print fetch sequence number", false);
-Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
-                                  "print correct-path sequence number", false);
-
-//
-// Helper function for ExecutionTraceParamContext::checkParams() just
-// to get us into the InstRecord namespace
-//
-void
-Trace::InstRecord::setParams()
-{
-    flags[TRACE_MISSPEC]     = exe_trace_spec;
-
-    flags[PRINT_CYCLE]       = exe_trace_print_cycle;
-    flags[PRINT_OP_CLASS]    = exe_trace_print_opclass;
-    flags[PRINT_THREAD_NUM]  = exe_trace_print_thread;
-    flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
-    flags[PRINT_EFF_ADDR]    = exe_trace_print_data;
-    flags[PRINT_INT_REGS]    = exe_trace_print_iregs;
-    flags[PRINT_FETCH_SEQ]   = exe_trace_print_fetchseq;
-    flags[PRINT_CP_SEQ]      = exe_trace_print_cp_seq;
-}
-
-void
-ExecutionTraceParamContext::checkParams()
-{
-    Trace::InstRecord::setParams();
-}
-
diff --git a/sim/exetrace.hh b/sim/exetrace.hh
deleted file mode 100644 (file)
index 2eb7753..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __EXETRACE_HH__
-#define __EXETRACE_HH__
-
-#include <fstream>
-#include <vector>
-
-#include "host.hh"
-#include "inst_seq.hh" // for InstSeqNum
-#include "trace.hh"
-#include "exec_context.hh"
-#include "static_inst.hh"
-
-class BaseCPU;
-
-
-namespace Trace {
-
-#if 0
-    static const FlagVec ALL =                 ULL(0x1);
-    static const FlagVec FULL =                        ULL(0x2);
-    static const FlagVec SYMBOLS =             ULL(0x4);
-    static const FlagVec EXTENDED =            ULL(0x8);
-    static const FlagVec BRANCH_TAKEN =        ULL(0x10);
-    static const FlagVec BRANCH_NOTTAKEN =     ULL(0x20);
-    static const FlagVec CALLPAL =             ULL(0x40);
-    static const FlagVec SPECULATIVE =         ULL(0x100);
-    static const FlagVec OMIT_COUNT =          ULL(0x200);
-    static const FlagVec INCLUDE_THREAD_NUM =  ULL(0x400);
-#endif
-
-class InstRecord : public Record
-{
-  protected:
-
-    // The following fields are initialized by the constructor and
-    // thus guaranteed to be valid.
-    BaseCPU *cpu;
-    // need to make this ref-counted so it doesn't go away before we
-    // dump the record
-    StaticInstPtr<TheISA> staticInst;
-    Addr PC;
-    bool misspeculating;
-    unsigned thread;
-
-    // The remaining fields are only valid for particular instruction
-    // types (e.g, addresses for memory ops) or when particular
-    // options are enabled (e.g., tracing full register contents).
-    // Each data field has an associated valid flag to indicate
-    // whether the data field is valid.
-    Addr addr;
-    bool addr_valid;
-
-    union {
-        uint64_t as_int;
-        double as_double;
-    } data;
-    enum {
-        DataInvalid = 0,
-        DataInt8 = 1,  // set to equal number of bytes
-        DataInt16 = 2,
-        DataInt32 = 4,
-        DataInt64 = 8,
-        DataDouble = 3
-    } data_status;
-
-    InstSeqNum fetch_seq;
-    bool fetch_seq_valid;
-
-    InstSeqNum cp_seq;
-    bool cp_seq_valid;
-
-    struct iRegFile {
-        IntRegFile regs;
-    };
-    iRegFile *iregs;
-    bool regs_valid;
-
-  public:
-    InstRecord(Tick _cycle, BaseCPU *_cpu, StaticInstPtr<TheISA> _staticInst,
-               Addr _pc, bool spec, unsigned _thread)
-        : Record(_cycle), cpu(_cpu), staticInst(_staticInst), PC(_pc),
-          misspeculating(spec), thread(_thread)
-    {
-        data_status = DataInvalid;
-        addr_valid = false;
-        regs_valid = false;
-
-        fetch_seq_valid = false;
-        cp_seq_valid = false;
-    }
-
-    virtual ~InstRecord() { }
-
-    virtual void dump(std::ostream &outs);
-
-    void setAddr(Addr a) { addr = a; addr_valid = true; }
-
-    void setData(uint64_t d) { data.as_int = d; data_status = DataInt64; }
-    void setData(uint32_t d) { data.as_int = d; data_status = DataInt32; }
-    void setData(uint16_t d) { data.as_int = d; data_status = DataInt16; }
-    void setData(uint8_t d) { data.as_int = d; data_status = DataInt8; }
-
-    void setData(int64_t d) { setData((uint64_t)d); }
-    void setData(int32_t d) { setData((uint32_t)d); }
-    void setData(int16_t d) { setData((uint16_t)d); }
-    void setData(int8_t d)  { setData((uint8_t)d); }
-
-    void setData(double d) { data.as_double = d; data_status = DataDouble; }
-
-    void setFetchSeq(InstSeqNum seq)
-    { fetch_seq = seq; fetch_seq_valid = true; }
-
-    void setCPSeq(InstSeqNum seq)
-    { cp_seq = seq; cp_seq_valid = true; }
-
-    void setRegs(const IntRegFile &regs);
-
-    void finalize() { theLog.append(this); }
-
-    enum InstExecFlagBits {
-        TRACE_MISSPEC = 0,
-        PRINT_CYCLE,
-        PRINT_OP_CLASS,
-        PRINT_THREAD_NUM,
-        PRINT_RESULT_DATA,
-        PRINT_EFF_ADDR,
-        PRINT_INT_REGS,
-        PRINT_FETCH_SEQ,
-        PRINT_CP_SEQ,
-        NUM_BITS
-    };
-
-    static std::vector<bool> flags;
-
-    static void setParams();
-
-    static bool traceMisspec() { return flags[TRACE_MISSPEC]; }
-};
-
-
-inline void
-InstRecord::setRegs(const IntRegFile &regs)
-{
-    if (!iregs)
-      iregs = new iRegFile;
-
-    memcpy(&iregs->regs, regs, sizeof(IntRegFile));
-    regs_valid = true;
-}
-
-inline
-InstRecord *
-getInstRecord(Tick cycle, ExecContext *xc, BaseCPU *cpu,
-              const StaticInstPtr<TheISA> staticInst,
-              Addr pc, int thread = 0)
-{
-    if (DTRACE(InstExec) &&
-        (InstRecord::traceMisspec() || !xc->misspeculating())) {
-        return new InstRecord(cycle, cpu, staticInst, pc,
-                              xc->misspeculating(), thread);
-    }
-
-    return NULL;
-}
-
-
-}
-
-#endif // __EXETRACE_HH__
diff --git a/sim/hybrid_pred.cc b/sim/hybrid_pred.cc
deleted file mode 100644 (file)
index ed7f781..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <sstream>
-
-#include "hybrid_pred.hh"
-#include "statistics.hh"
-#include "sim_stats.hh"
-
-using namespace std;
-
-HybridPredictor::HybridPredictor(const char *_p_name, const char *_z_name,
-                                 const char *_o_name,
-                                 unsigned _index_bits, unsigned _counter_bits,
-                                 unsigned _zero_change, unsigned _one_change,
-                                 unsigned _thresh,
-                                 unsigned _global_bits,
-                                 unsigned _global_thresh,
-                                 bool _reg_individual_stats)
-{
-    stringstream local_name, global_name;
-
-    pred_name = _p_name;
-    one_name  = _o_name;
-    zero_name = _z_name;
-    reg_individual_stats = _reg_individual_stats;
-
-    local_name << pred_name.c_str() << ":L";
-    local = new SaturatingCounterPred(local_name.str(), zero_name, one_name,
-                                      _index_bits, _counter_bits,
-                                      _zero_change, _one_change, _thresh);
-
-    global_name << pred_name.c_str() << ":G";
-    global = new SaturatingCounterPred(global_name.str(), zero_name, one_name,
-                                       0, _global_bits, 1, 1, _global_thresh);
-}
-
-void HybridPredictor::regStats()
-{
-    using namespace Statistics;
-
-    string p_name;
-    stringstream description;
-
-    if (reg_individual_stats)
-        p_name = pred_name + ":A";
-    else
-        p_name = pred_name;
-
-
-    //
-    //  Number of predictions
-    //
-    stringstream num_zero_preds;
-    num_zero_preds << p_name << ":" << zero_name << ":preds";
-    description << "number of predictions of " << zero_name;
-    pred_zero
-        .name(num_zero_preds.str())
-        .desc(description.str());
-    description.str("");
-
-    stringstream num_one_preds;
-    num_one_preds << p_name << ":" << one_name << ":preds";
-    description << "number of predictions of " << one_name;
-    pred_one
-        .name(num_one_preds.str())
-        .desc(description.str())
-        ;
-    description.str("");
-
-    //
-    //  Count the number of correct predictions
-    //
-    stringstream num_zero_correct;
-    num_zero_correct << p_name << ":" << zero_name << ":corr_preds";
-    description << "number of correct " << zero_name << " preds" ;
-    correct_pred_zero
-        .name(num_zero_correct.str())
-        .desc(description.str())
-        ;
-    description.str("");
-
-    stringstream num_one_correct;
-    num_one_correct << p_name << ":" << one_name << ":corr_preds";
-    description << "number of correct " << one_name << " preds" ;
-    correct_pred_one
-        .name(num_one_correct.str())
-        .desc(description.str())
-        ;
-    description.str("");
-
-
-    //
-    //  Number of predictor updates
-    //
-    stringstream num_zero_updates;
-    num_zero_updates << p_name << ":" << zero_name << ":updates" ;
-    description << "number of actual " << zero_name << "s" ;
-    record_zero
-        .name(num_zero_updates.str())
-        .desc(description.str())
-        ;
-    description.str("");
-
-    stringstream num_one_updates;
-    num_one_updates << p_name << ":" << one_name << ":updates" ;
-    description << "number of actual " << one_name << "s" ;
-    record_one
-        .name(num_one_updates.str())
-        .desc(description.str())
-        ;
-    description.str("");
-
-    //
-    //  Local & Global predictor stats
-    //
-    if (reg_individual_stats) {
-        local->regStats();
-        global->regStats();
-    }
-}
-
-void HybridPredictor::regFormulas()
-{
-    using namespace Statistics;
-
-    string p_name;
-    stringstream description;
-    stringstream name;
-
-    if (reg_individual_stats)
-        p_name = pred_name + ":A";
-    else
-        p_name = pred_name;
-
-    //
-    //  Number of predictions
-    //
-    name << p_name << ":predictions" ;
-    total_preds
-        .name(name.str())
-        .desc("total number of predictions made")
-        ;
-    total_preds = pred_one + pred_zero;
-    name.str("");
-
-    //
-    //  Fraction of all predictions that are one or zero
-    //
-    name << p_name << ":" << zero_name << ":pred_frac";
-    description << "fraction of all preds that were " << zero_name ;
-    frac_preds_zero
-        .name(name.str())
-        .desc(description.str())
-        ;
-    frac_preds_zero = 100 * record_zero / total_preds;
-    description.str("");
-    name.str("");
-
-    name << p_name << ":" << one_name << ":pred_frac";
-    description << "fraction of all preds that were " << one_name ;
-    frac_preds_one
-        .name(name.str())
-        .desc(description.str())
-        ;
-    frac_preds_one = 100 * record_one / total_preds;
-    description.str("");
-    name.str("");
-
-    //
-    //  Count the number of correct predictions
-    //
-    name << p_name << ":correct_preds" ;
-    total_correct
-        .name(name.str())
-        .desc("total number of correct predictions made")
-        ;
-    total_correct = correct_pred_one + correct_pred_zero;
-    name.str("");
-
-
-    //
-    //  Prediction accuracy rates
-    //
-    name << p_name << ":pred_rate";
-    total_accuracy
-        .name(name.str())
-        .desc("fraction of all preds that were correct")
-        ;
-    total_accuracy = 100 * total_correct / total_preds;
-    name.str("");
-
-    name << p_name << ":" << zero_name << ":pred_rate" ;
-    description << "fraction of "<< zero_name <<" preds that were correct";
-    zero_accuracy
-        .name(name.str())
-        .desc(description.str())
-        ;
-    zero_accuracy = 100 * correct_pred_zero / pred_zero;
-    description.str("");
-    name.str("");
-
-    name << p_name << ":" << one_name << ":pred_rate" ;
-    description << "fraction of "<< one_name <<" preds that were correct";
-    one_accuracy
-        .name(name.str())
-        .desc(description.str())
-        ;
-    one_accuracy = 100 * correct_pred_one / pred_one;
-    description.str("");
-    name.str("");
-
-    //
-    //  Coverage
-    //
-    name << p_name << ":" << zero_name << ":coverage";
-    description << "fraction of " << zero_name
-                << "s that were predicted correctly";
-    zero_coverage
-        .name(name.str())
-        .desc(description.str())
-        ;
-    zero_coverage = 100 * correct_pred_zero / record_zero;
-    description.str("");
-    name.str("");
-
-    name << p_name << ":" << one_name << ":coverage";
-    description << "fraction of " << one_name
-                << "s that were predicted correctly";
-    one_coverage
-        .name(name.str())
-        .desc(description.str())
-        ;
-    one_coverage = 100 * correct_pred_one / record_one;
-    description.str("");
-    name.str("");
-
-    //
-    //  Local & Global predictor stats
-    //
-    if (reg_individual_stats) {
-        local->regFormulas();
-        global->regFormulas();
-    }
-
-}
-
diff --git a/sim/hybrid_pred.hh b/sim/hybrid_pred.hh
deleted file mode 100644 (file)
index f6e14e3..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-//==========================================================================
-//
-//  This predictor takes the AND of a "local" and a "global" predictor
-//  in order to determine its prediction.
-//
-//
-//
-//
-
-#ifndef __HYBRID_PRED_HH__
-#define __HYBRID_PRED_HH__
-
-#include <string>
-
-#include "sat_counter.hh"
-
-#include "statistics.hh"
-#include "sim_stats.hh"
-
-class HybridPredictor : public GenericPredictor
-{
-  private:
-    std::string pred_name;
-    std::string one_name;
-    std::string zero_name;
-    bool reg_individual_stats;
-
-    SaturatingCounterPred *local;
-    SaturatingCounterPred *global;
-
-    unsigned long max_index;
-
-    //
-    //  Stats
-    //
-    Statistics::Scalar<> pred_one; //num_one_preds
-    Statistics::Scalar<> pred_zero; //num_zero_preds
-    Statistics::Scalar<> correct_pred_one; //num_one_correct
-    Statistics::Scalar<> correct_pred_zero; //num_zero_correct
-    Statistics::Scalar<> record_one; //num_one_updates
-    Statistics::Scalar<> record_zero; //num_zero_updates
-
-    Statistics::Formula total_preds;
-    Statistics::Formula frac_preds_zero;
-    Statistics::Formula frac_preds_one;
-    Statistics::Formula total_correct;
-    Statistics::Formula total_accuracy;
-    Statistics::Formula zero_accuracy;
-    Statistics::Formula one_accuracy;
-    Statistics::Formula zero_coverage;
-    Statistics::Formula one_coverage;
-
-  public:
-    HybridPredictor(const char *_p_name, const char *_z_name,
-                    const char *_o_name,
-                    unsigned _index_bits, unsigned _counter_bits,
-                    unsigned _zero_change, unsigned _one_change,
-                    unsigned _thresh,
-                    unsigned _global_bits, unsigned _global_thresh,
-                    bool _reg_individual_stats = false);
-
-    void clear() {
-        global->clear();
-        local->clear();
-    }
-
-    unsigned peek(unsigned long _index) {
-        unsigned l = local->peek(_index);
-        unsigned g = global->peek(_index);
-
-        if (l && g)
-            return 1;
-
-        return 0;
-    }
-
-    unsigned value(unsigned long _index) {
-        unsigned l = local->peek(_index);
-        unsigned g = global->peek(_index);
-
-        l = l & 0xFFFF;
-        g = g & 0xFFFF;
-
-        return  (l << 16) | g;
-
-    }
-
-    unsigned predict(unsigned long _index) {
-        unsigned l = local->predict(_index);
-        unsigned g = global->predict(_index);
-
-        if (l && g) {
-            ++pred_one;
-            return 1;
-        }
-
-        ++pred_zero;
-        return 0;
-    }
-
-
-    //
-    //  This version need only be used if local/global statistics
-    //  will be maintained
-    //
-    unsigned predict(unsigned long _index, unsigned &_pdata) {
-        unsigned l = local->predict(_index);
-        unsigned g = global->predict(_index);
-
-        //
-        //  bit 0 => local predictor result
-        //  bit 1 => global predictor result
-        //
-        _pdata = 0;
-        if (l)
-            _pdata |= 1;
-        if (g)
-            _pdata |= 2;
-        if (l && g) {
-            ++pred_one;
-            return 1;
-        }
-
-        ++pred_zero;
-        return 0;
-    }
-
-    void record(unsigned long _index, unsigned _val, unsigned _predicted) {
-
-        if (_val) {
-            local->record(_index, _val, 0);
-            global->record(_index, _val, 0);
-            ++record_one;
-
-            if (_val == _predicted) {
-                ++correct_pred_one;
-            }
-        } else {
-            local->record(_index, _val, 0);
-            global->record(_index, _val, 0);
-            ++record_zero;
-
-            if (_val == _predicted)
-                ++correct_pred_zero;
-        }
-    }
-
-    void record(unsigned long _index, unsigned _val, unsigned _predicted,
-                unsigned _pdata)
-    {
-
-        local->record(_index, _val, (_pdata & 1));
-        global->record(_index, _val, ((_pdata & 2) ? 1 : 0));
-
-
-        if (_val) {
-            ++record_one;
-
-            if (_val == _predicted)
-                ++correct_pred_one;
-        } else {
-            ++record_zero;
-
-            if (_val == _predicted)
-                ++correct_pred_zero;
-        }
-    }
-
-    void regStats();
-    void regFormulas();
-};
-
-
-#endif  // _HYBRID_PRED_HH__
-
diff --git a/sim/inst_seq.hh b/sim/inst_seq.hh
deleted file mode 100644 (file)
index 9c3898f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __STD_TYPES_HH__
-#define __STD_TYPES_HH__
-
-// inst sequence type, used to order instructions in the ready list,
-// if this rolls over the ready list order temporarily will get messed
-// up, but execution will continue and complete correctly
-typedef unsigned long long InstSeqNum;
-
-// inst tag type, used to tag an operation instance in the IQ
-typedef unsigned int InstTag;
-
-#endif // __STD_TYPES_HH__
diff --git a/sim/intr_control.cc b/sim/intr_control.cc
deleted file mode 100644 (file)
index 7ad32a2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-
-#include "base_cpu.hh"
-#include "intr_control.hh"
-#include "sim_object.hh"
-
-using namespace std;
-
-IntrControl::IntrControl(const string &name, BaseCPU *c)
-    : SimObject(name), cpu(c)
-{}
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
-
-    SimObjectParam<BaseCPU *> cpu;
-
-END_DECLARE_SIM_OBJECT_PARAMS(IntrControl)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(IntrControl)
-
-    INIT_PARAM(cpu, "the processor")
-
-END_INIT_SIM_OBJECT_PARAMS(IntrControl)
-
-CREATE_SIM_OBJECT(IntrControl)
-{
-    return new IntrControl(getInstanceName(), cpu);
-}
-
-REGISTER_SIM_OBJECT("IntrControl", IntrControl)
diff --git a/sim/intr_control.hh b/sim/intr_control.hh
deleted file mode 100644 (file)
index 660d6d7..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __INTR_CONTROL_HH__
-#define __INTR_CONTROL_HH__
-
-#include "misc.hh"
-#include "base_cpu.hh"
-#include "sim_object.hh"
-
-class IntrControl : public SimObject
-{
-  public:
-    BaseCPU *cpu;
-    IntrControl(const std::string &name, BaseCPU *c);
-
-    void clear(int int_num, int index = 0);
-    void post(int int_num, int index = 0);
-};
-
-inline void
-IntrControl::post(int int_num, int index)
-{ cpu->post_interrupt(int_num, index); }
-
-inline void
-IntrControl::clear(int int_num, int index)
-{ cpu->clear_interrupt(int_num, index); }
-
-#endif // __INTR_CONTROL_HH__
-
-
-
-
-
-
-
diff --git a/sim/memtest.cc b/sim/memtest.cc
deleted file mode 100644 (file)
index 70b6fbf..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded
-
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <vector>
-
-#include "memtest.hh"
-#include "misc.hh"
-#include "sim_events.hh"
-#include "main_memory.hh"
-#include "base_cache.hh"
-
-#include "statistics.hh"
-#include "sim_stats.hh"
-
-using namespace std;
-
-MemTest::MemTest(const string &name,
-                 MemInterface *_cache_interface,
-                 FunctionalMemory *main_mem,
-                 FunctionalMemory *check_mem,
-                 unsigned _memorySize,
-                 unsigned _percentReads,
-                 unsigned _percentUncacheable,
-                 unsigned _maxReads,
-                 unsigned _progressInterval,
-                 Addr _traceAddr)
-    : BaseCPU(name, 1),
-      tickEvent(this),
-      cacheInterface(_cache_interface),
-      mainMem(main_mem),
-      checkMem(check_mem),
-      size(_memorySize),
-      percentReads(_percentReads),
-      percentUncacheable(_percentUncacheable),
-      maxReads(_maxReads),
-      progressInterval(_progressInterval),
-      nextProgressMessage(_progressInterval)
-{
-    vector<string> cmd;
-    cmd.push_back("/bin/ls");
-    vector<string> null_vec;
-    xc = new ExecContext(this ,0,mainMem,0);
-
-    blockSize = cacheInterface->getBlockSize();
-    blockAddrMask = blockSize - 1;
-    traceBlockAddr = blockAddr(_traceAddr);
-
-    //setup data storage with interesting values
-    uint8_t *data1 = new uint8_t[size];
-    uint8_t *data2 = new uint8_t[size];
-    uint8_t *data3 = new uint8_t[size];
-    memset(data1, 1, size);
-    memset(data2, 2, size);
-    memset(data3, 3, size);
-    curTick = 0;
-
-    baseAddr1 = 0x100000;
-    baseAddr2 = 0x400000;
-    uncacheAddr = 0x800000;
-
-    // set up intial memory contents here
-    mainMem->prot_write(baseAddr1, data1, size);
-    checkMem->prot_write(baseAddr1, data1, size);
-    mainMem->prot_write(baseAddr2, data2, size);
-    checkMem->prot_write(baseAddr2, data2, size);
-    mainMem->prot_write(uncacheAddr, data3, size);
-    checkMem->prot_write(uncacheAddr, data3, size);
-
-    delete [] data1;
-    delete [] data2;
-    delete [] data3;
-
-    // set up counters
-    noResponseCycles = 0;
-    numReads = 0;
-    numWrites = 0;
-    tickEvent.schedule(0);
-}
-
-static void
-printData(ostream &os, uint8_t *data, int nbytes)
-{
-    os << hex << setfill('0');
-    // assume little-endian: print bytes from highest address to lowest
-    for (uint8_t *dp = data + nbytes - 1; dp >= data; --dp) {
-        os << setw(2) << (unsigned)*dp;
-    }
-    os << dec;
-}
-
-void
-MemTest::completeRequest(MemReqPtr req, uint8_t *data)
-{
-    switch (req->cmd) {
-      case Read:
-        if (memcmp(req->data, data, req->size) != 0) {
-            cerr << name() << ": on read of 0x" << hex << req->paddr
-                 << " @ cycle " << dec << curTick
-                 << ", cache returns 0x";
-            printData(cerr, req->data, req->size);
-            cerr << ", expected 0x";
-            printData(cerr, data, req->size);
-            cerr << endl;
-            fatal("");
-        }
-
-        numReads++;
-
-        if (numReads.val() == nextProgressMessage) {
-            cerr << name() << ": completed " << numReads.val()
-                 << " read accesses @ " << curTick << endl;
-            nextProgressMessage += progressInterval;
-        }
-
-        if (numReads.val() == maxReads) {
-            stringstream stream;
-            stream << name() << " reached max read count (" << maxReads
-                   << ")" << endl;
-
-            new SimExitEvent(stream.str());
-        }
-        break;
-
-      case Write:
-        numWrites++;
-        break;
-
-
-      default:
-        panic("invalid command");
-    }
-
-    if (blockAddr(req->paddr) == traceBlockAddr) {
-        cerr << name() << ": completed "
-             << (req->cmd.isWrite() ? "write" : "read") << " access of "
-             << req->size << " bytes at address 0x"
-             << hex << req->paddr << ", value = 0x";
-        printData(cerr, req->data, req->size);
-        cerr << endl;
-    }
-
-    noResponseCycles = 0;
-    delete [] data;
-}
-
-
-void
-MemTest::regStats()
-{
-    using namespace Statistics;
-
-    numReads
-        .name(name() + ".num_reads")
-        .desc("number of read accesses completed")
-        ;
-
-    numWrites
-        .name(name() + ".num_writes")
-        .desc("number of write accesses completed")
-        ;
-
-    numCopies
-        .name(name() + ".num_copies")
-        .desc("number of copy accesses completed")
-        ;
-}
-
-void
-MemTest::tick()
-{
-    if (!tickEvent.scheduled())
-        tickEvent.schedule(curTick + 1);
-
-    if (++noResponseCycles >= 5000) {
-        cerr << name() << ": deadlocked at cycle " << curTick << endl;
-        fatal("");
-    }
-
-    if (cacheInterface->isBlocked()) {
-        return;
-    }
-
-    //make new request
-    unsigned cmd = rand() % 100;
-    unsigned offset1 = random() % size;
-    unsigned base = random() % 2;
-    uint64_t data = random();
-    unsigned access_size = random() % 4;
-    unsigned cacheable = rand() % 100;
-
-    MemReqPtr req = new MemReq();
-
-    if (cacheable < percentUncacheable) {
-        req->flags |= UNCACHEABLE;
-        req->paddr = uncacheAddr + offset1;
-    } else {
-        req->paddr = ((base) ? baseAddr1 : baseAddr2) + offset1;
-    }
-
-    req->size = 1 << access_size;
-    req->data = new uint8_t[req->size];
-    req->paddr &= ~(req->size - 1);
-    req->time = curTick;
-    req->xc = xc;
-
-    if (cmd < percentReads) {
-        // read
-        req->cmd = Read;
-        uint8_t *result = new uint8_t[8];
-        checkMem->access(Read, req->paddr, result, req->size);
-        if (blockAddr(req->paddr) == traceBlockAddr) {
-            cerr << name() << ": initiating read of "
-                 << req->size << " bytes from addr 0x"
-                 << hex << req->paddr << " at cycle "
-                 << dec << curTick << endl;
-        }
-
-        req->completionEvent = new MemCompleteEvent(req, result, this);
-        cacheInterface->access(req);
-    } else {
-        // write
-        req->cmd = Write;
-        memcpy(req->data, &data, req->size);
-        checkMem->access(Write, req->paddr, req->data, req->size);
-        if (blockAddr(req->paddr) == traceBlockAddr) {
-            cerr << name() << ": initiating write of "
-                 << req->size << " bytes (value = 0x";
-            printData(cerr, req->data, req->size);
-            cerr << ") to addr 0x"
-                 << hex << req->paddr << " at cycle "
-                 << dec << curTick << endl;
-        }
-        req->completionEvent = new MemCompleteEvent(req, NULL, this);
-        cacheInterface->access(req);
-    }
-}
-
-
-void
-MemCompleteEvent::process()
-{
-    tester->completeRequest(req, data);
-    delete this;
-}
-
-
-const char *
-MemCompleteEvent::description()
-{
-    return "memory access completion";
-}
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
-
-    SimObjectParam<BaseCache *> cache;
-    SimObjectParam<FunctionalMemory *> main_mem;
-    SimObjectParam<FunctionalMemory *> check_mem;
-    Param<unsigned> memory_size;
-    Param<unsigned> percent_reads;
-    Param<unsigned> percent_uncacheable;
-    Param<unsigned> max_reads;
-    Param<unsigned> progress_interval;
-    Param<Addr> trace_addr;
-
-END_DECLARE_SIM_OBJECT_PARAMS(MemTest)
-
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest)
-
-    INIT_PARAM(cache, "L1 cache"),
-    INIT_PARAM(main_mem, "hierarchical memory"),
-    INIT_PARAM(check_mem, "check memory"),
-    INIT_PARAM_DFLT(memory_size, "memory size", 65536),
-    INIT_PARAM_DFLT(percent_reads, "target read percentage", 65),
-    INIT_PARAM_DFLT(percent_uncacheable, "target uncacheable percentage", 10),
-    INIT_PARAM_DFLT(max_reads, "number of reads to simulate", 0),
-    INIT_PARAM_DFLT(progress_interval,
-                    "progress report interval (in accesses)", 1000000),
-    INIT_PARAM_DFLT(trace_addr, "address to trace", 0)
-
-END_INIT_SIM_OBJECT_PARAMS(MemTest)
-
-
-CREATE_SIM_OBJECT(MemTest)
-{
-    return new MemTest(getInstanceName(), cache->getInterface(), main_mem,
-                       check_mem,
-                       memory_size, percent_reads,
-                       percent_uncacheable, max_reads, progress_interval,
-                       trace_addr);
-}
-
-REGISTER_SIM_OBJECT("MemTest", MemTest)
diff --git a/sim/memtest.hh b/sim/memtest.hh
deleted file mode 100644 (file)
index aa652ab..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __MEMTEST_HH__
-#define __MEMTEST_HH__
-
-#include "sim_object.hh"
-#include "mem_interface.hh"
-#include "functional_memory.hh"
-#include "base_cpu.hh"
-#include "exec_context.hh"
-
-#include "statistics.hh"
-#include "sim_stats.hh"
-
-class MemTest : public BaseCPU
-{
-  public:
-
-    MemTest(const std::string &name,
-            MemInterface *_cache_interface,
-            FunctionalMemory *main_mem,
-            FunctionalMemory *check_mem,
-            unsigned _memorySize,
-            unsigned _percentReads,
-            unsigned _percentUncacheable,
-            unsigned _maxReads,
-            unsigned _progressInterval,
-            Addr _traceAddr);
-
-    // register statistics
-    virtual void regStats();
-    // main simulation loop (one cycle)
-    void tick();
-
-  protected:
-    class TickEvent : public Event
-    {
-      private:
-        MemTest *cpu;
-      public:
-        TickEvent(MemTest *c)
-            : Event(&mainEventQueue, 100), cpu(c) {}
-        void process() {cpu->tick();}
-        virtual const char *description() { return "tick event"; }
-    };
-
-    TickEvent tickEvent;
-
-    MemInterface *cacheInterface;
-    FunctionalMemory *mainMem;
-    FunctionalMemory *checkMem;
-    ExecContext *xc;
-
-    unsigned size;             // size of testing memory region
-
-    unsigned percentReads;     // target percentage of read accesses
-    unsigned percentUncacheable;
-
-    Tick maxReads;             // max # of reads to perform (then quit)
-
-    unsigned blockSize;
-
-    Addr blockAddrMask;
-
-    Addr blockAddr(Addr addr)
-    {
-        return (addr & ~blockAddrMask);
-    }
-
-    Addr traceBlockAddr;
-
-    Addr baseAddr1;            // fix this to option
-    Addr baseAddr2;            // fix this to option
-    Addr uncacheAddr;
-
-    unsigned progressInterval; // frequency of progress reports
-    Tick nextProgressMessage;  // access # for next progress report
-
-    Tick noResponseCycles;
-
-    Statistics::Scalar<long long int> numReads;
-    Statistics::Scalar<long long int> numWrites;
-    Statistics::Scalar<long long int> numCopies;
-
-    // called by MemCompleteEvent::process()
-    void completeRequest(MemReqPtr req, uint8_t *data);
-
-    friend class MemCompleteEvent;
-};
-
-
-class MemCompleteEvent : public Event
-{
-    MemReqPtr req;
-    uint8_t *data;
-    MemTest *tester;
-
-  public:
-
-    MemCompleteEvent(MemReqPtr _req, uint8_t *_data, MemTest *_tester)
-        : Event(&mainEventQueue),
-          req(_req), data(_data), tester(_tester)
-    {
-    }
-
-    void process();
-
-    virtual const char *description();
-};
-
-#endif // __MEMTEST_HH__
-
-
-
diff --git a/sim/op_class.hh b/sim/op_class.hh
deleted file mode 100644 (file)
index 67ccaab..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __OP_CLASS_HH__
-#define __OP_CLASS_HH__
-
-/**
- * @file
- * Definition of operation classes.
- */
-
-/**
- * Instruction operation classes.  These classes are used for
- * assigning instructions to functional units.
- */
-enum OpClass {
-    No_OpClass = 0,    /* inst does not use a functional unit */
-    IntALU,            /* integer ALU */
-    IntMULT,           /* integer multiplier */
-    IntDIV,            /* integer divider */
-    FloatADD,          /* floating point adder/subtractor */
-    FloatCMP,          /* floating point comparator */
-    FloatCVT,          /* floating point<->integer converter */
-    FloatMULT,         /* floating point multiplier */
-    FloatDIV,          /* floating point divider */
-    FloatSQRT,         /* floating point square root */
-    RdPort,            /* memory read port */
-    WrPort,            /* memory write port */
-    LvqPort,           /* load value queue read port (redundant threading) */
-    IPrefPort,
-    Num_OpClasses      /* total functional unit classes */
-};
-
-/**
- * Array mapping OpClass enum values to strings.
- */
-extern const char *opClassStrings[];
-
-#endif // __OP_CLASS_HH__
diff --git a/sim/pc_event.cc b/sim/pc_event.cc
deleted file mode 100644 (file)
index 4de4251..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <algorithm>
-#include <map>
-#include <string>
-#include <utility>
-
-#include "debug.hh"
-#include "exec_context.hh"
-#include "pc_event.hh"
-#include "trace.hh"
-#include "universe.hh"
-
-#ifdef FULL_SYSTEM
-#include "arguments.hh"
-#include "pmap.h"
-#include "kernel.hh"
-#include "memory_control.hh"
-#include "cpu.hh"
-#include "system.hh"
-#include "bpred.hh"
-#endif
-
-using namespace std;
-
-PCEventQueue::PCEventQueue()
-{}
-
-PCEventQueue::~PCEventQueue()
-{}
-
-bool
-PCEventQueue::remove(PCEvent *event)
-{
-    int removed = 0;
-    range_t range = equal_range(event);
-    for (iterator i = range.first; i != range.second; ++i) {
-        if (*i == event) {
-            DPRINTF(PCEvent, "PC based event removed at %#x: %s\n",
-                    event->pc(), event->descr());
-            pc_map.erase(i);
-            ++removed;
-        }
-    }
-
-    return removed > 0;
-}
-
-bool
-PCEventQueue::schedule(PCEvent *event)
-{
-    pc_map.push_back(event);
-    sort(pc_map.begin(), pc_map.end(), MapCompare());
-
-    DPRINTF(PCEvent, "PC based event scheduled for %#x: %s\n",
-            event->pc(), event->descr());
-
-    return true;
-}
-
-bool
-PCEventQueue::service(ExecContext *xc)
-{
-    Addr pc = xc->regs.pc;
-    int serviced = 0;
-    range_t range = equal_range(pc);
-    for (iterator i = range.first; i != range.second; ++i) {
-        // Make sure that the pc wasn't changed as the side effect of
-        // another event.  This for example, prevents two invocations
-        // of the SkipFuncEvent.  Maybe we should have separate PC
-        // event queues for each processor?
-        if (pc != xc->regs.pc)
-            continue;
-
-        DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n",
-                (*i)->pc(), (*i)->descr());
-
-        (*i)->process(xc);
-        ++serviced;
-    }
-
-    return serviced > 0;
-}
-
-void
-PCEventQueue::dump() const
-{
-    const_iterator i = pc_map.begin();
-    const_iterator e = pc_map.end();
-
-    for (; i != e; ++i)
-        cprintf("%d: event at %#x: %s\n", curTick, (*i)->pc(),
-                (*i)->descr());
-}
-
-PCEventQueue::range_t
-PCEventQueue::equal_range(Addr pc)
-{
-    return std::equal_range(pc_map.begin(), pc_map.end(), pc, MapCompare());
-}
-
-#ifdef FULL_SYSTEM
-void
-SkipFuncEvent::process(ExecContext *xc)
-{
-    Addr newpc = xc->regs.intRegFile[ReturnAddressReg];
-
-    DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description,
-            xc->regs.pc, newpc);
-
-    xc->regs.pc = newpc;
-    xc->regs.npc = xc->regs.pc + sizeof(MachInst);
-
-    BranchPred *bp = xc->cpu->getBranchPred();
-    if (bp != NULL) {
-        bp->popRAS(xc->thread_num);
-    }
-}
-
-void
-BadAddrEvent::process(ExecContext *xc)
-{
-    // The following gross hack is the equivalent function to the
-    // annotation for vmunix::badaddr in:
-    // simos/simulation/apps/tcl/osf/tlaser.tcl
-
-    uint64_t a0 = xc->regs.intRegFile[ArgumentReg0];
-
-    if (a0 < ALPHA_K0SEG_BASE || a0 >= ALPHA_K1SEG_BASE ||
-        xc->memCtrl->badaddr(ALPHA_K0SEG_TO_PHYS(a0) & PA_IMPL_MASK)) {
-
-        DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0);
-        xc->regs.intRegFile[ReturnValueReg] = 0x1;
-        SkipFuncEvent::process(xc);
-    }
-    else
-        DPRINTF(BADADDR, "badaddr arg=%#x good\n", a0);
-}
-
-void
-PrintfEvent::process(ExecContext *xc)
-{
-    if (DTRACE(Printf)) {
-        DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
-
-        AlphaArguments args(xc);
-        Kernel::Printf(args);
-    }
-}
-
-void
-DebugPrintfEvent::process(ExecContext *xc)
-{
-    if (DTRACE(DebugPrintf)) {
-        if (!raw)
-            DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
-
-        AlphaArguments args(xc);
-        Kernel::Printf(args);
-    }
-}
-
-void
-DumpMbufEvent::process(ExecContext *xc)
-{
-    if (DTRACE(DebugPrintf)) {
-        AlphaArguments args(xc);
-        Kernel::DumpMbuf(args);
-    }
-}
-#endif
-
-BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del)
-    : PCEvent(q, desc), remove(del)
-{
-}
-
-void
-BreakPCEvent::process(ExecContext *xc)
-{
-    debug_break();
-    if (remove)
-        delete this;
-}
-
-#ifdef FULL_SYSTEM
-extern "C"
-void
-sched_break_pc_sys(System *sys, Addr addr)
-{
-    PCEvent *event = new BreakPCEvent(&sys->pcEventQueue, "debug break", true);
-    event->schedule(addr);
-}
-
-extern "C"
-void
-sched_break_pc(Addr addr)
-{
-     for (vector<System *>::iterator sysi = System::systemList.begin();
-          sysi != System::systemList.end(); ++sysi) {
-         sched_break_pc_sys(*sysi, addr);
-    }
-
-}
-#endif
diff --git a/sim/pc_event.hh b/sim/pc_event.hh
deleted file mode 100644 (file)
index 24442f5..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __PC_EVENT_HH__
-#define __PC_EVENT_HH__
-
-#include <vector>
-
-#include "mem_req.hh"
-
-class ExecContext;
-class PCEventQueue;
-
-class PCEvent
-{
-  protected:
-    static const Addr badpc = MemReq::inval_addr;
-
-  protected:
-    std::string description;
-    PCEventQueue *queue;
-    Addr evpc;
-
-  public:
-    PCEvent() : queue(0), evpc(badpc) { }
-
-    PCEvent(const std::string &desc)
-        : description(desc), queue(0), evpc(badpc) { }
-
-    PCEvent(PCEventQueue *q, Addr pc = badpc) : queue(q), evpc(pc) { }
-
-    PCEvent(PCEventQueue *q, const std::string &desc, Addr pc = badpc)
-        : description(desc), queue(q), evpc(pc) { }
-
-    virtual ~PCEvent() { if (queue) remove(); }
-
-    std::string descr() const { return description; }
-    Addr pc() const { return evpc; }
-
-    bool remove();
-    bool schedule();
-    bool schedule(Addr pc);
-    bool schedule(PCEventQueue *q, Addr pc);
-    virtual void process(ExecContext *xc) = 0;
-};
-
-class PCEventQueue
-{
-  protected:
-    typedef PCEvent * record_t;
-    class MapCompare {
-      public:
-        bool operator()(const record_t &l, const record_t &r) const {
-            return l->pc() < r->pc();
-        }
-        bool operator()(const record_t &l, Addr pc) const {
-            return l->pc() < pc;
-        }
-        bool operator()(Addr pc, const record_t &r) const {
-            return pc < r->pc();
-        }
-    };
-    typedef std::vector<record_t> map_t;
-
-  public:
-    typedef map_t::iterator iterator;
-    typedef map_t::const_iterator const_iterator;
-
-  protected:
-    typedef std::pair<iterator, iterator> range_t;
-    typedef std::pair<const_iterator, const_iterator> const_range_t;
-
-  protected:
-    map_t pc_map;
-
-  public:
-    PCEventQueue();
-    ~PCEventQueue();
-
-    bool remove(PCEvent *event);
-    bool schedule(PCEvent *event);
-    bool service(ExecContext *xc);
-
-    range_t equal_range(Addr pc);
-    range_t equal_range(PCEvent *event) { return equal_range(event->pc()); }
-
-    void dump() const;
-};
-
-inline bool
-PCEvent::remove()
-{
-    if (!queue)
-        panic("cannot remove an uninitialized event;");
-
-    return queue->remove(this);
-}
-
-inline bool
-PCEvent::schedule()
-{
-    if (!queue || evpc == badpc)
-        panic("cannot schedule an uninitialized event;");
-
-    return queue->schedule(this);
-}
-
-inline bool
-PCEvent::schedule(Addr pc)
-{
-    if (evpc != badpc)
-        panic("cannot switch PC");
-    evpc = pc;
-
-    return schedule();
-}
-
-inline bool
-PCEvent::schedule(PCEventQueue *q, Addr pc)
-{
-    if (queue)
-        panic("cannot switch event queues");
-
-    if (evpc != badpc)
-        panic("cannot switch addresses");
-
-    queue = q;
-    evpc = pc;
-
-    return schedule();
-}
-
-
-#ifdef FULL_SYSTEM
-class SkipFuncEvent : public PCEvent
-{
-  public:
-    SkipFuncEvent(PCEventQueue *q, const std::string &desc)
-        : PCEvent(q, desc) {}
-    virtual void process(ExecContext *xc);
-};
-
-class BadAddrEvent : public SkipFuncEvent
-{
-  public:
-    BadAddrEvent(PCEventQueue *q, const std::string &desc)
-        : SkipFuncEvent(q, desc) {}
-    virtual void process(ExecContext *xc);
-};
-
-class PrintfEvent : public PCEvent
-{
-  public:
-    PrintfEvent(PCEventQueue *q, const std::string &desc)
-        : PCEvent(q, desc) {}
-    virtual void process(ExecContext *xc);
-};
-
-class DebugPrintfEvent : public PCEvent
-{
-  private:
-    bool raw;
-
-  public:
-    DebugPrintfEvent(PCEventQueue *q, const std::string &desc, bool r = false)
-        : PCEvent(q, desc), raw(r) {}
-    virtual void process(ExecContext *xc);
-};
-
-class DumpMbufEvent : public PCEvent
-{
-  public:
-    DumpMbufEvent(PCEventQueue *q, const std::string &desc)
-        : PCEvent(q, desc) {}
-    virtual void process(ExecContext *xc);
-};
-#endif
-
-class BreakPCEvent : public PCEvent
-{
-  protected:
-    bool remove;
-
-  public:
-    BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del = false);
-    virtual void process(ExecContext *xc);
-};
-
-
-#endif // __PC_EVENT_HH__
diff --git a/sim/predictor.hh b/sim/predictor.hh
deleted file mode 100644 (file)
index 7c446f2..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-//
-//  Abstract base class for a generic predictor
-//
-//
-
-#ifndef __PREDICTOR_HH__
-#define __PREDICTOR_HH__
-
-struct stat_sdb_t;
-
-class GenericPredictor {
-
-  public:
-    virtual void clear() = 0;
-
-    virtual unsigned predict(unsigned long _index) = 0;
-    virtual unsigned predict(unsigned long _index, unsigned &pdata) = 0;
-
-    virtual unsigned peek(unsigned long _index) = 0;
-
-    virtual void record(unsigned long _index, unsigned _actual_value,
-                        unsigned _pred_value) = 0;
-    virtual void record(unsigned long _index, unsigned _actual_value,
-                        unsigned _pred_value, unsigned _pdata) = 0;
-
-    virtual unsigned value(unsigned long _index) = 0;
-
-    virtual void regStats() = 0;
-    virtual void regFormulas() = 0;
-
-    virtual ~GenericPredictor() {};
-};
-
-#endif //  __PREDICTOR_HH__
diff --git a/sim/sat_counter.cc b/sim/sat_counter.cc
deleted file mode 100644 (file)
index dc365f0..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sstream>
-
-#include "sat_counter.hh"
-
-#include "statistics.hh"
-#include "sim_stats.hh"
-
-
-using namespace std;
-
-
-SaturatingCounterPred::SaturatingCounterPred(string p_name,
-                                             string z_name,
-                                             string o_name,
-                                             unsigned _index_bits,
-                                             unsigned _counter_bits,
-                                             unsigned _zero_change,
-                                             unsigned _one_change,
-                                             unsigned _thresh,
-                                             unsigned _init_value)
-{
-    pred_name    = p_name;
-    zero_name    = z_name;
-    one_name     = o_name;
-
-    index_bits   = _index_bits;
-    counter_bits = _counter_bits;
-    zero_change  = _zero_change;
-    one_change   = _one_change;
-    thresh       = _thresh;
-    init_value   = _init_value;
-
-    max_index = (1 << index_bits) - 1;
-    max_value = (1 << counter_bits) - 1;
-
-    table = new unsigned[max_index + 1];
-
-    //  Initialize with the right parameters & clear the counter
-    for (int i = 0; i <= max_index; ++i)
-        table[i] = init_value;
-}
-
-void SaturatingCounterPred::regStats()
-{
-    using namespace Statistics;
-    stringstream name, description;
-
-    //
-    //  Number of predictions
-    //
-    name << pred_name << ":" << zero_name << ":preds";
-    description << "number of predictions of " << zero_name;
-    predicted_zero
-        .name(name.str())
-        .desc(description.str())
-        ;
-    description.str("");
-    name.str("");
-
-    name << pred_name << ":" << one_name << ":preds";
-    description << "number of predictions of " << one_name;
-    predicted_one
-        .name(name.str())
-        .desc(description.str())
-        ;
-    description.str("");
-    name.str("");
-
-    //
-    //  Count the number of correct predictions
-    //
-    name << pred_name << ":" << zero_name << ":corr_preds";
-    description << "number of correct " << zero_name << " preds";
-    correct_pred_zero
-        .name(name.str())
-        .desc(description.str())
-        ;
-    description.str("");
-    name.str("");
-
-    name << pred_name << ":" << one_name << ":corr_preds";
-    description << "number of correct " << one_name << " preds";
-    correct_pred_one
-        .name(name.str())
-        .desc(description.str())
-        ;
-    description.str("");
-    name.str("");
-
-    //
-    //  Number of predictor updates
-    //
-    name << pred_name << ":" << zero_name << ":updates";
-    description << "number of actual " << zero_name << "s";
-    record_zero
-        .name(name.str())
-        .desc(description.str())
-        ;
-    description.str("");
-    name.str("");
-
-    name << pred_name << ":" << one_name << ":updates";
-    description << "number of actual " << one_name << "s";
-    record_one
-        .name(name.str())
-        .desc(description.str())
-        ;
-    description.str("");
-    name.str("");
-}
-
-void SaturatingCounterPred::regFormulas()
-{
-    using namespace Statistics;
-    stringstream name, description;
-
-    //
-    //  Number of predictions
-    //
-    name << pred_name << ":predictions";
-    preds_total
-        .name(name.str())
-        .desc("total number of predictions made")
-        ;
-    preds_total = predicted_zero + predicted_one;
-    name.str("");
-
-    //
-    //  Fraction of all predictions that are one or zero
-    //
-    name << pred_name << ":" << zero_name << ":pred_frac";
-    description << "fraction of all preds that were " << zero_name;
-    pred_frac_zero
-        .name(name.str())
-        .desc(description.str())
-        ;
-    pred_frac_zero = 100 * predicted_zero / preds_total;
-    description.str("");
-    name.str("");
-
-    name << pred_name << ":" << one_name << ":pred_frac";
-    description << "fraction of all preds that were " << one_name;
-    pred_frac_one
-        .name(name.str())
-        .desc(description.str())
-        ;
-    pred_frac_one = 100 * predicted_one / preds_total;
-    description.str("");
-    name.str("");
-
-
-    //
-    //  Count the number of correct predictions
-    //
-    name << pred_name << ":correct_preds";
-    correct_total
-        .name(name.str())
-        .desc("total correct predictions made")
-        ;
-    correct_total = correct_pred_one + correct_pred_zero;
-    name.str("");
-
-    //
-    //  Number of predictor updates
-    //
-    name << pred_name << ":updates";
-    updates_total
-        .name(name.str())
-        .desc("total number of updates")
-        ;
-    updates_total = record_zero + record_one;
-    name.str("");
-
-    //
-    //  Prediction accuracy rates
-    //
-    name << pred_name << ":pred_rate";
-    pred_rate
-        .name(name.str())
-        .desc("correct fraction of all preds")
-        ;
-    pred_rate = correct_total / updates_total;
-    name.str("");
-
-    name << pred_name << ":" << zero_name << ":pred_rate";
-    description << "fraction of " << zero_name << " preds that were correct";
-    frac_correct_zero
-        .name(name.str())
-        .desc(description.str())
-        ;
-    frac_correct_zero = 100 * correct_pred_zero /
-        (correct_pred_zero + record_one - correct_pred_one);
-    description.str("");
-    name.str("");
-
-    name << pred_name << ":" << one_name << ":pred_rate";
-    description << "fraction of " << one_name << " preds that were correct";
-    frac_correct_one
-        .name(name.str())
-        .desc(description.str())
-        ;
-    frac_correct_one = 100 * correct_pred_one /
-        (correct_pred_one + record_zero - correct_pred_zero);
-    description.str("");
-    name.str("");
-
-    //
-    //  Coverage
-    //
-    name << pred_name << ":" << zero_name << ":coverage";
-    description << "fraction of " << zero_name
-                << "s that were predicted correctly";
-    coverage_zero
-        .name(name.str())
-        .desc(description.str())
-        ;
-    coverage_zero = 100 * correct_pred_zero / record_zero;
-    description.str("");
-    name.str("");
-
-    name << pred_name << ":" << one_name << ":coverage";
-    description << "fraction of " << one_name
-                << "s that were predicted correctly";
-    coverage_one
-        .name(name.str())
-        .desc(description.str())
-        ;
-    coverage_one = 100 * correct_pred_one / record_one;
-    description.str("");
-    name.str("");
-}
-
-
-
-
-
-
-
-
-
-
diff --git a/sim/sat_counter.hh b/sim/sat_counter.hh
deleted file mode 100644 (file)
index 18eab35..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __SAT_COUNTER_HH__
-#define __SAT_COUNTER_HH__
-
-#include <string>
-
-#include "predictor.hh"
-
-#include "statistics.hh"
-#include "sim_stats.hh"
-
-struct stat_sdb_t;
-
-//
-//
-//  A simple saturating counter predictor
-//
-//
-class SaturatingCounterPred : public GenericPredictor
-{
-  private:
-    std::string   pred_name;
-    std::string   zero_name;
-    std::string   one_name;
-
-    unsigned index_bits;
-    unsigned counter_bits;
-    unsigned zero_change;
-    unsigned one_change;
-    unsigned thresh;
-    unsigned init_value;
-
-    unsigned max_value;       // maximum counter value
-
-    unsigned long max_index;  // also the index mask value
-    unsigned *table;
-
-    //  Statistics
-    Statistics::Scalar<> predicted_one;      // Total predictions of one, preds_one
-    Statistics::Scalar<> predicted_zero;     // Total predictions of zero, preds_zero
-    Statistics::Scalar<> correct_pred_one;   // Total correct predictions of one, correct_one
-    Statistics::Scalar<> correct_pred_zero;  // Total correct predictions of zero, correct_zero
-
-    Statistics::Scalar<> record_zero;        //updates_zero
-    Statistics::Scalar<> record_one;         //updates_one
-
-    Statistics::Formula preds_total;
-    Statistics::Formula pred_frac_zero;
-    Statistics::Formula pred_frac_one;
-    Statistics::Formula correct_total;
-    Statistics::Formula updates_total;
-    Statistics::Formula pred_rate;
-    Statistics::Formula frac_correct_zero;
-    Statistics::Formula frac_correct_one;
-    Statistics::Formula coverage_zero;
-    Statistics::Formula coverage_one;
-
-  private:
-    bool pred_one(unsigned &counter)  { return counter >  thresh; }
-    bool pred_zero(unsigned &counter) { return counter <= thresh; }
-
-    void update_one(unsigned &counter) {
-
-        if (one_change)
-            counter += one_change;
-        else
-            counter = 0;
-
-        // check for wrap
-        if (counter > max_value)
-            counter = max_value;
-    }
-
-    void update_zero(unsigned &counter) {
-        if (zero_change) {
-            // check for wrap
-            if (counter < zero_change)
-                counter = 0;
-            else
-                counter -= zero_change;
-        } else
-            counter = 0;
-    }
-
-
-  public:
-
-    SaturatingCounterPred(std::string p_name,
-                          std::string z_name, std::string o_name,
-                          unsigned _index_bits, unsigned _counter_bits = 2,
-                          unsigned _zero_change = 1, unsigned _one_change = 1,
-                          unsigned _thresh = 1, unsigned _init_value = 0);
-
-    void clear() {
-        for (int i = 0; i <= max_index; ++i)
-            table[i] = init_value;
-    }
-
-    //  Record the ACTUAL result... and indicate whether the prediction
-    //  corresponding to this event was correct
-    void record(unsigned long _index, unsigned _val, unsigned _predicted,
-                unsigned _pdata)
-    {
-        record(_index, _val, _predicted);
-    }
-
-    void record(unsigned long _index, unsigned _val, unsigned _predicted) {
-        unsigned long index = _index & max_index;
-
-        if (_val) {
-            update_one(table[index]);
-            ++record_one;
-
-            if (_predicted)
-                ++correct_pred_one;
-        } else {
-            update_zero(table[index]);
-            ++record_zero;
-
-            if (!_predicted)
-                ++correct_pred_zero;
-        }
-    }
-
-    unsigned value(unsigned long _index) {
-        unsigned long index = _index & max_index;
-
-        return table[index];
-    }
-
-
-    unsigned predict(unsigned long _index, unsigned &pdata) {
-        return predict(_index);
-    }
-
-    unsigned predict(unsigned long _index) {
-        unsigned long index = _index & max_index;
-
-        if (pred_one(table[index])) {
-            ++predicted_one;
-            return 1;
-        }
-
-        ++predicted_zero;
-        return 0;
-    }
-
-    //  No internal state is changed here
-    unsigned peek(unsigned long _index) {
-        unsigned long index = _index & max_index;
-
-        if (pred_one(table[index]))
-            return 1;
-
-        return 0;
-    }
-
-
-    //=======================================================
-    void regStats();
-    void regFormulas();
-};
-
-
-#endif // __SAT_COUNTER_HH__
diff --git a/sim/simple_cpu.cc b/sim/simple_cpu.cc
deleted file mode 100644 (file)
index 41a6123..0000000
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <iostream>
-#include <iomanip>
-#include <list>
-#include <sstream>
-#include <string>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "host.hh"
-#include "cprintf.hh"
-#include "misc.hh"
-#include "smt.hh"
-
-#include "annotation.hh"
-#include "exec_context.hh"
-#include "base_cpu.hh"
-#include "debug.hh"
-#include "simple_cpu.hh"
-#include "inifile.hh"
-#include "mem_interface.hh"
-#include "base_mem.hh"
-#include "static_inst.hh"
-
-#ifdef FULL_SYSTEM
-#include "memory_control.hh"
-#include "physical_memory.hh"
-#include "alpha_memory.hh"
-#include "system.hh"
-#else // !FULL_SYSTEM
-#include "functional_memory.hh"
-#include "prog.hh"
-#include "eio.hh"
-#endif // FULL_SYSTEM
-
-#include "exetrace.hh"
-#include "trace.hh"
-#include "sim_events.hh"
-#include "pollevent.hh"
-#include "sim_object.hh"
-#include "sim_stats.hh"
-
-#include "range.hh"
-#include "symtab.hh"
-
-#ifdef FULL_SYSTEM
-#include "vtophys.hh"
-#include "pciareg.h"
-#include "remote_gdb.hh"
-#include "alpha_access.h"
-#endif
-
-
-using namespace std;
-
-SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
-    : Event(&mainEventQueue),
-      cpu(_cpu)
-{
-}
-
-void SimpleCPU::CacheCompletionEvent::process()
-{
-    cpu->processCacheCompletion();
-}
-
-const char *
-SimpleCPU::CacheCompletionEvent::description()
-{
-    return "cache completion event";
-}
-
-#ifdef FULL_SYSTEM
-SimpleCPU::SimpleCPU(const string &_name,
-                     System *_system,
-                     Counter max_insts_any_thread,
-                     Counter max_insts_all_threads,
-                     AlphaItb *itb, AlphaDtb *dtb,
-                     FunctionalMemory *mem,
-                     MemInterface *icache_interface,
-                     MemInterface *dcache_interface,
-                     int cpu_id, Tick freq)
-    : BaseCPU(_name, /* number_of_threads */ 1,
-              max_insts_any_thread, max_insts_all_threads,
-              _system, cpu_id, freq),
-#else
-SimpleCPU::SimpleCPU(const string &_name, Process *_process,
-                     Counter max_insts_any_thread,
-                     Counter max_insts_all_threads,
-                     MemInterface *icache_interface,
-                     MemInterface *dcache_interface)
-    : BaseCPU(_name, /* number_of_threads */ 1,
-              max_insts_any_thread, max_insts_all_threads),
-#endif
-      tickEvent(this), xc(NULL), cacheCompletionEvent(this)
-{
-#ifdef FULL_SYSTEM
-    xc = new ExecContext(this, 0, system, itb, dtb, mem, cpu_id);
-
-    _status = Running;
-    if (cpu_id != 0) {
-
-       xc->setStatus(ExecContext::Unallocated);
-
-       //Open a GDB debug session on port (7000 + the cpu_id)
-       (new GDBListener(new RemoteGDB(system, xc), 7000 + cpu_id))->listen();
-
-       AlphaISA::init(system->physmem, &xc->regs);
-
-       fault = Reset_Fault;
-
-       IntReg *ipr = xc->regs.ipr;
-       ipr[TheISA::IPR_MCSR] = 0x6;
-
-       AlphaISA::swap_palshadow(&xc->regs, true);
-
-       xc->regs.pc =
-           ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault];
-       xc->regs.npc = xc->regs.pc + sizeof(MachInst);
-
-       _status = Idle;
-    }
-    else {
-      system->initBootContext(xc);
-
-      // Reset the system
-      //
-      AlphaISA::init(system->physmem, &xc->regs);
-
-      fault = Reset_Fault;
-
-      IntReg *ipr = xc->regs.ipr;
-      ipr[TheISA::IPR_MCSR] = 0x6;
-
-      AlphaISA::swap_palshadow(&xc->regs, true);
-
-      xc->regs.pc = ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault];
-      xc->regs.npc = xc->regs.pc + sizeof(MachInst);
-
-       _status = Running;
-       tickEvent.schedule(0);
-    }
-
-#else
-    xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0);
-    fault = No_Fault;
-    if (xc->status() == ExecContext::Active) {
-        _status = Running;
-       tickEvent.schedule(0);
-    } else
-        _status = Idle;
-#endif // !FULL_SYSTEM
-
-    icacheInterface = icache_interface;
-    dcacheInterface = dcache_interface;
-
-    memReq = new MemReq();
-    memReq->xc = xc;
-    memReq->asid = 0;
-
-    numInst = 0;
-    last_idle = 0;
-    lastIcacheStall = 0;
-    lastDcacheStall = 0;
-
-    contexts.push_back(xc);
-}
-
-SimpleCPU::~SimpleCPU()
-{
-}
-
-void
-SimpleCPU::regStats()
-{
-    BaseCPU::regStats();
-
-    numInsts
-        .name(name() + ".num_insts")
-        .desc("Number of instructions executed")
-        ;
-
-    numMemRefs
-        .name(name() + ".num_refs")
-        .desc("Number of memory references")
-        ;
-
-    idleCycles
-        .name(name() + ".idle_cycles")
-        .desc("Number of idle cycles")
-        ;
-
-    idleFraction
-        .name(name() + ".idle_fraction")
-        .desc("Percentage of idle cycles")
-        ;
-
-    icacheStallCycles
-        .name(name() + ".icache_stall_cycles")
-        .desc("ICache total stall cycles")
-        .prereq(icacheStallCycles)
-        ;
-
-    dcacheStallCycles
-        .name(name() + ".dcache_stall_cycles")
-        .desc("DCache total stall cycles")
-        .prereq(dcacheStallCycles)
-        ;
-
-    idleFraction = idleCycles / simTicks;
-
-    numInsts = Statistics::scalar(numInst);
-    simInsts += numInsts;
-}
-
-void
-SimpleCPU::serialize()
-{
-    nameOut();
-
-#ifdef FULL_SYSTEM
-#if 0
-    // do we need this anymore?? egh
-    childOut("itb", xc->itb);
-    childOut("dtb", xc->dtb);
-    childOut("physmem", physmem);
-#endif
-#endif
-
-    for (int i = 0; i < NumIntRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "R%02d", i);
-        paramOut(buf.str(), xc->regs.intRegFile[i]);
-    }
-    for (int i = 0; i < NumFloatRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "F%02d", i);
-        paramOut(buf.str(), xc->regs.floatRegFile.d[i]);
-    }
-    // CPUTraitsType::serializeSpecialRegs(getProxy(), xc->regs);
-}
-
-void
-SimpleCPU::unserialize(IniFile &db, const string &category, ConfigNode *node)
-{
-    string data;
-
-    for (int i = 0; i < NumIntRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "R%02d", i);
-        db.findDefault(category, buf.str(), data);
-        to_number(data,xc->regs.intRegFile[i]);
-    }
-    for (int i = 0; i < NumFloatRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "F%02d", i);
-        db.findDefault(category, buf.str(), data);
-        xc->regs.floatRegFile.d[i] = strtod(data.c_str(),NULL);
-    }
-
-    // Read in Special registers
-
-    // CPUTraitsType::unserializeSpecialRegs(db,category,node,xc->regs);
-}
-
-void
-change_thread_state(int thread_number, int activate, int priority)
-{
-}
-
-// precise architected memory state accessor macros
-template <class T>
-Fault
-SimpleCPU::read(Addr addr, T& data, unsigned flags)
-{
-    memReq->reset(addr, sizeof(T), flags);
-
-    // translate to physical address
-    Fault fault = xc->translateDataReadReq(memReq);
-
-    // do functional access
-    if (fault == No_Fault)
-        fault = xc->read(memReq, data);
-
-    if (traceData) {
-        traceData->setAddr(addr);
-        if (fault == No_Fault)
-            traceData->setData(data);
-    }
-
-    // if we have a cache, do cache access too
-    if (fault == No_Fault && dcacheInterface) {
-        memReq->cmd = Read;
-        memReq->completionEvent = NULL;
-        memReq->time = curTick;
-        memReq->flags &= ~UNCACHEABLE;
-        MemAccessResult result = dcacheInterface->access(memReq);
-
-        // Ugly hack to get an event scheduled *only* if the access is
-        // a miss.  We really should add first-class support for this
-        // at some point.
-        if (result != MA_HIT && dcacheInterface->doEvents) {
-            memReq->completionEvent = &cacheCompletionEvent;
-            setStatus(DcacheMissStall);
-        }
-    }
-
-    return fault;
-}
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-template
-Fault
-SimpleCPU::read(Addr addr, uint64_t& data, unsigned flags);
-
-template
-Fault
-SimpleCPU::read(Addr addr, uint32_t& data, unsigned flags);
-
-template
-Fault
-SimpleCPU::read(Addr addr, uint16_t& data, unsigned flags);
-
-template
-Fault
-SimpleCPU::read(Addr addr, uint8_t& data, unsigned flags);
-
-#endif //DOXYGEN_SHOULD_SKIP_THIS
-
-template<>
-Fault
-SimpleCPU::read(Addr addr, double& data, unsigned flags)
-{
-    return read(addr, *(uint64_t*)&data, flags);
-}
-
-template<>
-Fault
-SimpleCPU::read(Addr addr, float& data, unsigned flags)
-{
-    return read(addr, *(uint32_t*)&data, flags);
-}
-
-
-template<>
-Fault
-SimpleCPU::read(Addr addr, int32_t& data, unsigned flags)
-{
-    return read(addr, (uint32_t&)data, flags);
-}
-
-
-template <class T>
-Fault
-SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
-{
-    if (traceData) {
-        traceData->setAddr(addr);
-        traceData->setData(data);
-    }
-
-    memReq->reset(addr, sizeof(T), flags);
-
-    // translate to physical address
-    Fault fault = xc->translateDataWriteReq(memReq);
-
-    // do functional access
-    if (fault == No_Fault)
-        fault = xc->write(memReq, data);
-
-    if (fault == No_Fault && dcacheInterface) {
-        memReq->cmd = Write;
-        memReq->data = (uint8_t *)&data;
-        memReq->completionEvent = NULL;
-        memReq->time = curTick;
-        memReq->flags &= ~UNCACHEABLE;
-        MemAccessResult result = dcacheInterface->access(memReq);
-
-        // Ugly hack to get an event scheduled *only* if the access is
-        // a miss.  We really should add first-class support for this
-        // at some point.
-        if (result != MA_HIT && dcacheInterface->doEvents) {
-            memReq->completionEvent = &cacheCompletionEvent;
-            setStatus(DcacheMissStall);
-        }
-    }
-
-    if (res && (fault == No_Fault))
-        *res = memReq->result;
-
-    return fault;
-}
-
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-template
-Fault
-SimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);
-
-template
-Fault
-SimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);
-
-template
-Fault
-SimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);
-
-template
-Fault
-SimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);
-
-#endif //DOXYGEN_SHOULD_SKIP_THIS
-
-template<>
-Fault
-SimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
-{
-    return write(*(uint64_t*)&data, addr, flags, res);
-}
-
-template<>
-Fault
-SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
-{
-    return write(*(uint32_t*)&data, addr, flags, res);
-}
-
-
-template<>
-Fault
-SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
-{
-    return write((uint32_t)data, addr, flags, res);
-}
-
-
-#ifdef FULL_SYSTEM
-Addr
-SimpleCPU::dbg_vtophys(Addr addr)
-{
-    return vtophys(xc, addr);
-}
-#endif // FULL_SYSTEM
-
-Tick save_cycle = 0;
-
-
-void
-SimpleCPU::processCacheCompletion()
-{
-    switch (status()) {
-      case IcacheMissStall:
-        icacheStallCycles += curTick - lastIcacheStall;
-        setStatus(IcacheMissComplete);
-        break;
-      case DcacheMissStall:
-        dcacheStallCycles += curTick - lastDcacheStall;
-        setStatus(Running);
-        break;
-      default:
-        panic("SimpleCPU::processCacheCompletion: bad state");
-        break;
-    }
-}
-
-#ifdef FULL_SYSTEM
-void
-SimpleCPU::post_interrupt(int int_num, int index)
-{
-    BaseCPU::post_interrupt(int_num, index);
-
-    if (xc->status() == ExecContext::Suspended) {
-                DPRINTF(IPI,"Suspended Processor awoke\n");
-        xc->setStatus(ExecContext::Active);
-        Annotate::Resume(xc);
-    }
-}
-#endif // FULL_SYSTEM
-
-/* start simulation, program loaded, processor precise state initialized */
-void
-SimpleCPU::tick()
-{
-    traceData = NULL;
-
-#ifdef FULL_SYSTEM
-    if (fault == No_Fault && AlphaISA::check_interrupts &&
-        xc->cpu->check_interrupts() &&
-        !PC_PAL(xc->regs.pc) &&
-        status() != IcacheMissComplete) {
-        int ipl = 0;
-        int summary = 0;
-        AlphaISA::check_interrupts = 0;
-        IntReg *ipr = xc->regs.ipr;
-
-        if (xc->regs.ipr[TheISA::IPR_SIRR]) {
-            for (int i = TheISA::INTLEVEL_SOFTWARE_MIN;
-                 i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) {
-                if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) {
-                    // See table 4-19 of 21164 hardware reference
-                    ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1;
-                    summary |= (ULL(1) << i);
-                }
-            }
-        }
-
-        uint64_t interrupts = xc->cpu->intr_status();
-        for(int i = TheISA::INTLEVEL_EXTERNAL_MIN;
-            i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) {
-            if (interrupts & (ULL(1) << i)) {
-                // See table 4-19 of 21164 hardware reference
-                ipl = i;
-                summary |= (ULL(1) << i);
-            }
-        }
-
-        if (ipr[TheISA::IPR_ASTRR])
-            panic("asynchronous traps not implemented\n");
-
-        if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) {
-            ipr[TheISA::IPR_ISR] = summary;
-            ipr[TheISA::IPR_INTID] = ipl;
-            xc->ev5_trap(Interrupt_Fault);
-
-            DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
-                    ipr[TheISA::IPR_IPLR], ipl, summary);
-        }
-    }
-#endif
-
-    // maintain $r0 semantics
-    xc->regs.intRegFile[ZeroReg] = 0;
-#ifdef TARGET_ALPHA
-    xc->regs.floatRegFile.d[ZeroReg] = 0.0;
-#endif // TARGET_ALPHA
-
-    if (status() == IcacheMissComplete) {
-        // We've already fetched an instruction and were stalled on an
-        // I-cache miss.  No need to fetch it again.
-
-        setStatus(Running);
-    }
-    else {
-        // Try to fetch an instruction
-
-        // set up memory request for instruction fetch
-#ifdef FULL_SYSTEM
-#define IFETCH_FLAGS(pc)       ((pc) & 1) ? PHYSICAL : 0
-#else
-#define IFETCH_FLAGS(pc)       0
-#endif
-
-        memReq->cmd = Read;
-        memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),
-                     IFETCH_FLAGS(xc->regs.pc));
-
-        fault = xc->translateInstReq(memReq);
-
-        if (fault == No_Fault)
-            fault = xc->mem->read(memReq, inst);
-
-        if (icacheInterface && fault == No_Fault) {
-            memReq->completionEvent = NULL;
-
-            memReq->time = curTick;
-            memReq->flags &= ~UNCACHEABLE;
-            MemAccessResult result = icacheInterface->access(memReq);
-
-            // Ugly hack to get an event scheduled *only* if the access is
-            // a miss.  We really should add first-class support for this
-            // at some point.
-            if (result != MA_HIT && icacheInterface->doEvents) {
-                memReq->completionEvent = &cacheCompletionEvent;
-                setStatus(IcacheMissStall);
-                return;
-            }
-        }
-    }
-
-    // If we've got a valid instruction (i.e., no fault on instruction
-    // fetch), then execute it.
-    if (fault == No_Fault) {
-
-        // keep an instruction count
-        numInst++;
-
-        // check for instruction-count-based events
-        comInsnEventQueue[0]->serviceEvents(numInst);
-
-        // decode the instruction
-        StaticInstPtr<TheISA> si(inst);
-
-        traceData = Trace::getInstRecord(curTick, xc, this, si,
-                                         xc->regs.pc);
-
-#ifdef FULL_SYSTEM
-        xc->regs.opcode = (inst >> 26) & 0x3f;
-        xc->regs.ra = (inst >> 21) & 0x1f;
-#endif // FULL_SYSTEM
-
-        xc->func_exe_insn++;
-
-        fault = si->execute(this, xc, traceData);
-
-        if (si->isMemRef()) {
-            numMemRefs++;
-        }
-
-        if (traceData)
-            traceData->finalize();
-
-    }  // if (fault == No_Fault)
-
-    if (fault != No_Fault) {
-#ifdef FULL_SYSTEM
-        xc->ev5_trap(fault);
-#else // !FULL_SYSTEM
-        fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc);
-#endif // FULL_SYSTEM
-    }
-    else {
-        // go to the next instruction
-        xc->regs.pc = xc->regs.npc;
-        xc->regs.npc += sizeof(MachInst);
-    }
-
-#ifdef FULL_SYSTEM
-    Addr oldpc;
-    do {
-        oldpc = xc->regs.pc;
-        system->pcEventQueue.service(xc);
-    } while (oldpc != xc->regs.pc);
-#endif
-
-    assert(status() == Running ||
-           status() == Idle ||
-           status() == DcacheMissStall);
-
-    if (status() == Running && !tickEvent.scheduled())
-        tickEvent.schedule(curTick + 1);
-}
-
-
-////////////////////////////////////////////////////////////////////////
-//
-//  SimpleCPU Simulation Object
-//
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
-
-    Param<Counter> max_insts_any_thread;
-    Param<Counter> max_insts_all_threads;
-
-#ifdef FULL_SYSTEM
-    SimObjectParam<AlphaItb *> itb;
-    SimObjectParam<AlphaDtb *> dtb;
-    SimObjectParam<FunctionalMemory *> mem;
-    SimObjectParam<System *> system;
-    Param<int> cpu_id;
-    Param<int> mult;
-#else
-    SimObjectParam<Process *> workload;
-#endif // FULL_SYSTEM
-
-    SimObjectParam<BaseMem *> icache;
-    SimObjectParam<BaseMem *> dcache;
-
-END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
-
-    INIT_PARAM_DFLT(max_insts_any_thread,
-                    "terminate when any thread reaches this insn count",
-                    0),
-    INIT_PARAM_DFLT(max_insts_all_threads,
-                    "terminate when all threads have reached this insn count",
-                    0),
-
-#ifdef FULL_SYSTEM
-    INIT_PARAM(itb, "Instruction TLB"),
-    INIT_PARAM(dtb, "Data TLB"),
-    INIT_PARAM(mem, "memory"),
-    INIT_PARAM(system, "system object"),
-    INIT_PARAM_DFLT(cpu_id, "CPU identification number", 0),
-    INIT_PARAM_DFLT(mult, "system clock multiplier", 1),
-#else
-    INIT_PARAM(workload, "processes to run"),
-#endif // FULL_SYSTEM
-
-    INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL),
-    INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL)
-
-END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
-
-
-CREATE_SIM_OBJECT(SimpleCPU)
-{
-#ifdef FULL_SYSTEM
-    if (mult != 1)
-        panic("processor clock multiplier must be 1\n");
-
-    return new SimpleCPU(getInstanceName(), system,
-                         max_insts_any_thread, max_insts_all_threads,
-                         itb, dtb, mem,
-                         (icache) ? icache->getInterface() : NULL,
-                         (dcache) ? dcache->getInterface() : NULL,
-                         cpu_id, ticksPerSecond * mult);
-#else
-
-    return new SimpleCPU(getInstanceName(), workload,
-                         max_insts_any_thread, max_insts_all_threads,
-                         icache->getInterface(), dcache->getInterface());
-
-#endif // FULL_SYSTEM
-}
-
-REGISTER_SIM_OBJECT("SimpleCPU", SimpleCPU)
diff --git a/sim/simple_cpu.hh b/sim/simple_cpu.hh
deleted file mode 100644 (file)
index c5671eb..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __SIMPLE_CPU_HH__
-#define __SIMPLE_CPU_HH__
-
-#include "base_cpu.hh"
-#include "eventq.hh"
-#include "symtab.hh"
-#include "pc_event.hh"
-#include "statistics.hh"
-
-
-// forward declarations
-#ifdef FULL_SYSTEM
-class Processor;
-class Kernel;
-class AlphaItb;
-class AlphaDtb;
-class PhysicalMemory;
-
-class RemoteGDB;
-class GDBListener;
-#endif // FULL_SYSTEM
-
-class MemInterface;
-class IniFile;
-
-namespace Trace {
-    class InstRecord;
-}
-
-class SimpleCPU : public BaseCPU
-{
-  public:
-    // main simulation loop (one cycle)
-    void tick();
-
-  private:
-    class TickEvent : public Event
-    {
-      private:
-        SimpleCPU *cpu;
-
-      public:
-        TickEvent(SimpleCPU *c)
-            : Event(&mainEventQueue, 100), cpu(c) { }
-        void process() { cpu->tick(); }
-        virtual const char *description() { return "tick event"; }
-    };
-
-    TickEvent tickEvent;
-
-  private:
-    Trace::InstRecord *traceData;
-    template<typename T>
-    void trace_data(T data) {
-      if (traceData) {
-        traceData->setData(data);
-      }
-    };
-
-  public:
-    //
-    enum Status {
-        Running,
-        Idle,
-        IcacheMissStall,
-        IcacheMissComplete,
-        DcacheMissStall
-    };
-
-  private:
-    Status _status;
-
-  public:
-    void post_interrupt(int int_num, int index);
-
-    void zero_fill_64(Addr addr) {
-      static int warned = 0;
-      if (!warned) {
-        warn ("WH64 is not implemented");
-        warned = 1;
-      }
-    };
-
-#ifdef FULL_SYSTEM
-
-    SimpleCPU(const std::string &_name,
-              System *_system,
-              Counter max_insts_any_thread, Counter max_insts_all_threads,
-              AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem,
-              MemInterface *icache_interface, MemInterface *dcache_interface,
-              int cpu_id, Tick freq);
-
-#else
-
-    SimpleCPU(const std::string &_name, Process *_process,
-              Counter max_insts_any_thread,
-              Counter max_insts_all_threads,
-              MemInterface *icache_interface, MemInterface *dcache_interface);
-
-#endif
-
-    virtual ~SimpleCPU();
-
-    // execution context
-    ExecContext *xc;
-
-#ifdef FULL_SYSTEM
-    Addr dbg_vtophys(Addr addr);
-
-    bool interval_stats;
-#endif
-
-    // L1 instruction cache
-    MemInterface *icacheInterface;
-
-    // L1 data cache
-    MemInterface *dcacheInterface;
-
-    // current instruction
-    MachInst inst;
-
-    // current fault status
-    Fault fault;
-
-    // Refcounted pointer to the one memory request.
-    MemReqPtr memReq;
-
-    class CacheCompletionEvent : public Event
-    {
-      private:
-        SimpleCPU *cpu;
-
-      public:
-        CacheCompletionEvent(SimpleCPU *_cpu);
-
-        virtual void process();
-        virtual const char *description();
-    };
-
-    CacheCompletionEvent cacheCompletionEvent;
-
-    Status status() const { return _status; }
-    virtual void execCtxStatusChg() {
-        if (xc) {
-            if (xc->status() == ExecContext::Active)
-                setStatus(Running);
-            else
-                setStatus(Idle);
-        }
-    }
-
-    void setStatus(Status new_status) {
-        Status old_status = status();
-        _status = new_status;
-
-        switch (status()) {
-          case IcacheMissStall:
-            assert(old_status == Running);
-            lastIcacheStall = curTick;
-            if (tickEvent.scheduled())
-                tickEvent.squash();
-            break;
-
-          case IcacheMissComplete:
-            assert(old_status == IcacheMissStall);
-            if (tickEvent.squashed())
-                tickEvent.reschedule(curTick + 1);
-            else if (!tickEvent.scheduled())
-                tickEvent.schedule(curTick + 1);
-            break;
-
-          case DcacheMissStall:
-            assert(old_status == Running);
-            lastDcacheStall = curTick;
-            if (tickEvent.scheduled())
-                tickEvent.squash();
-            break;
-
-          case Idle:
-            assert(old_status == Running);
-            last_idle = curTick;
-            if (tickEvent.scheduled())
-                tickEvent.squash();
-            break;
-
-          case Running:
-            assert(old_status == Idle ||
-                   old_status == DcacheMissStall ||
-                   old_status == IcacheMissComplete);
-            if (old_status == Idle)
-                idleCycles += curTick - last_idle;
-
-            if (tickEvent.squashed())
-                tickEvent.reschedule(curTick + 1);
-            else if (!tickEvent.scheduled())
-                tickEvent.schedule(curTick + 1);
-            break;
-
-          default:
-            panic("can't get here");
-        }
-    }
-
-    // statistics
-    void regStats();
-
-    // number of simulated instructions
-    Counter numInst;
-    Statistics::Formula numInsts;
-
-    // number of simulated memory references
-    Statistics::Scalar<> numMemRefs;
-
-    // number of idle cycles
-    Statistics::Scalar<> idleCycles;
-    Statistics::Formula idleFraction;
-    Counter last_idle;
-
-    // number of cycles stalled for I-cache misses
-    Statistics::Scalar<> icacheStallCycles;
-    Counter lastIcacheStall;
-
-    // number of cycles stalled for D-cache misses
-    Statistics::Scalar<> dcacheStallCycles;
-    Counter lastDcacheStall;
-
-    void processCacheCompletion();
-
-    virtual void serialize();
-    virtual void unserialize(IniFile &db, const std::string &category,
-                             ConfigNode *node);
-
-    template <class T>
-    Fault read(Addr addr, T& data, unsigned flags);
-
-    template <class T>
-    Fault write(T data, Addr addr, unsigned flags,
-                        uint64_t *res);
-
-    Fault prefetch(Addr addr, unsigned flags)
-    {
-        // need to do this...
-        return No_Fault;
-    }
-
-    void writeHint(Addr addr, int size)
-    {
-        // need to do this...
-    }
-};
-
-#endif // __SIMPLE_CPU_HH__
diff --git a/sim/smt.hh b/sim/smt.hh
deleted file mode 100644 (file)
index f9c1e46..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file
- * Defines SMT_MAX_CPUS and SMT_MAX_THREADS.
- */
-
-#ifndef __SMT_HH__
-#define __SMT_HH__
-
-#ifndef SMT_MAX_CPUS
-/** The maximum number of cpus in any one system. */
-#define SMT_MAX_CPUS 4
-#endif
-
-#ifndef SMT_MAX_THREADS
-/** The number of TPUs in any processor. */
-#define SMT_MAX_THREADS 4
-#endif
-
-/**
- * The maximum number of active threads across all cpus. Used to
- * initialize per-thread statistics in the cache.
- *
- * NB: Be careful to only use it once all the CPUs that you care about
- *     have been initialized
- */
-extern int maxThreadsPerCPU;
-
-/**
- * Changes the status and priority of the thread with the given number.
- * @param thread_number The thread to change.
- * @param activate The new active status.
- * @param priority The new priority.
- */
-void change_thread_state(int thread_number, int activate, int priority);
-
-#endif // __SMT_HH__
diff --git a/sim/static_inst.cc b/sim/static_inst.cc
deleted file mode 100644 (file)
index cf25d5f..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <iostream>
-#include "static_inst.hh"
-#include "universe.hh"
-
-template <class ISA>
-StaticInstPtr<ISA> StaticInst<ISA>::nullStaticInstPtr;
-
-template <class ISA>
-typename StaticInst<ISA>::DecodeCache StaticInst<ISA>::decodeCache;
-
-// Define the decode cache hash map.
-template StaticInst<AlphaISA>::DecodeCache
-StaticInst<AlphaISA>::decodeCache;
-
-template <class ISA>
-void
-StaticInst<ISA>::dumpDecodeCacheStats()
-{
-    using namespace std;
-
-    cerr << "Decode hash table stats @ " << curTick << ":" << endl;
-    cerr << "\tnum entries = " << decodeCache.size() << endl;
-    cerr << "\tnum buckets = " << decodeCache.bucket_count() << endl;
-    vector<int> hist(100, 0);
-    int max_hist = 0;
-    for (int i = 0; i < decodeCache.bucket_count(); ++i) {
-        int count = decodeCache.elems_in_bucket(i);
-        if (count > max_hist)
-            max_hist = count;
-        hist[count]++;
-    }
-    for (int i = 0; i <= max_hist; ++i) {
-        cerr << "\tbuckets of size " << i << " = " << hist[i] << endl;
-    }
-}
-
-
-template StaticInstPtr<AlphaISA>
-StaticInst<AlphaISA>::nullStaticInstPtr;
-
-template <class ISA>
-bool
-StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt)
-{
-    if (isDirectCtrl()) {
-        tgt = branchTarget(pc);
-        return true;
-    }
-
-    if (isIndirectCtrl()) {
-        tgt = branchTarget(xc);
-        return true;
-    }
-
-    return false;
-}
-
-
-// force instantiation of template function(s) above
-template StaticInst<AlphaISA>;
diff --git a/sim/static_inst.hh b/sim/static_inst.hh
deleted file mode 100644 (file)
index b8f9cc0..0000000
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (c) 2003 The Regents of The University of Michigan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __STATIC_INST_HH__
-#define __STATIC_INST_HH__
-
-#include <bitset>
-#include <string>
-
-#include "host.hh"
-#include "hashmap.hh"
-#include "refcnt.hh"
-
-#include "op_class.hh"
-#include "isa_traits.hh"
-
-// forward declarations
-class ExecContext;
-class SpecExecContext;
-class SimpleCPU;
-class CPU;
-class DynInst;
-class SymbolTable;
-
-namespace Trace {
-    class InstRecord;
-}
-
-/**
- * Base, ISA-independent static instruction class.
- *
- * The main component of this class is the vector of flags and the
- * associated methods for reading them.  Any object that can rely
- * solely on these flags can process instructions without being
- * recompiled for multiple ISAs.
- */
-class StaticInstBase : public RefCounted
-{
-  protected:
-
-    /// Set of boolean static instruction properties.
-    ///
-    /// Notes:
-    /// - The IsInteger and IsFloating flags are based on the class of
-    /// registers accessed by the instruction.  Although most
-    /// instructions will have exactly one of these two flags set, it
-    /// is possible for an instruction to have neither (e.g., direct
-    /// unconditional branches, memory barriers) or both (e.g., an
-    /// FP/int conversion).
-    /// - If IsMemRef is set, then exactly one of IsLoad or IsStore
-    /// will be set.  Prefetches are marked as IsLoad, even if they
-    /// prefetch exclusive copies.
-    /// - If IsControl is set, then exactly one of IsDirectControl or
-    /// IsIndirect Control will be set, and exactly one of
-    /// IsCondControl or IsUncondControl will be set.
-    ///
-    enum Flags {
-        IsNop,         ///< Is a no-op (no effect at all).
-
-        IsInteger,     ///< References integer regs.
-        IsFloating,    ///< References FP regs.
-
-        IsMemRef,      ///< References memory (load, store, or prefetch).
-        IsLoad,                ///< Reads from memory (load or prefetch).
-        IsStore,       ///< Writes to memory.
-        IsInstPrefetch,        ///< Instruction-cache prefetch.
-        IsDataPrefetch,        ///< Data-cache prefetch.
-
-        IsControl,             ///< Control transfer instruction.
-        IsDirectControl,       ///< PC relative control transfer.
-        IsIndirectControl,     ///< Register indirect control transfer.
-        IsCondControl,         ///< Conditional control transfer.
-        IsUncondControl,       ///< Unconditional control transfer.
-        IsCall,                        ///< Subroutine call.
-        IsReturn,              ///< Subroutine return.
-
-        IsThreadSync,          ///< Thread synchronization operation.
-
-        NumFlags
-    };
-
-    /// Flag values for this instruction.
-    std::bitset<NumFlags> flags;
-
-    /// See opClass().
-    OpClass _opClass;
-
-    /// See numSrcRegs().
-    int8_t _numSrcRegs;
-
-    /// See numDestRegs().
-    int8_t _numDestRegs;
-
-    /// The following are used to track physical register usage
-    /// for machines with separate int & FP reg files.
-    //@{
-    int8_t _numFPDestRegs;
-    int8_t _numIntDestRegs;
-    //@}
-
-    /// Constructor.
-    /// It's important to initialize everything here to a sane
-    /// default, since the decoder generally only overrides
-    /// the fields that are meaningful for the particular
-    /// instruction.
-    StaticInstBase(OpClass __opClass)
-        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
-          _numFPDestRegs(0), _numIntDestRegs(0)
-    {
-    }
-
-  public:
-
-    /// @name Register information.
-    /// The sum of numFPDestRegs() and numIntDestRegs() equals
-    /// numDestRegs().  The former two functions are used to track
-    /// physical register usage for machines with separate int & FP
-    /// reg files.
-    //@{
-    /// Number of source registers.
-    int8_t numSrcRegs()  const { return _numSrcRegs; }
-    /// Number of destination registers.
-    int8_t numDestRegs() const { return _numDestRegs; }
-    /// Number of floating-point destination regs.
-    int8_t numFPDestRegs()  const { return _numFPDestRegs; }
-    /// Number of integer destination regs.
-    int8_t numIntDestRegs() const { return _numIntDestRegs; }
-    //@}
-
-    /// @name Flag accessors.
-    /// These functions are used to access the values of the various
-    /// instruction property flags.  See StaticInstBase::Flags for descriptions
-    /// of the individual flags.
-    //@{
-
-    bool isNop()         const { return flags[IsNop]; }
-
-    bool isMemRef()              const { return flags[IsMemRef]; }
-    bool isLoad()        const { return flags[IsLoad]; }
-    bool isStore()       const { return flags[IsStore]; }
-    bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
-    bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
-
-    bool isInteger()     const { return flags[IsInteger]; }
-    bool isFloating()    const { return flags[IsFloating]; }
-
-    bool isControl()     const { return flags[IsControl]; }
-    bool isCall()        const { return flags[IsCall]; }
-    bool isReturn()      const { return flags[IsReturn]; }
-    bool isDirectCtrl()          const { return flags[IsDirectControl]; }
-    bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
-    bool isCondCtrl()    const { return flags[IsCondControl]; }
-    bool isUncondCtrl()          const { return flags[IsUncondControl]; }
-
-    bool isThreadSync()   const { return flags[IsThreadSync]; }
-    //@}
-
-    /// Operation class.  Used to select appropriate function unit in issue.
-    OpClass opClass()     const { return _opClass; }
-};
-
-
-// forward declaration
-template <class ISA>
-class StaticInstPtr;
-
-/**
- * Generic yet ISA-dependent static instruction class.
- *
- * This class builds on StaticInstBase, defining fields and interfaces
- * that are generic across all ISAs but that differ in details
- * according to the specific ISA being used.
- */
-template <class ISA>
-class StaticInst : public StaticInstBase
-{
-  public:
-
-    /// Binary machine instruction type.
-    typedef typename ISA::MachInst MachInst;
-    /// Memory address type.
-    typedef typename ISA::Addr    Addr;
-    /// Logical register index type.
-    typedef typename ISA::RegIndex RegIndex;
-
-    enum {
-        MaxInstSrcRegs = ISA::MaxInstSrcRegs,  //< Max source regs
-        MaxInstDestRegs = ISA::MaxInstDestRegs,        //< Max dest regs
-    };
-
-
-    /// Return logical index (architectural reg num) of i'th destination reg.
-    /// Only the entries from 0 through numDestRegs()-1 are valid.
-    RegIndex destRegIdx(int i) { return _destRegIdx[i]; }
-
-    /// Return logical index (architectural reg num) of i'th source reg.
-    /// Only the entries from 0 through numSrcRegs()-1 are valid.
-    RegIndex srcRegIdx(int i)  { return _srcRegIdx[i]; }
-
-    /// Pointer to a statically allocated "null" instruction object.
-    /// Used to give eaCompInst() and memAccInst() something to return
-    /// when called on non-memory instructions.
-    static StaticInstPtr<ISA> nullStaticInstPtr;
-
-    /**
-     * Memory references only: returns "fake" instruction representing
-     * the effective address part of the memory operation.  Used to
-     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
-     * just the EA computation.
-     */
-    virtual StaticInstPtr<ISA> eaCompInst() { return nullStaticInstPtr; }
-
-    /**
-     * Memory references only: returns "fake" instruction representing
-     * the memory access part of the memory operation.  Used to
-     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
-     * just the memory access (not the EA computation).
-     */
-    virtual StaticInstPtr<ISA> memAccInst() { return nullStaticInstPtr; }
-
-    /// The binary machine instruction.
-    const MachInst machInst;
-
-  protected:
-
-    /// See destRegIdx().
-    RegIndex _destRegIdx[MaxInstDestRegs];
-    /// See srcRegIdx().
-    RegIndex _srcRegIdx[MaxInstSrcRegs];
-
-    /**
-     * Base mnemonic (e.g., "add").  Used by generateDisassembly()
-     * methods.  Also useful to readily identify instructions from
-     * within the debugger when #cachedDisassembly has not been
-     * initialized.
-     */
-    const char *mnemonic;
-
-    /**
-     * String representation of disassembly (lazily evaluated via
-     * disassemble()).
-     */
-    std::string *cachedDisassembly;
-
-    /**
-     * Internal function to generate disassembly string.
-     */
-    virtual std::string generateDisassembly(Addr pc,
-                                            const SymbolTable *symtab) = 0;
-
-    /// Constructor.
-    StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass)
-        : StaticInstBase(__opClass),
-          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
-    {
-    }
-
-  public:
-
-    virtual ~StaticInst()
-    {
-        if (cachedDisassembly)
-            delete cachedDisassembly;
-    }
-
-    /**
-     * Execute this instruction under SimpleCPU model.
-     */
-    virtual Fault execute(SimpleCPU *cpu, ExecContext *xc,
-                          Trace::InstRecord *traceData) = 0;
-
-    /**
-     * Execute this instruction under detailed CPU model.
-     */
-    virtual Fault execute(CPU *cpu, SpecExecContext *xc, DynInst *dynInst,
-                          Trace::InstRecord *traceData) = 0;
-
-    /**
-     * Return the target address for a PC-relative branch.
-     * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
-     * should be true).
-     */
-    virtual Addr branchTarget(Addr branchPC)
-    {
-        panic("StaticInst::branchTarget() called on instruction "
-              "that is not a PC-relative branch.");
-    }
-
-    /**
-     * Return the target address for an indirect branch (jump).
-     * The register value is read from the supplied execution context.
-     * Invalid if not an indirect branch (i.e. isIndirectCtrl()
-     * should be true).
-     */
-    virtual Addr branchTarget(ExecContext *xc)
-    {
-        panic("StaticInst::branchTarget() called on instruction "
-              "that is not an indirect branch.");
-    }
-
-    /**
-     * Return true if the instruction is a control transfer, and if so,
-     * return the target address as well.
-     */
-    bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt);
-
-    /**
-     * Return string representation of disassembled instruction.
-     * The default version of this function will call the internal
-     * virtual generateDisassembly() function to get the string,
-     * then cache it in #cachedDisassembly.  If the disassembly
-     * should not be cached, this function should be overridden directly.
-     */
-    virtual const std::string &disassemble(Addr pc,
-                                           const SymbolTable *symtab = 0)
-    {
-        if (!cachedDisassembly)
-            cachedDisassembly =
-                new std::string(generateDisassembly(pc, symtab));
-
-        return *cachedDisassembly;
-    }
-
-    /// Decoded instruction cache type.
-    /// For now we're using a generic hash_map; this seems to work
-    /// pretty well.
-    typedef m5::hash_map<MachInst, StaticInstPtr<ISA> > DecodeCache;
-
-    /// A cache of decoded instruction objects.
-    static DecodeCache decodeCache;
-
-    /**
-     * Dump some basic stats on the decode cache hash map.
-     * Only gets called if DECODE_CACHE_HASH_STATS is defined.
-     */
-    static void dumpDecodeCacheStats();
-
-    /// Decode a machine instruction.
-    /// @param mach_inst The binary instruction to decode.
-    /// @retval A pointer to the corresponding StaticInst object.
-    static
-    StaticInstPtr<ISA> decode(MachInst mach_inst)
-    {
-#ifdef DECODE_CACHE_HASH_STATS
-        // Simple stats on decode hash_map.  Turns out the default
-        // hash function is as good as anything I could come up with.
-        const int dump_every_n = 10000000;
-        static int decodes_til_dump = dump_every_n;
-
-        if (--decodes_til_dump == 0) {
-            dumpDecodeCacheStats();
-            decodes_til_dump = dump_every_n;
-        }
-#endif
-
-        typename DecodeCache::iterator iter = decodeCache.find(mach_inst);
-        if (iter != decodeCache.end()) {
-            return iter->second;
-        }
-
-        StaticInstPtr<ISA> si = ISA::decodeInst(mach_inst);
-        decodeCache[mach_inst] = si;
-        return si;
-    }
-};
-
-typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
-
-/// Reference-counted pointer to a StaticInst object.
-/// This type should be used instead of "StaticInst<ISA> *" so that
-/// StaticInst objects can be properly reference-counted.
-template <class ISA>
-class StaticInstPtr : public RefCountingPtr<StaticInst<ISA> >
-{
-  public:
-    /// Constructor.
-    StaticInstPtr()
-        : RefCountingPtr<StaticInst<ISA> >()
-    {
-    }
-
-    /// Conversion from "StaticInst<ISA> *".
-    StaticInstPtr(StaticInst<ISA> *p)
-        : RefCountingPtr<StaticInst<ISA> >(p)
-    {
-    }
-
-    /// Copy constructor.
-    StaticInstPtr(const StaticInstPtr &r)
-        : RefCountingPtr<StaticInst<ISA> >(r)
-    {
-    }
-
-    /// Construct directly from machine instruction.
-    /// Calls StaticInst<ISA>::decode().
-    StaticInstPtr(typename ISA::MachInst mach_inst)
-        : RefCountingPtr<StaticInst<ISA> >(StaticInst<ISA>::decode(mach_inst))
-    {
-    }
-
-    /// Convert to pointer to StaticInstBase class.
-    operator const StaticInstBasePtr()
-    {
-        return get();
-    }
-};
-
-#endif // __STATIC_INST_HH__