+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/* $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
+++ /dev/null
-/* $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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/* $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_ */
+++ /dev/null
-/* $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_ */
--- /dev/null
+/*
+ * 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();
+ }
+
+}
+
--- /dev/null
+/*
+ * 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__
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/* $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
--- /dev/null
+/* $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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/* $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_ */
--- /dev/null
+/* $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_ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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("");
+}
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * 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__
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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(®s, 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
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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();
+}
+
--- /dev/null
+/*
+ * 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 ®s);
+
+ 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 ®s)
+{
+ 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__
+
+
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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>;
--- /dev/null
+/*
+ * 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__
+++ /dev/null
-/*
- * 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)
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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(®s, 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
-}
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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();
-}
-
+++ /dev/null
-/*
- * 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 ®s);
-
- 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 ®s)
-{
- 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__
+++ /dev/null
-/*
- * 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();
- }
-
-}
-
+++ /dev/null
-/*
- * 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__
-
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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)
+++ /dev/null
-/*
- * 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__
-
-
-
-
-
-
-
+++ /dev/null
-/*
- * 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)
+++ /dev/null
-/*
- * 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__
-
-
-
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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("");
-}
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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)
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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__
+++ /dev/null
-/*
- * 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>;
+++ /dev/null
-/*
- * 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__