Adding gem5 source to svn.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
8
simulators/gem5/src/base/CPA.py
Normal file
8
simulators/gem5/src/base/CPA.py
Normal file
@ -0,0 +1,8 @@
|
||||
from m5.SimObject import SimObject
|
||||
from m5.params import *
|
||||
|
||||
class CPA(SimObject):
|
||||
type = 'CPA'
|
||||
|
||||
enabled = Param.Bool(False, "Is Annotation enabled?")
|
||||
user_apps = VectorParam.String([], "List of apps to get symbols for")
|
||||
94
simulators/gem5/src/base/SConscript
Normal file
94
simulators/gem5/src/base/SConscript
Normal file
@ -0,0 +1,94 @@
|
||||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2006 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.
|
||||
#
|
||||
# Authors: Nathan Binkert
|
||||
|
||||
Import('*')
|
||||
|
||||
if env['CP_ANNOTATE']:
|
||||
SimObject('CPA.py')
|
||||
Source('cp_annotate.cc')
|
||||
Source('atomicio.cc')
|
||||
Source('bigint.cc')
|
||||
Source('bitmap.cc')
|
||||
Source('callback.cc')
|
||||
Source('circlebuf.cc')
|
||||
Source('cprintf.cc')
|
||||
Source('debug.cc')
|
||||
if env['USE_FENV']:
|
||||
Source('fenv.c')
|
||||
Source('hostinfo.cc')
|
||||
Source('inet.cc')
|
||||
Source('inifile.cc')
|
||||
Source('intmath.cc')
|
||||
Source('match.cc')
|
||||
Source('misc.cc')
|
||||
Source('output.cc')
|
||||
Source('pollevent.cc')
|
||||
Source('random.cc')
|
||||
Source('random_mt.cc')
|
||||
Source('range.cc')
|
||||
if env['TARGET_ISA'] != 'no':
|
||||
Source('remote_gdb.cc')
|
||||
Source('socket.cc')
|
||||
Source('statistics.cc')
|
||||
Source('str.cc')
|
||||
Source('time.cc')
|
||||
Source('trace.cc')
|
||||
Source('userinfo.cc')
|
||||
|
||||
Source('loader/aout_object.cc')
|
||||
Source('loader/ecoff_object.cc')
|
||||
Source('loader/elf_object.cc')
|
||||
Source('loader/hex_file.cc')
|
||||
Source('loader/object_file.cc')
|
||||
Source('loader/raw_object.cc')
|
||||
Source('loader/symtab.cc')
|
||||
|
||||
Source('stats/text.cc')
|
||||
|
||||
DebugFlag('Annotate', "State machine annotation debugging")
|
||||
DebugFlag('AnnotateQ', "State machine annotation queue debugging")
|
||||
DebugFlag('AnnotateVerbose', "Dump all state machine annotation details")
|
||||
DebugFlag('GDBAcc', "Remote debugger accesses")
|
||||
DebugFlag('GDBExtra', "Dump extra information on reads and writes")
|
||||
DebugFlag('GDBMisc', "Breakpoints, traps, watchpoints, etc.")
|
||||
DebugFlag('GDBRead', "Reads to the remote address space")
|
||||
DebugFlag('GDBRecv', "Messages received from the remote application")
|
||||
DebugFlag('GDBSend', "Messages sent to the remote application")
|
||||
DebugFlag('GDBWrite', "Writes to the remote address space")
|
||||
DebugFlag('SQL', "SQL queries sent to the server")
|
||||
DebugFlag('StatEvents', "Statistics event tracking")
|
||||
|
||||
CompoundFlag('GDBAll',
|
||||
[ 'GDBMisc', 'GDBAcc', 'GDBRead', 'GDBWrite', 'GDBSend', 'GDBRecv',
|
||||
'GDBExtra' ],
|
||||
desc="All Remote debugging flags")
|
||||
CompoundFlag('AnnotateAll', ['Annotate', 'AnnotateQ', 'AnnotateVerbose'],
|
||||
desc="All Annotation flags")
|
||||
|
||||
92
simulators/gem5/src/base/atomicio.cc
Normal file
92
simulators/gem5/src/base/atomicio.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2008 The Hewlett-Packard Development Company
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
|
||||
#include "base/atomicio.hh"
|
||||
|
||||
ssize_t
|
||||
atomic_read(int fd, void *s, size_t n)
|
||||
{
|
||||
char *p = reinterpret_cast<char *>(s);
|
||||
size_t pos = 0;
|
||||
|
||||
// Keep reading until we've gotten all of the data.
|
||||
while (n > pos) {
|
||||
ssize_t result = read(fd, p + pos, n - pos);
|
||||
|
||||
// We didn't get any more data, so we should probably punt,
|
||||
// otherwise we'd just keep spinning
|
||||
if (result == 0)
|
||||
break;
|
||||
|
||||
// If there was an error, try again on EINTR/EAGAIN, pass the
|
||||
// error up otherwise.
|
||||
if (result == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return result;
|
||||
}
|
||||
|
||||
pos += result;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
atomic_write(int fd, const void *s, size_t n)
|
||||
{
|
||||
const char *p = reinterpret_cast<const char *>(s);
|
||||
size_t pos = 0;
|
||||
|
||||
// Keep writing until we've written all of the data
|
||||
while (n > pos) {
|
||||
ssize_t result = write(fd, p + pos, n - pos);
|
||||
|
||||
// We didn't manage to write anything this time, so we should
|
||||
// probably punt, otherwise we'd just keep spinning
|
||||
if (result == 0)
|
||||
break;
|
||||
|
||||
// If there was an error, try again on EINTR/EAGAIN, pass the
|
||||
// error up otherwise.
|
||||
if (result == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return result;
|
||||
}
|
||||
|
||||
pos += result;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
44
simulators/gem5/src/base/atomicio.hh
Normal file
44
simulators/gem5/src/base/atomicio.hh
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2008 The Hewlett-Packard Development Company
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_ATOMICIO_HH__
|
||||
#define __BASE_ATOMICIO_HH__
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
// These functions keep reading/writing, if possible, until all data
|
||||
// has been transferred. Basically, try again when there's no error,
|
||||
// but there is data left also retry on EINTR.
|
||||
// This function blocks until it is done.
|
||||
|
||||
ssize_t atomic_read(int fd, void *s, size_t n);
|
||||
ssize_t atomic_write(int fd, const void *s, size_t n);
|
||||
|
||||
#endif // __BASE_ATOMICIO_HH__
|
||||
47
simulators/gem5/src/base/bigint.cc
Normal file
47
simulators/gem5/src/base/bigint.cc
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "base/bigint.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ostream & operator << (ostream & os, const Twin64_t & t)
|
||||
{
|
||||
os << t.a << ", " << t.b;
|
||||
return os;
|
||||
}
|
||||
|
||||
ostream & operator << (ostream & os, const Twin32_t & t)
|
||||
{
|
||||
os << t.a << ", " << t.b;
|
||||
return os;
|
||||
}
|
||||
98
simulators/gem5/src/base/bigint.hh
Normal file
98
simulators/gem5/src/base/bigint.hh
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
#ifndef __BASE_BIGINT_HH__
|
||||
#define __BASE_BIGINT_HH__
|
||||
// Create a couple of large int types for atomic reads
|
||||
struct m5_twin64_t {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
m5_twin64_t()
|
||||
{}
|
||||
m5_twin64_t(const uint64_t x)
|
||||
{
|
||||
a = x;
|
||||
b = x;
|
||||
}
|
||||
inline m5_twin64_t& operator=(const uint64_t x)
|
||||
{
|
||||
a = x;
|
||||
b = x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator uint64_t()
|
||||
{
|
||||
panic("Tried to cram a twin64_t into an integer!\n");
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct m5_twin32_t {
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
m5_twin32_t()
|
||||
{}
|
||||
m5_twin32_t(const uint32_t x)
|
||||
{
|
||||
a = x;
|
||||
b = x;
|
||||
}
|
||||
inline m5_twin32_t& operator=(const uint32_t x)
|
||||
{
|
||||
a = x;
|
||||
b = x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator uint32_t()
|
||||
{
|
||||
panic("Tried to cram a twin32_t into an integer!\n");
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// This is for twin loads (two 64 bit values), not 1 128 bit value (as far as
|
||||
// endian conversion is concerned!
|
||||
typedef m5_twin64_t Twin64_t;
|
||||
typedef m5_twin32_t Twin32_t;
|
||||
|
||||
// Output operator overloads
|
||||
std::ostream & operator << (std::ostream & os, const Twin64_t & t);
|
||||
std::ostream & operator << (std::ostream & os, const Twin32_t & t);
|
||||
|
||||
#endif // __BASE_BIGINT_HH__
|
||||
|
||||
181
simulators/gem5/src/base/bitfield.hh
Normal file
181
simulators/gem5/src/base/bitfield.hh
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
* Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_BITFIELD_HH__
|
||||
#define __BASE_BITFIELD_HH__
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
/**
|
||||
* Generate a 64-bit mask of 'nbits' 1s, right justified.
|
||||
*/
|
||||
inline uint64_t
|
||||
mask(int nbits)
|
||||
{
|
||||
return (nbits == 64) ? (uint64_t)-1LL : (1ULL << nbits) - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extract the bitfield from position 'first' to 'last' (inclusive)
|
||||
* from 'val' and right justify it. MSB is numbered 63, LSB is 0.
|
||||
*/
|
||||
template <class T>
|
||||
inline
|
||||
T
|
||||
bits(T val, int first, int last)
|
||||
{
|
||||
int nbits = first - last + 1;
|
||||
return (val >> last) & mask(nbits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the bit from this position from 'val' and right justify it.
|
||||
*/
|
||||
template <class T>
|
||||
inline
|
||||
T
|
||||
bits(T val, int bit)
|
||||
{
|
||||
return bits(val, bit, bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mask off the given bits in place like bits() but without shifting.
|
||||
* msb = 63, lsb = 0
|
||||
*/
|
||||
template <class T>
|
||||
inline
|
||||
T
|
||||
mbits(T val, int first, int last)
|
||||
{
|
||||
return val & (mask(first+1) & ~mask(last));
|
||||
}
|
||||
|
||||
inline uint64_t
|
||||
mask(int first, int last)
|
||||
{
|
||||
return mbits((uint64_t)-1LL, first, last);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign-extend an N-bit value to 64 bits.
|
||||
*/
|
||||
template <int N>
|
||||
inline
|
||||
int64_t
|
||||
sext(uint64_t val)
|
||||
{
|
||||
int sign_bit = bits(val, N-1, N-1);
|
||||
return sign_bit ? (val | ~mask(N)) : val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return val with bits first to last set to bit_val
|
||||
*/
|
||||
template <class T, class B>
|
||||
inline
|
||||
T
|
||||
insertBits(T val, int first, int last, B bit_val)
|
||||
{
|
||||
T t_bit_val = bit_val;
|
||||
T bmask = mask(first - last + 1) << last;
|
||||
return ((t_bit_val << last) & bmask) | (val & ~bmask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded for access to only one bit in value
|
||||
*/
|
||||
template <class T, class B>
|
||||
inline
|
||||
T
|
||||
insertBits(T val, int bit, B bit_val)
|
||||
{
|
||||
return insertBits(val, bit, bit, bit_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function to replace bits first to last of val with bit_val
|
||||
* in place.
|
||||
*/
|
||||
template <class T, class B>
|
||||
inline
|
||||
void
|
||||
replaceBits(T& val, int first, int last, B bit_val)
|
||||
{
|
||||
val = insertBits(val, first, last, bit_val);
|
||||
}
|
||||
|
||||
/** Overloaded function to allow to access only 1 bit*/
|
||||
template <class T, class B>
|
||||
inline
|
||||
void
|
||||
replaceBits(T& val, int bit, B bit_val)
|
||||
{
|
||||
val = insertBits(val, bit, bit, bit_val);
|
||||
}
|
||||
/**
|
||||
* Returns the bit position of the MSB that is set in the input
|
||||
*/
|
||||
inline
|
||||
int
|
||||
findMsbSet(uint64_t val) {
|
||||
int msb = 0;
|
||||
if (!val)
|
||||
return 0;
|
||||
if (bits(val, 63,32)) { msb += 32; val >>= 32; }
|
||||
if (bits(val, 31,16)) { msb += 16; val >>= 16; }
|
||||
if (bits(val, 15,8)) { msb += 8; val >>= 8; }
|
||||
if (bits(val, 7,4)) { msb += 4; val >>= 4; }
|
||||
if (bits(val, 3,2)) { msb += 2; val >>= 2; }
|
||||
if (bits(val, 1,1)) { msb += 1; }
|
||||
return msb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bit position of the LSB that is set in the input
|
||||
*/
|
||||
inline int
|
||||
findLsbSet(uint64_t val) {
|
||||
int lsb = 0;
|
||||
if (!val)
|
||||
return sizeof(val) * 8;
|
||||
if (!bits(val, 31,0)) { lsb += 32; val >>= 32; }
|
||||
if (!bits(val, 15,0)) { lsb += 16; val >>= 16; }
|
||||
if (!bits(val, 7,0)) { lsb += 8; val >>= 8; }
|
||||
if (!bits(val, 3,0)) { lsb += 4; val >>= 4; }
|
||||
if (!bits(val, 1,0)) { lsb += 2; val >>= 2; }
|
||||
if (!bits(val, 0,0)) { lsb += 1; }
|
||||
return lsb;
|
||||
}
|
||||
|
||||
#endif // __BASE_BITFIELD_HH__
|
||||
106
simulators/gem5/src/base/bitmap.cc
Normal file
106
simulators/gem5/src/base/bitmap.cc
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2010 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Authors: William Wang
|
||||
* Ali Saidi
|
||||
* Chris Emmons
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "base/bitmap.hh"
|
||||
#include "base/misc.hh"
|
||||
|
||||
const size_t Bitmap::sizeofHeaderBuffer = sizeof(Magic) + sizeof(Header) +
|
||||
sizeof(Info);
|
||||
|
||||
// bitmap class ctor
|
||||
Bitmap::Bitmap(VideoConvert::Mode _mode, uint16_t w, uint16_t h, uint8_t *d)
|
||||
: mode(_mode), height(h), width(w), data(d),
|
||||
vc(mode, VideoConvert::rgb8888, width, height), headerBuffer(0)
|
||||
{
|
||||
}
|
||||
|
||||
Bitmap::~Bitmap() {
|
||||
if (headerBuffer)
|
||||
delete [] headerBuffer;
|
||||
}
|
||||
|
||||
void
|
||||
Bitmap::write(std::ostream *bmp) const
|
||||
{
|
||||
assert(data);
|
||||
|
||||
// header is always the same for a bitmap object; compute the info once per
|
||||
// bitmap object
|
||||
if (!headerBuffer) {
|
||||
// For further information see:
|
||||
// http://en.wikipedia.org/wiki/BMP_file_format
|
||||
Magic magic = {{'B','M'}};
|
||||
Header header = {
|
||||
static_cast<uint32_t>(sizeof(VideoConvert::Rgb8888)) *
|
||||
width * height, 0, 0, 54};
|
||||
Info info = {static_cast<uint32_t>(sizeof(Info)), width, height, 1,
|
||||
static_cast<uint32_t>(sizeof(VideoConvert::Rgb8888)) * 8,
|
||||
0, static_cast<uint32_t>(sizeof(VideoConvert::Rgb8888)) *
|
||||
width * height, 1, 1, 0, 0};
|
||||
|
||||
char *p = headerBuffer = new char[sizeofHeaderBuffer];
|
||||
memcpy(p, &magic, sizeof(Magic));
|
||||
p += sizeof(Magic);
|
||||
memcpy(p, &header, sizeof(Header));
|
||||
p += sizeof(Header);
|
||||
memcpy(p, &info, sizeof(Info));
|
||||
}
|
||||
|
||||
// 1. write the header
|
||||
bmp->write(headerBuffer, sizeofHeaderBuffer);
|
||||
|
||||
// 2. write the bitmap data
|
||||
uint8_t *tmp = vc.convert(data);
|
||||
uint32_t *tmp32 = (uint32_t*)tmp;
|
||||
|
||||
// BMP start store data left to right starting with the bottom row
|
||||
// so we need to do some creative flipping
|
||||
for (int i = height - 1; i >= 0; i--)
|
||||
for (int j = 0; j < width; j++)
|
||||
bmp->write((char*)&tmp32[i * width + j], sizeof(uint32_t));
|
||||
|
||||
bmp->flush();
|
||||
|
||||
delete [] tmp;
|
||||
}
|
||||
|
||||
127
simulators/gem5/src/base/bitmap.hh
Normal file
127
simulators/gem5/src/base/bitmap.hh
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2010 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Authors: William Wang
|
||||
* Ali Saidi
|
||||
* Chris Emmons
|
||||
*/
|
||||
#ifndef __BASE_BITMAP_HH__
|
||||
#define __BASE_BITMAP_HH__
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "base/vnc/convert.hh"
|
||||
|
||||
/**
|
||||
* @file Declaration of a class that writes a frame buffer to a bitmap
|
||||
*/
|
||||
|
||||
|
||||
// write frame buffer into a bitmap picture
|
||||
class Bitmap
|
||||
{
|
||||
public:
|
||||
/** Create a Bitmap creator that takes data in the given mode & size
|
||||
* and outputs to an fstream
|
||||
* @param mode the type of data that is being provided
|
||||
* @param h the hight of the image
|
||||
* @param w the width of the image
|
||||
* @param d the data for the image in mode
|
||||
*/
|
||||
Bitmap(VideoConvert::Mode mode, uint16_t w, uint16_t h, uint8_t *d);
|
||||
|
||||
/** Destructor */
|
||||
~Bitmap();
|
||||
|
||||
/** Provide the converter with the data that should be output. It will be
|
||||
* converted into rgb8888 and write out when write() is called.
|
||||
* @param d the data
|
||||
*/
|
||||
void rawData(uint8_t* d) { data = d; }
|
||||
|
||||
/** Write the provided data into the fstream provided
|
||||
* @param bmp stream to write to
|
||||
*/
|
||||
void write(std::ostream *bmp) const;
|
||||
|
||||
/** Gets a hash over the bitmap for quick comparisons to other bitmaps.
|
||||
* @return hash of the bitmap
|
||||
*/
|
||||
uint64_t getHash() const { return vc.getHash(data); }
|
||||
|
||||
|
||||
private:
|
||||
VideoConvert::Mode mode;
|
||||
uint16_t height;
|
||||
uint16_t width;
|
||||
uint8_t *data;
|
||||
|
||||
VideoConvert vc;
|
||||
|
||||
mutable char *headerBuffer;
|
||||
static const size_t sizeofHeaderBuffer;
|
||||
|
||||
struct Magic
|
||||
{
|
||||
unsigned char magic_number[2];
|
||||
};
|
||||
|
||||
struct Header
|
||||
{
|
||||
uint32_t size;
|
||||
uint16_t reserved1;
|
||||
uint16_t reserved2;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct Info
|
||||
{
|
||||
uint32_t Size;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
uint16_t Planes;
|
||||
uint16_t BitCount;
|
||||
uint32_t Compression;
|
||||
uint32_t SizeImage;
|
||||
uint32_t XPelsPerMeter;
|
||||
uint32_t YPelsPerMeter;
|
||||
uint32_t ClrUsed;
|
||||
uint32_t ClrImportant;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // __BASE_BITMAP_HH__
|
||||
|
||||
309
simulators/gem5/src/base/bitunion.hh
Normal file
309
simulators/gem5/src/base/bitunion.hh
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008 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.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __BASE_BITUNION_HH__
|
||||
#define __BASE_BITUNION_HH__
|
||||
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
// The following implements the BitUnion system of defining bitfields
|
||||
//on top of an underlying class. This is done through the pervasive use of
|
||||
//both named and unnamed unions which all contain the same actual storage.
|
||||
//Since they're unioned with each other, all of these storage locations
|
||||
//overlap. This allows all of the bitfields to manipulate the same data
|
||||
//without having to have access to each other. More details are provided with
|
||||
//the individual components.
|
||||
|
||||
//This namespace is for classes which implement the backend of the BitUnion
|
||||
//stuff. Don't use any of these directly, except for the Bitfield classes in
|
||||
//the *BitfieldTypes class(es).
|
||||
namespace BitfieldBackend
|
||||
{
|
||||
//A base class for all bitfields. It instantiates the actual storage,
|
||||
//and provides getBits and setBits functions for manipulating it. The
|
||||
//Data template parameter is type of the underlying storage.
|
||||
template<class Data>
|
||||
class BitfieldBase
|
||||
{
|
||||
protected:
|
||||
Data __data;
|
||||
|
||||
//This function returns a range of bits from the underlying storage.
|
||||
//It relies on the "bits" function above. It's the user's
|
||||
//responsibility to make sure that there is a properly overloaded
|
||||
//version of this function for whatever type they want to overlay.
|
||||
inline uint64_t
|
||||
getBits(int first, int last) const
|
||||
{
|
||||
return bits(__data, first, last);
|
||||
}
|
||||
|
||||
//Similar to the above, but for settings bits with replaceBits.
|
||||
inline void
|
||||
setBits(int first, int last, uint64_t val)
|
||||
{
|
||||
replaceBits(__data, first, last, val);
|
||||
}
|
||||
};
|
||||
|
||||
//This class contains all the "regular" bitfield classes. It is inherited
|
||||
//by all BitUnions which give them access to those types.
|
||||
template<class Type>
|
||||
class RegularBitfieldTypes
|
||||
{
|
||||
protected:
|
||||
//This class implements ordinary bitfields, that is a span of bits
|
||||
//who's msb is "first", and who's lsb is "last".
|
||||
template<int first, int last=first>
|
||||
class Bitfield : public BitfieldBase<Type>
|
||||
{
|
||||
public:
|
||||
operator const uint64_t () const
|
||||
{
|
||||
return this->getBits(first, last);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
operator=(const uint64_t _data)
|
||||
{
|
||||
this->setBits(first, last, _data);
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
|
||||
//A class which specializes the above so that it can only be read
|
||||
//from. This is accomplished explicitly making sure the assignment
|
||||
//operator is blocked. The conversion operator is carried through
|
||||
//inheritance. This will unfortunately need to be copied into each
|
||||
//bitfield type due to limitations with how templates work
|
||||
template<int first, int last=first>
|
||||
class BitfieldRO : public Bitfield<first, last>
|
||||
{
|
||||
private:
|
||||
uint64_t
|
||||
operator=(const uint64_t _data);
|
||||
};
|
||||
|
||||
//Similar to the above, but only allows writing.
|
||||
template<int first, int last=first>
|
||||
class BitfieldWO : public Bitfield<first, last>
|
||||
{
|
||||
private:
|
||||
operator const uint64_t () const;
|
||||
|
||||
public:
|
||||
using Bitfield<first, last>::operator=;
|
||||
};
|
||||
};
|
||||
|
||||
//This class contains all the "regular" bitfield classes. It is inherited
|
||||
//by all BitUnions which give them access to those types.
|
||||
template<class Type>
|
||||
class SignedBitfieldTypes
|
||||
{
|
||||
protected:
|
||||
//This class implements ordinary bitfields, that is a span of bits
|
||||
//who's msb is "first", and who's lsb is "last".
|
||||
template<int first, int last=first>
|
||||
class SignedBitfield : public BitfieldBase<Type>
|
||||
{
|
||||
public:
|
||||
operator const int64_t () const
|
||||
{
|
||||
return sext<first - last + 1>(this->getBits(first, last));
|
||||
}
|
||||
|
||||
int64_t
|
||||
operator=(const int64_t _data)
|
||||
{
|
||||
this->setBits(first, last, _data);
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
|
||||
//A class which specializes the above so that it can only be read
|
||||
//from. This is accomplished explicitly making sure the assignment
|
||||
//operator is blocked. The conversion operator is carried through
|
||||
//inheritance. This will unfortunately need to be copied into each
|
||||
//bitfield type due to limitations with how templates work
|
||||
template<int first, int last=first>
|
||||
class SignedBitfieldRO : public SignedBitfield<first, last>
|
||||
{
|
||||
private:
|
||||
int64_t
|
||||
operator=(const int64_t _data);
|
||||
};
|
||||
|
||||
//Similar to the above, but only allows writing.
|
||||
template<int first, int last=first>
|
||||
class SignedBitfieldWO : public SignedBitfield<first, last>
|
||||
{
|
||||
private:
|
||||
operator const int64_t () const;
|
||||
|
||||
public:
|
||||
int64_t operator=(const int64_t _data)
|
||||
{
|
||||
*((SignedBitfield<first, last> *)this) = _data;
|
||||
return _data;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
class BitfieldTypes : public RegularBitfieldTypes<Type>,
|
||||
public SignedBitfieldTypes<Type>
|
||||
{};
|
||||
|
||||
//When a BitUnion is set up, an underlying class is created which holds
|
||||
//the actual union. This class then inherits from it, and provids the
|
||||
//implementations for various operators. Setting things up this way
|
||||
//prevents having to redefine these functions in every different BitUnion
|
||||
//type. More operators could be implemented in the future, as the need
|
||||
//arises.
|
||||
template <class Type, class Base>
|
||||
class BitUnionOperators : public Base
|
||||
{
|
||||
public:
|
||||
BitUnionOperators(Type const & _data)
|
||||
{
|
||||
Base::__data = _data;
|
||||
}
|
||||
|
||||
BitUnionOperators() {}
|
||||
|
||||
operator const Type () const
|
||||
{
|
||||
return Base::__data;
|
||||
}
|
||||
|
||||
Type
|
||||
operator=(Type const & _data)
|
||||
{
|
||||
Base::__data = _data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(Base const & base) const
|
||||
{
|
||||
return Base::__data < base.__data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(Base const & base) const
|
||||
{
|
||||
return Base::__data == base.__data;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//This macro is a backend for other macros that specialize it slightly.
|
||||
//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and
|
||||
//sticks the class which has the actual union in it, which
|
||||
//BitfieldOperators above inherits from. Putting these classes in a special
|
||||
//namespace ensures that there will be no collisions with other names as long
|
||||
//as the BitUnion names themselves are all distinct and nothing else uses
|
||||
//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself
|
||||
//creates a typedef of the "type" parameter called __DataType. This allows
|
||||
//the type to propagate outside of the macro itself in a controlled way.
|
||||
//Finally, the base storage is defined which BitfieldOperators will refer to
|
||||
//in the operators it defines. This macro is intended to be followed by
|
||||
//bitfield definitions which will end up inside it's union. As explained
|
||||
//above, these is overlayed the __data member in its entirety by each of the
|
||||
//bitfields which are defined in the union, creating shared storage with no
|
||||
//overhead.
|
||||
#define __BitUnion(type, name) \
|
||||
class BitfieldUnderlyingClasses##name : \
|
||||
public BitfieldBackend::BitfieldTypes<type> \
|
||||
{ \
|
||||
public: \
|
||||
typedef type __DataType; \
|
||||
union { \
|
||||
type __data;\
|
||||
|
||||
//This closes off the class and union started by the above macro. It is
|
||||
//followed by a typedef which makes "name" refer to a BitfieldOperator
|
||||
//class inheriting from the class and union just defined, which completes
|
||||
//building up the type for the user.
|
||||
#define EndBitUnion(name) \
|
||||
}; \
|
||||
}; \
|
||||
typedef BitfieldBackend::BitUnionOperators< \
|
||||
BitfieldUnderlyingClasses##name::__DataType, \
|
||||
BitfieldUnderlyingClasses##name> name;
|
||||
|
||||
//This sets up a bitfield which has other bitfields nested inside of it. The
|
||||
//__data member functions like the "underlying storage" of the top level
|
||||
//BitUnion. Like everything else, it overlays with the top level storage, so
|
||||
//making it a regular bitfield type makes the entire thing function as a
|
||||
//regular bitfield when referred to by itself.
|
||||
#define __SubBitUnion(fieldType, first, last, name) \
|
||||
class : public BitfieldBackend::BitfieldTypes<__DataType> \
|
||||
{ \
|
||||
public: \
|
||||
union { \
|
||||
fieldType<first, last> __data;
|
||||
|
||||
//This closes off the union created above and gives it a name. Unlike the top
|
||||
//level BitUnion, we're interested in creating an object instead of a type.
|
||||
//The operators are defined in the macro itself instead of a class for
|
||||
//technical reasons. If someone determines a way to move them to one, please
|
||||
//do so.
|
||||
#define EndSubBitUnion(name) \
|
||||
}; \
|
||||
inline operator const __DataType () const \
|
||||
{ return __data; } \
|
||||
\
|
||||
inline const __DataType operator = (const __DataType & _data) \
|
||||
{ return __data = _data;} \
|
||||
} name;
|
||||
|
||||
//Regular bitfields
|
||||
//These define macros for read/write regular bitfield based subbitfields.
|
||||
#define SubBitUnion(name, first, last) \
|
||||
__SubBitUnion(Bitfield, first, last, name)
|
||||
|
||||
//Regular bitfields
|
||||
//These define macros for read/write regular bitfield based subbitfields.
|
||||
#define SignedSubBitUnion(name, first, last) \
|
||||
__SubBitUnion(SignedBitfield, first, last, name)
|
||||
|
||||
//Use this to define an arbitrary type overlayed with bitfields.
|
||||
#define BitUnion(type, name) __BitUnion(type, name)
|
||||
|
||||
//Use this to define conveniently sized values overlayed with bitfields.
|
||||
#define BitUnion64(name) __BitUnion(uint64_t, name)
|
||||
#define BitUnion32(name) __BitUnion(uint32_t, name)
|
||||
#define BitUnion16(name) __BitUnion(uint16_t, name)
|
||||
#define BitUnion8(name) __BitUnion(uint8_t, name)
|
||||
|
||||
#endif // __BASE_BITUNION_HH__
|
||||
39
simulators/gem5/src/base/callback.cc
Normal file
39
simulators/gem5/src/base/callback.cc
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include "base/callback.hh"
|
||||
|
||||
CallbackQueue::~CallbackQueue()
|
||||
{
|
||||
queue::iterator i = callbacks.begin();
|
||||
queue::iterator end = callbacks.end();
|
||||
for (; i != end; ++i)
|
||||
(*i)->autoDestruct();
|
||||
}
|
||||
156
simulators/gem5/src/base/callback.hh
Normal file
156
simulators/gem5/src/base/callback.hh
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_CALLBACK_HH__
|
||||
#define __BASE_CALLBACK_HH__
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Generic callback class. This base class provides a virtual process
|
||||
* function that gets called when the callback queue is processed.
|
||||
*/
|
||||
class Callback
|
||||
{
|
||||
protected:
|
||||
friend class CallbackQueue;
|
||||
virtual void autoDestruct() {}
|
||||
|
||||
public:
|
||||
/**
|
||||
* virtualize the destructor to make sure that the correct one
|
||||
* gets called.
|
||||
*/
|
||||
virtual ~Callback() {}
|
||||
|
||||
/**
|
||||
* virtual process function that is invoked when the callback
|
||||
* queue is executed.
|
||||
*/
|
||||
virtual void process() = 0;
|
||||
};
|
||||
|
||||
/// Helper template class to turn a simple class member function into
|
||||
/// a callback.
|
||||
template <class T, void (T::* F)()>
|
||||
class MakeCallback : public Callback
|
||||
{
|
||||
protected:
|
||||
T *object;
|
||||
const bool autoDestroy;
|
||||
|
||||
void autoDestruct() { if (autoDestroy) delete this; }
|
||||
|
||||
public:
|
||||
MakeCallback(T *o, bool auto_destroy = false)
|
||||
: object(o), autoDestroy(auto_destroy)
|
||||
{ }
|
||||
|
||||
MakeCallback(T &o, bool auto_destroy = false)
|
||||
: object(&o), autoDestroy(auto_destroy)
|
||||
{ }
|
||||
|
||||
void process() { (object->*F)(); }
|
||||
};
|
||||
|
||||
class CallbackQueue
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Simple typedef for the data structure that stores all of the
|
||||
* callbacks.
|
||||
*/
|
||||
typedef std::list<Callback *> queue;
|
||||
|
||||
/**
|
||||
* List of all callbacks. To be called in fifo order.
|
||||
*/
|
||||
queue callbacks;
|
||||
|
||||
public:
|
||||
~CallbackQueue();
|
||||
std::string name() const { return "CallbackQueue"; }
|
||||
|
||||
/**
|
||||
* Add a callback to the end of the queue
|
||||
* @param callback the callback to be added to the queue
|
||||
*/
|
||||
void
|
||||
add(Callback *callback)
|
||||
{
|
||||
callbacks.push_back(callback);
|
||||
}
|
||||
|
||||
template <class T, void (T::* F)()>
|
||||
void
|
||||
add(T *obj)
|
||||
{
|
||||
add(new MakeCallback<T, F>(obj, true));
|
||||
}
|
||||
|
||||
template <class T, void (T::* F)()>
|
||||
void
|
||||
add(T &obj)
|
||||
{
|
||||
add(new MakeCallback<T, F>(&obj, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out if there are any callbacks in the queue
|
||||
*/
|
||||
bool empty() const { return callbacks.empty(); }
|
||||
|
||||
/**
|
||||
* process all callbacks
|
||||
*/
|
||||
void
|
||||
process()
|
||||
{
|
||||
queue::iterator i = callbacks.begin();
|
||||
queue::iterator end = callbacks.end();
|
||||
|
||||
while (i != end) {
|
||||
(*i)->process();
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the callback queue
|
||||
*/
|
||||
void
|
||||
clear()
|
||||
{
|
||||
callbacks.clear();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __BASE_CALLBACK_HH__
|
||||
68
simulators/gem5/src/base/cast.hh
Normal file
68
simulators/gem5/src/base/cast.hh
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2008 The Hewlett-Packard Development Company
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_CAST_HH__
|
||||
#define __BASE_CAST_HH__
|
||||
|
||||
#include <cassert>
|
||||
|
||||
// This is designed for situations where we have a pointer to a base
|
||||
// type, but in all cases when we cast it to a derived type, we know
|
||||
// by construction that it should work correctly.
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
// In debug builds, do the dynamic cast and assert the result is good
|
||||
|
||||
template <class T, class U>
|
||||
inline T
|
||||
safe_cast(U ptr)
|
||||
{
|
||||
T ret = dynamic_cast<T>(ptr);
|
||||
assert(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// In non debug builds statically cast the result to the pointer we
|
||||
// want to use. This is technically unsafe, but this is only for
|
||||
// cases where we know that this should work by construction.
|
||||
|
||||
template <class T, class U>
|
||||
inline T
|
||||
safe_cast(U ptr)
|
||||
{
|
||||
return static_cast<T>(ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __BASE_CAST_HH__
|
||||
147
simulators/gem5/src/base/chunk_generator.hh
Normal file
147
simulators/gem5/src/base/chunk_generator.hh
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __BASE__CHUNK_GENERATOR_HH__
|
||||
#define __BASE__CHUNK_GENERATOR_HH__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Declaration and inline definition of ChunkGenerator object.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/intmath.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
/**
|
||||
* This class takes an arbitrary memory region (address/length pair)
|
||||
* and generates a series of appropriately (e.g. block- or page-)
|
||||
* aligned chunks covering the same region.
|
||||
*
|
||||
* Example usage:
|
||||
|
||||
\code
|
||||
for (ChunkGenerator gen(addr, size, chunkSize); !gen.done(); gen.next()) {
|
||||
doSomethingChunky(gen.addr(), gen.size());
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class ChunkGenerator
|
||||
{
|
||||
private:
|
||||
/** The starting address of the current chunk. */
|
||||
Addr curAddr;
|
||||
/** The starting address of the next chunk (after the current one). */
|
||||
Addr nextAddr;
|
||||
/** The size of the current chunk (in bytes). */
|
||||
unsigned curSize;
|
||||
/** The number of bytes remaining in the region after the current chunk. */
|
||||
unsigned sizeLeft;
|
||||
/** The start address so we can calculate offset in writing block. */
|
||||
const Addr startAddr;
|
||||
/** The maximum chunk size, e.g., the cache block size or page size. */
|
||||
const unsigned chunkSize;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param _startAddr The starting address of the region.
|
||||
* @param totalSize The total size of the region.
|
||||
* @param _chunkSize The size/alignment of chunks into which
|
||||
* the region should be decomposed.
|
||||
*/
|
||||
ChunkGenerator(Addr _startAddr, unsigned totalSize, unsigned _chunkSize)
|
||||
: startAddr(_startAddr), chunkSize(_chunkSize)
|
||||
{
|
||||
// chunkSize must be a power of two
|
||||
assert(chunkSize == 0 || isPowerOf2(chunkSize));
|
||||
assert(totalSize >= 0);
|
||||
|
||||
// set up initial chunk.
|
||||
curAddr = startAddr;
|
||||
|
||||
if (chunkSize == 0) //Special Case, if we see 0, assume no chuncking
|
||||
{
|
||||
nextAddr = startAddr + totalSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nextAddr should be *next* chunk start
|
||||
nextAddr = roundUp(startAddr, chunkSize);
|
||||
if (curAddr == nextAddr) {
|
||||
// ... even if startAddr is already chunk-aligned
|
||||
nextAddr += chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
// how many bytes are left between curAddr and the end of this chunk?
|
||||
unsigned left_in_chunk = nextAddr - curAddr;
|
||||
curSize = std::min(totalSize, left_in_chunk);
|
||||
sizeLeft = totalSize - curSize;
|
||||
}
|
||||
|
||||
/** Return starting address of current chunk. */
|
||||
Addr addr() const { return curAddr; }
|
||||
/** Return size in bytes of current chunk. */
|
||||
unsigned size() const { return curSize; }
|
||||
|
||||
/** Number of bytes we have already chunked up. */
|
||||
unsigned complete() const { return curAddr - startAddr; }
|
||||
|
||||
/**
|
||||
* Are we done? That is, did the last call to next() advance
|
||||
* past the end of the region?
|
||||
* @return True if yes, false if more to go.
|
||||
*/
|
||||
bool done() const { return (curSize == 0); }
|
||||
|
||||
/**
|
||||
* Advance generator to next chunk.
|
||||
* @return True if successful, false if unsuccessful
|
||||
* (because we were at the last chunk).
|
||||
*/
|
||||
bool
|
||||
next()
|
||||
{
|
||||
if (sizeLeft == 0) {
|
||||
curSize = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
curAddr = nextAddr;
|
||||
curSize = std::min(sizeLeft, chunkSize);
|
||||
sizeLeft -= curSize;
|
||||
nextAddr += curSize;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __BASE__CHUNK_GENERATOR_HH__
|
||||
214
simulators/gem5/src/base/circlebuf.cc
Normal file
214
simulators/gem5/src/base/circlebuf.cc
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "base/atomicio.hh"
|
||||
#include "base/circlebuf.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/intmath.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
CircleBuf::CircleBuf(int l)
|
||||
: _rollover(false), _buflen(l), _size(0), _start(0), _stop(0)
|
||||
{
|
||||
_buf = new char[_buflen];
|
||||
}
|
||||
|
||||
CircleBuf::~CircleBuf()
|
||||
{
|
||||
if (_buf)
|
||||
delete [] _buf;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::dump()
|
||||
{
|
||||
cprintf("start = %10d, stop = %10d, buflen = %10d\n",
|
||||
_start, _stop, _buflen);
|
||||
fflush(stdout);
|
||||
atomic_write(STDOUT_FILENO, _buf, _buflen);
|
||||
atomic_write(STDOUT_FILENO, "<\n", 2);
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::flush()
|
||||
{
|
||||
_start = 0;
|
||||
_stop = 0;
|
||||
_rollover = false;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(char *b, int len)
|
||||
{
|
||||
_size -= len;
|
||||
if (_size < 0)
|
||||
_size = 0;
|
||||
|
||||
if (_stop > _start) {
|
||||
len = min(len, _stop - _start);
|
||||
memcpy(b, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
int endlen = _buflen - _start;
|
||||
if (endlen > len) {
|
||||
memcpy(b, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
memcpy(b, _buf + _start, endlen);
|
||||
_start = min(len - endlen, _stop);
|
||||
memcpy(b + endlen, _buf, _start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(int fd, int len)
|
||||
{
|
||||
_size -= len;
|
||||
if (_size < 0)
|
||||
_size = 0;
|
||||
|
||||
if (_stop > _start) {
|
||||
len = min(len, _stop - _start);
|
||||
atomic_write(fd, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
int endlen = _buflen - _start;
|
||||
if (endlen > len) {
|
||||
atomic_write(fd, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
atomic_write(fd, _buf + _start, endlen);
|
||||
_start = min(len - endlen, _stop);
|
||||
atomic_write(fd, _buf, _start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(int fd)
|
||||
{
|
||||
_size = 0;
|
||||
|
||||
if (_stop > _start) {
|
||||
atomic_write(fd, _buf + _start, _stop - _start);
|
||||
}
|
||||
else {
|
||||
atomic_write(fd, _buf + _start, _buflen - _start);
|
||||
atomic_write(fd, _buf, _stop);
|
||||
}
|
||||
|
||||
_start = _stop;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(ostream &out)
|
||||
{
|
||||
_size = 0;
|
||||
|
||||
if (_stop > _start) {
|
||||
out.write(_buf + _start, _stop - _start);
|
||||
}
|
||||
else {
|
||||
out.write(_buf + _start, _buflen - _start);
|
||||
out.write(_buf, _stop);
|
||||
}
|
||||
|
||||
_start = _stop;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::readall(int fd)
|
||||
{
|
||||
if (_rollover)
|
||||
atomic_write(fd, _buf + _stop, _buflen - _stop);
|
||||
|
||||
atomic_write(fd, _buf, _stop);
|
||||
_start = _stop;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::write(char b)
|
||||
{
|
||||
write(&b, 1);
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::write(const char *b)
|
||||
{
|
||||
write(b, strlen(b));
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::write(const char *b, int len)
|
||||
{
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
_size += len;
|
||||
if (_size > _buflen)
|
||||
_size = _buflen;
|
||||
|
||||
int old_start = _start;
|
||||
int old_stop = _stop;
|
||||
|
||||
if (len >= _buflen) {
|
||||
_start = 0;
|
||||
_stop = _buflen;
|
||||
_rollover = true;
|
||||
memcpy(_buf, b + (len - _buflen), _buflen);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_stop + len <= _buflen) {
|
||||
memcpy(_buf + _stop, b, len);
|
||||
_stop += len;
|
||||
} else {
|
||||
int end_len = _buflen - old_stop;
|
||||
_stop = len - end_len;
|
||||
memcpy(_buf + old_stop, b, end_len);
|
||||
memcpy(_buf, b + end_len, _stop);
|
||||
_rollover = true;
|
||||
}
|
||||
|
||||
if ((old_start > old_stop && old_start < _stop) ||
|
||||
(old_start < old_stop && _stop < old_stop))
|
||||
_start = _stop + 1;
|
||||
}
|
||||
64
simulators/gem5/src/base/circlebuf.hh
Normal file
64
simulators/gem5/src/base/circlebuf.hh
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __CIRCLEBUF_HH__
|
||||
#define __CIRCLEBUF_HH__
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
class CircleBuf
|
||||
{
|
||||
protected:
|
||||
char *_buf;
|
||||
bool _rollover;
|
||||
int _buflen;
|
||||
int _size;
|
||||
int _start;
|
||||
int _stop;
|
||||
|
||||
public:
|
||||
explicit CircleBuf(int l);
|
||||
~CircleBuf();
|
||||
|
||||
bool empty() const { return _size == 0; }
|
||||
int size() const { return _size; }
|
||||
void dump();
|
||||
void flush();
|
||||
void read(char *b, int len);
|
||||
void read(int fd, int len);
|
||||
void read(int fd);
|
||||
void read(std::ostream &out);
|
||||
void readall(int fd);
|
||||
void write(char b);
|
||||
void write(const char *b);
|
||||
void write(const char *b, int len);
|
||||
};
|
||||
|
||||
#endif // __CIRCLEBUF_HH__
|
||||
59
simulators/gem5/src/base/compiler.hh
Normal file
59
simulators/gem5/src/base/compiler.hh
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __BASE_COMPILER_HH__
|
||||
#define __BASE_COMPILER_HH__
|
||||
|
||||
//http://msdn2.microsoft.com/en-us/library/ms937669.aspx
|
||||
//http://msdn2.microsoft.com/en-us/library/aa448724.aspx
|
||||
//http://docs.sun.com/source/819-3688/sun.specific.html#marker-998278
|
||||
//http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Function-Attributes.html#Function%20Attributes
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define M5_ATTR_NORETURN __attribute__((noreturn))
|
||||
#define M5_PRAGMA_NORETURN(x)
|
||||
#define M5_DUMMY_RETURN
|
||||
#define M5_VAR_USED __attribute__((unused))
|
||||
#define M5_ATTR_PACKED __attribute__ ((__packed__))
|
||||
#define M5_NO_INLINE __attribute__ ((__noinline__))
|
||||
#elif defined(__SUNPRO_CC)
|
||||
// this doesn't do anything with sun cc, but why not
|
||||
#define M5_ATTR_NORETURN __sun_attr__((__noreturn__))
|
||||
#define M5_DUMMY_RETURN return (0);
|
||||
#define DO_PRAGMA(x) _Pragma(#x)
|
||||
#define M5_VAR_USED
|
||||
#define M5_PRAGMA_NORETURN(x) DO_PRAGMA(does_not_return(x))
|
||||
#define M5_ATTR_PACKED __attribute__ ((__packed__))
|
||||
#define M5_NO_INLINE __attribute__ ((__noinline__))
|
||||
#else
|
||||
#error "Need to define compiler options in base/compiler.hh"
|
||||
#endif
|
||||
|
||||
#endif // __BASE_COMPILER_HH__
|
||||
94
simulators/gem5/src/base/condcodes.hh
Normal file
94
simulators/gem5/src/base/condcodes.hh
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __BASE_CONDCODE_HH__
|
||||
#define __BASE_CONDCODE_HH__
|
||||
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/trace.hh"
|
||||
|
||||
/**
|
||||
* Calculate the carry flag from an addition. This should work even when
|
||||
* a carry value is also added in.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findCarry(int width, uint64_t dest, uint64_t src1, uint64_t src2) {
|
||||
int shift = width - 1;
|
||||
return ((~(dest >> shift) & 1) +
|
||||
((src1 >> shift) & 1) +
|
||||
((src2 >> shift) & 1)) & 0x2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the overflow flag from an addition.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findOverflow(int width, uint64_t dest, uint64_t src1, uint64_t src2) {
|
||||
int shift = width - 1;
|
||||
return ((src1 ^ ~src2) & (src1 ^ dest)) & (1ULL << shift);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the parity of a value. 1 is for odd parity and 0 is for even.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findParity(int width, uint64_t dest) {
|
||||
dest &= mask(width);
|
||||
dest ^= (dest >> 32);
|
||||
dest ^= (dest >> 16);
|
||||
dest ^= (dest >> 8);
|
||||
dest ^= (dest >> 4);
|
||||
dest ^= (dest >> 2);
|
||||
dest ^= (dest >> 1);
|
||||
return dest & 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the negative flag.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findNegative(int width, uint64_t dest) {
|
||||
return bits(dest, width - 1, width - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the zero flag.
|
||||
*/
|
||||
inline
|
||||
bool
|
||||
findZero(int width, uint64_t dest) {
|
||||
return !(dest & mask(width));
|
||||
}
|
||||
|
||||
#endif // __BASE_CONDCODE_HH__
|
||||
1405
simulators/gem5/src/base/cp_annotate.cc
Normal file
1405
simulators/gem5/src/base/cp_annotate.cc
Normal file
File diff suppressed because it is too large
Load Diff
523
simulators/gem5/src/base/cp_annotate.hh
Normal file
523
simulators/gem5/src/base/cp_annotate.hh
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __BASE__CP_ANNOTATE_HH__
|
||||
#define __BASE__CP_ANNOTATE_HH__
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/hashmap.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "base/types.hh"
|
||||
#include "config/cp_annotate.hh"
|
||||
#include "config/the_isa.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
#if CP_ANNOTATE
|
||||
#include "params/CPA.hh"
|
||||
#endif
|
||||
|
||||
class System;
|
||||
class ThreadContext;
|
||||
|
||||
|
||||
#if !CP_ANNOTATE
|
||||
class CPA
|
||||
{
|
||||
public:
|
||||
enum flags {
|
||||
FL_NONE = 0x00,
|
||||
FL_HW = 0x01,
|
||||
FL_BAD = 0x02,
|
||||
FL_QOPP = 0x04,
|
||||
FL_WAIT = 0x08,
|
||||
FL_LINK = 0x10,
|
||||
FL_RESET = 0x20
|
||||
};
|
||||
|
||||
static CPA *cpa() { return NULL; }
|
||||
static bool available() { return false; }
|
||||
bool enabled() { return false; }
|
||||
void swSmBegin(ThreadContext *tc) { return; }
|
||||
void swSmEnd(ThreadContext *tc) { return; }
|
||||
void swExplictBegin(ThreadContext *tc) { return; }
|
||||
void swAutoBegin(ThreadContext *tc, Addr next_pc) { return; }
|
||||
void swEnd(ThreadContext *tc) { return; }
|
||||
void swQ(ThreadContext *tc) { return; }
|
||||
void swDq(ThreadContext *tc) { return; }
|
||||
void swPq(ThreadContext *tc) { return; }
|
||||
void swRq(ThreadContext *tc) { return; }
|
||||
void swWf(ThreadContext *tc) { return; }
|
||||
void swWe(ThreadContext *tc) { return; }
|
||||
void swSq(ThreadContext *tc) { return; }
|
||||
void swAq(ThreadContext *tc) { return; }
|
||||
void swLink(ThreadContext *tc) { return; }
|
||||
void swIdentify(ThreadContext *tc) { return; }
|
||||
uint64_t swGetId(ThreadContext *tc) { return 0; }
|
||||
void swSyscallLink(ThreadContext *tc) { return; }
|
||||
void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string st) { return; }
|
||||
void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||
int32_t count = 1) { return; }
|
||||
void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||
int32_t count = 1) { return; }
|
||||
void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||
int32_t count = 1) { return; }
|
||||
void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||
int32_t count = 1) { return; }
|
||||
void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||
int32_t count = 1) { return; }
|
||||
void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||
int32_t count = 1) { return; }
|
||||
};
|
||||
#else
|
||||
class CPA : SimObject
|
||||
{
|
||||
public:
|
||||
typedef CPAParams Params;
|
||||
|
||||
/** The known operations that are written to the annotation output file. */
|
||||
enum ops {
|
||||
OP_BEGIN = 0x01,
|
||||
OP_WAIT_EMPTY = 0x02,
|
||||
OP_WAIT_FULL = 0x03,
|
||||
OP_QUEUE = 0x04,
|
||||
OP_DEQUEUE = 0x05,
|
||||
OP_SIZE_QUEUE = 0x08,
|
||||
OP_PEEK = 0x09,
|
||||
OP_LINK = 0x0A,
|
||||
OP_IDENT = 0x0B,
|
||||
OP_RESERVE = 0x0C
|
||||
};
|
||||
|
||||
/** Flags for the various options.*/
|
||||
enum flags {
|
||||
/* no flags */
|
||||
FL_NONE = 0x00,
|
||||
/* operation was done on hardware */
|
||||
FL_HW = 0x01,
|
||||
/* operation should cause a warning when encountered */
|
||||
FL_BAD = 0x02,
|
||||
/* Queue like a stack, not a queue */
|
||||
FL_QOPP = 0x04,
|
||||
/* Mark HW state as waiting for some non-resource constraint
|
||||
* (e.g. wait because SM only starts after 10 items are queued) */
|
||||
FL_WAIT = 0x08,
|
||||
/* operation is linking to another state machine */
|
||||
FL_LINK = 0x10,
|
||||
/* queue should be completely cleared/reset before executing this
|
||||
* operation */
|
||||
FL_RESET = 0x20
|
||||
};
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
const Params *
|
||||
params() const
|
||||
{
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
/* struct that is written to the annotation output file */
|
||||
struct AnnotateData : public RefCounted {
|
||||
|
||||
Tick time;
|
||||
uint32_t data;
|
||||
uint32_t orig_data;
|
||||
uint16_t sm;
|
||||
uint16_t stq;
|
||||
uint8_t op;
|
||||
uint8_t flag;
|
||||
uint8_t cpu;
|
||||
bool dump;
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
typedef RefCountingPtr<AnnotateData> AnnDataPtr;
|
||||
|
||||
/* header for the annotation file */
|
||||
struct AnnotateHeader {
|
||||
uint64_t version;
|
||||
uint64_t num_recs;
|
||||
uint64_t key_off;
|
||||
uint64_t idx_off;
|
||||
uint32_t key_len;
|
||||
uint32_t idx_len;
|
||||
};
|
||||
|
||||
AnnotateHeader ah;
|
||||
|
||||
std::vector<uint64_t> annotateIdx;
|
||||
|
||||
// number of state machines encountered in the simulation
|
||||
int numSm;
|
||||
// number of states encountered in the simulation
|
||||
int numSmt;
|
||||
// number of states/queues for a given state machine/system respectively
|
||||
std::vector<int> numSt, numQ;
|
||||
// number of systems in the simulation
|
||||
int numSys;
|
||||
// number of queues in the state machine
|
||||
int numQs;
|
||||
// maximum connection id assigned so far
|
||||
uint64_t conId;
|
||||
|
||||
// Convert state strings into state ids
|
||||
typedef m5::hash_map<std::string, int> SCache;
|
||||
typedef std::vector<SCache> StCache;
|
||||
|
||||
// Convert sm and queue name,id into queue id
|
||||
typedef std::pair<std::string, uint64_t> Id;
|
||||
typedef m5::hash_map<Id, int> IdHCache;
|
||||
typedef std::vector<IdHCache> IdCache;
|
||||
|
||||
// Hold mapping of sm and queues to output python
|
||||
typedef std::vector<std::pair<int, Id> > IdMap;
|
||||
|
||||
// System pointer to name,id
|
||||
typedef std::map<System*, std::pair<std::string, int> > NameCache;
|
||||
|
||||
// array of systems each of which is a stack of running sm
|
||||
typedef std::pair<int, uint64_t> StackId;
|
||||
typedef std::map<StackId, std::vector<int> > SmStack;
|
||||
|
||||
// map of each context and if it's currently in explict state mode
|
||||
// states are not automatically updated until it leaves
|
||||
typedef std::map<StackId, bool> SwExpl;
|
||||
|
||||
typedef std::map<int,int> IMap;
|
||||
// List of annotate records have not been written/completed yet
|
||||
typedef std::list<AnnDataPtr> AnnotateList;
|
||||
|
||||
// Maintain link state information
|
||||
typedef std::map<int, int> LinkMap;
|
||||
|
||||
// SC Links
|
||||
typedef m5::hash_map<Id, AnnDataPtr> ScHCache;
|
||||
typedef std::vector<ScHCache> ScCache;
|
||||
|
||||
|
||||
AnnotateList data;
|
||||
|
||||
// vector indexed by queueid to find current number of elements and bytes
|
||||
std::vector<int> qSize;
|
||||
std::vector<int32_t> qBytes;
|
||||
|
||||
|
||||
// Turn state machine string into state machine id (small int)
|
||||
// Used for outputting key to convert id back into string
|
||||
SCache smtCache;
|
||||
// Turn state machine id, state name into state id (small int)
|
||||
StCache stCache;
|
||||
// turn system, queue, and queue identify into qid (small int)
|
||||
// turn system, state, and context into state machine id (small int)
|
||||
IdCache qCache, smCache;
|
||||
//Link state machines accross system calls
|
||||
ScCache scLinks;
|
||||
// System pointer to name,id
|
||||
NameCache nameCache;
|
||||
// Stack of state machines currently nested (should unwind correctly)
|
||||
SmStack smStack;
|
||||
// Map of currently outstanding links
|
||||
LinkMap lnMap;
|
||||
// If the state machine is currently exculding automatic changes
|
||||
SwExpl swExpl;
|
||||
// Last state that a given state machine was in
|
||||
IMap lastState;
|
||||
// Hold mapping of sm and queues to output python
|
||||
IdMap smMap, qMap;
|
||||
// Items still in queue, used for sanity checking
|
||||
std::vector<AnnotateList> qData;
|
||||
|
||||
void doDq(System *sys, int flags, int cpu, int sm, std::string q, int qi,
|
||||
int count);
|
||||
void doQ(System *sys, int flags, int cpu, int sm, std::string q, int qi,
|
||||
int count);
|
||||
|
||||
void doSwSmEnd(System *sys, int cpuid, std::string sm, uint64_t frame);
|
||||
|
||||
// Turn a system id, state machine string, state machine id into a small int
|
||||
// for annotation output
|
||||
int
|
||||
getSm(int sysi, std::string si, uint64_t id)
|
||||
{
|
||||
int smi;
|
||||
Id smid = Id(si, id);
|
||||
|
||||
smi = smCache[sysi-1][smid];
|
||||
if (smi == 0) {
|
||||
smCache[sysi-1][smid] = smi = ++numSm;
|
||||
assert(smi < 65535);
|
||||
smMap.push_back(std::make_pair<int, Id>(sysi, smid));
|
||||
}
|
||||
return smi;
|
||||
}
|
||||
|
||||
// Turn a state machine string, state string into a small int
|
||||
// for annotation output
|
||||
int
|
||||
getSt(std::string sm, std::string s)
|
||||
{
|
||||
int sti, smi;
|
||||
|
||||
smi = smtCache[sm];
|
||||
if (smi == 0)
|
||||
smi = smtCache[sm] = ++numSmt;
|
||||
|
||||
while (stCache.size() < smi) {
|
||||
//stCache.resize(sm);
|
||||
stCache.push_back(SCache());
|
||||
numSt.push_back(0);
|
||||
}
|
||||
//assert(stCache.size() == sm);
|
||||
//assert(numSt.size() == sm);
|
||||
sti = stCache[smi-1][s];
|
||||
if (sti == 0)
|
||||
stCache[smi-1][s] = sti = ++numSt[smi-1];
|
||||
return sti;
|
||||
}
|
||||
|
||||
// Turn state machine pointer into a smal int for annotation output
|
||||
int
|
||||
getSys(System *s)
|
||||
{
|
||||
NameCache::iterator i = nameCache.find(s);
|
||||
if (i == nameCache.end()) {
|
||||
nameCache[s] = std::make_pair<std::string,int>(s->name(), ++numSys);
|
||||
i = nameCache.find(s);
|
||||
// might need to put smstackid into map here, but perhaps not
|
||||
//smStack.push_back(std::vector<int>());
|
||||
//swExpl.push_back(false);
|
||||
numQ.push_back(0);
|
||||
qCache.push_back(IdHCache());
|
||||
smCache.push_back(IdHCache());
|
||||
scLinks.push_back(ScHCache());
|
||||
}
|
||||
return i->second.second;
|
||||
}
|
||||
|
||||
// Turn queue name, and queue context into small int for
|
||||
// annotation output
|
||||
int
|
||||
getQ(int sys, std::string q, uint64_t id)
|
||||
{
|
||||
int qi;
|
||||
Id qid = Id(q, id);
|
||||
|
||||
qi = qCache[sys-1][qid];
|
||||
if (qi == 0) {
|
||||
qi = qCache[sys-1][qid] = ++numQs;
|
||||
assert(qi < 65535);
|
||||
qSize.push_back(0);
|
||||
qBytes.push_back(0);
|
||||
qData.push_back(AnnotateList());
|
||||
numQ[sys-1]++;
|
||||
qMap.push_back(std::make_pair<int, Id>(sys, qid));
|
||||
}
|
||||
return qi;
|
||||
}
|
||||
|
||||
void swBegin(System *sys, int cpuid, std::string st, uint64_t frame,
|
||||
bool expl = false, int flags = FL_NONE);
|
||||
|
||||
AnnDataPtr add(int t, int f, int c, int sm, int stq, int32_t data=0);
|
||||
|
||||
std::ostream *osbin;
|
||||
|
||||
bool _enabled;
|
||||
|
||||
/** Only allow one CPA object in a system. It doesn't make sense to have
|
||||
* more that one per simulation because if a part of the system was
|
||||
* important it would have annotations and queues, and with more than one
|
||||
* object none of the sanity checking for queues will work. */
|
||||
static bool exists;
|
||||
static CPA *_cpa;
|
||||
|
||||
|
||||
std::map<std::string, SymbolTable*> userApp;
|
||||
|
||||
public:
|
||||
static CPA *cpa() { return _cpa; }
|
||||
void swSmBegin(ThreadContext *tc);
|
||||
void swSmEnd(ThreadContext *tc);
|
||||
void swExplictBegin(ThreadContext *tc);
|
||||
void swAutoBegin(ThreadContext *tc, Addr next_pc);
|
||||
void swEnd(ThreadContext *tc);
|
||||
void swQ(ThreadContext *tc);
|
||||
void swDq(ThreadContext *tc);
|
||||
void swPq(ThreadContext *tc);
|
||||
void swRq(ThreadContext *tc);
|
||||
void swWf(ThreadContext *tc);
|
||||
void swWe(ThreadContext *tc);
|
||||
void swSq(ThreadContext *tc);
|
||||
void swAq(ThreadContext *tc);
|
||||
void swLink(ThreadContext *tc);
|
||||
void swIdentify(ThreadContext *tc);
|
||||
uint64_t swGetId(ThreadContext *tc);
|
||||
void swSyscallLink(ThreadContext *tc);
|
||||
|
||||
inline void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string st)
|
||||
{
|
||||
if (!enabled())
|
||||
return;
|
||||
|
||||
int sysi = getSys(sys);
|
||||
int smi = getSm(sysi, sm, frame);
|
||||
add(OP_BEGIN, FL_HW | f, 0, smi, getSt(sm, st));
|
||||
if (f & FL_BAD)
|
||||
warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
|
||||
}
|
||||
|
||||
inline void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||
{
|
||||
if (!enabled())
|
||||
return;
|
||||
|
||||
int sysi = getSys(sys);
|
||||
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||
DPRINTFS(AnnotateQ, sys,
|
||||
"hwQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
|
||||
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||
doQ(sys, FL_HW | f, 0, getSm(sysi, sm, frame), q, qi, count);
|
||||
|
||||
}
|
||||
|
||||
inline void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||
{
|
||||
if (!enabled())
|
||||
return;
|
||||
|
||||
int sysi = getSys(sys);
|
||||
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||
DPRINTFS(AnnotateQ, sys,
|
||||
"hwDQ: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
|
||||
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||
doDq(sys, FL_HW | f, 0, getSm(sysi,sm, frame), q, qi, count);
|
||||
}
|
||||
|
||||
inline void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||
{
|
||||
if (!enabled())
|
||||
return;
|
||||
|
||||
int sysi = getSys(sys);
|
||||
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||
DPRINTFS(AnnotateQ, sys,
|
||||
"hwPQ: %s[%#x] cur size %d %d bytes: %d peeking: %d\n",
|
||||
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||
add(OP_PEEK, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||
}
|
||||
|
||||
inline void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||
{
|
||||
if (!enabled())
|
||||
return;
|
||||
|
||||
int sysi = getSys(sys);
|
||||
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||
DPRINTFS(AnnotateQ, sys,
|
||||
"hwRQ: %s[%#x] cur size %d %d bytes: %d reserving: %d\n",
|
||||
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||
add(OP_RESERVE, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||
}
|
||||
|
||||
inline void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||
{
|
||||
if (!enabled())
|
||||
return;
|
||||
|
||||
int sysi = getSys(sys);
|
||||
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||
add(OP_WAIT_FULL, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||
}
|
||||
|
||||
inline void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
|
||||
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||
{
|
||||
if (!enabled())
|
||||
return;
|
||||
|
||||
int sysi = getSys(sys);
|
||||
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||
add(OP_WAIT_EMPTY, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||
}
|
||||
|
||||
public:
|
||||
CPA(Params *p);
|
||||
void startup();
|
||||
|
||||
// This code is ISA specific and will need to be changed
|
||||
// if the annotation code is used for something other than Alpha
|
||||
inline uint64_t getFrame(ThreadContext *tc)
|
||||
{ return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) &
|
||||
~ULL(0x3FFF)); }
|
||||
|
||||
static bool available() { return true; }
|
||||
|
||||
bool
|
||||
enabled()
|
||||
{
|
||||
if (!this)
|
||||
return false;
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
void dump(bool all);
|
||||
void dumpKey();
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
#endif // !CP_ANNOTATE
|
||||
|
||||
#endif //__BASE__CP_ANNOTATE_HH__
|
||||
|
||||
294
simulators/gem5/src/base/cprintf.cc
Normal file
294
simulators/gem5/src/base/cprintf.cc
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2006 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace cp {
|
||||
|
||||
Print::Print(std::ostream &stream, const std::string &format)
|
||||
: stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false)
|
||||
{
|
||||
saved_flags = stream.flags();
|
||||
saved_fill = stream.fill();
|
||||
saved_precision = stream.precision();
|
||||
}
|
||||
|
||||
Print::Print(std::ostream &stream, const char *format)
|
||||
: stream(stream), format(format), ptr(format), cont(false)
|
||||
{
|
||||
saved_flags = stream.flags();
|
||||
saved_fill = stream.fill();
|
||||
saved_precision = stream.precision();
|
||||
}
|
||||
|
||||
Print::~Print()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Print::process()
|
||||
{
|
||||
fmt.clear();
|
||||
|
||||
size_t len;
|
||||
|
||||
while (*ptr) {
|
||||
switch (*ptr) {
|
||||
case '%':
|
||||
if (ptr[1] != '%')
|
||||
goto processing;
|
||||
|
||||
stream.put('%');
|
||||
ptr += 2;
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
stream << endl;
|
||||
++ptr;
|
||||
break;
|
||||
case '\r':
|
||||
++ptr;
|
||||
if (*ptr != '\n')
|
||||
stream << endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
len = strcspn(ptr, "%\n\r\0");
|
||||
stream.write(ptr, len);
|
||||
ptr += len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
processing:
|
||||
bool done = false;
|
||||
bool end_number = false;
|
||||
bool have_precision = false;
|
||||
int number = 0;
|
||||
|
||||
stream.fill(' ');
|
||||
stream.flags((ios::fmtflags)0);
|
||||
|
||||
while (!done) {
|
||||
++ptr;
|
||||
if (*ptr >= '0' && *ptr <= '9') {
|
||||
if (end_number)
|
||||
continue;
|
||||
} else if (number > 0)
|
||||
end_number = true;
|
||||
|
||||
switch (*ptr) {
|
||||
case 's':
|
||||
fmt.format = Format::string;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
fmt.format = Format::character;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
fmt.format = Format::integer;
|
||||
fmt.base = Format::hex;
|
||||
fmt.alternate_form = true;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
fmt.uppercase = true;
|
||||
case 'x':
|
||||
fmt.base = Format::hex;
|
||||
fmt.format = Format::integer;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
fmt.base = Format::oct;
|
||||
fmt.format = Format::integer;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
case 'u':
|
||||
fmt.format = Format::integer;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
fmt.uppercase = true;
|
||||
case 'g':
|
||||
fmt.format = Format::floating;
|
||||
fmt.float_format = Format::best;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
fmt.uppercase = true;
|
||||
case 'e':
|
||||
fmt.format = Format::floating;
|
||||
fmt.float_format = Format::scientific;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
fmt.format = Format::floating;
|
||||
fmt.float_format = Format::fixed;
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
stream << "we don't do %n!!!\n";
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
fmt.alternate_form = true;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fmt.flush_left = true;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fmt.print_sign = true;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
fmt.blank_space = true;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
fmt.width = number;
|
||||
fmt.precision = 0;
|
||||
have_precision = true;
|
||||
number = 0;
|
||||
end_number = false;
|
||||
break;
|
||||
|
||||
case '0':
|
||||
if (number == 0) {
|
||||
fmt.fill_zero = true;
|
||||
break;
|
||||
}
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
number = number * 10 + (*ptr - '0');
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (have_precision)
|
||||
fmt.get_precision = true;
|
||||
else
|
||||
fmt.get_width = true;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
assert(false && "we shouldn't get here");
|
||||
break;
|
||||
|
||||
default:
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (end_number) {
|
||||
if (have_precision)
|
||||
fmt.precision = number;
|
||||
else
|
||||
fmt.width = number;
|
||||
|
||||
end_number = false;
|
||||
number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
++ptr;
|
||||
}
|
||||
|
||||
void
|
||||
Print::end_args()
|
||||
{
|
||||
size_t len;
|
||||
|
||||
while (*ptr) {
|
||||
switch (*ptr) {
|
||||
case '%':
|
||||
if (ptr[1] != '%')
|
||||
stream << "<extra arg>";
|
||||
|
||||
stream.put('%');
|
||||
ptr += 2;
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
stream << endl;
|
||||
++ptr;
|
||||
break;
|
||||
case '\r':
|
||||
++ptr;
|
||||
if (*ptr != '\n')
|
||||
stream << endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
len = strcspn(ptr, "%\n\r\0");
|
||||
stream.write(ptr, len);
|
||||
ptr += len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stream.flags(saved_flags);
|
||||
stream.fill(saved_fill);
|
||||
stream.precision(saved_precision);
|
||||
}
|
||||
|
||||
} // namespace cp
|
||||
192
simulators/gem5/src/base/cprintf.hh
Normal file
192
simulators/gem5/src/base/cprintf.hh
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2006 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __BASE_CPRINTF_HH__
|
||||
#define __BASE_CPRINTF_HH__
|
||||
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "base/cprintf_formats.hh"
|
||||
#include "base/varargs.hh"
|
||||
|
||||
namespace cp {
|
||||
|
||||
#define CPRINTF_DECLARATION VARARGS_DECLARATION(cp::Print)
|
||||
#define CPRINTF_DEFINITION VARARGS_DEFINITION(cp::Print)
|
||||
|
||||
struct Print
|
||||
{
|
||||
protected:
|
||||
std::ostream &stream;
|
||||
const char *format;
|
||||
const char *ptr;
|
||||
bool cont;
|
||||
|
||||
std::ios::fmtflags saved_flags;
|
||||
char saved_fill;
|
||||
int saved_precision;
|
||||
|
||||
Format fmt;
|
||||
void process();
|
||||
|
||||
public:
|
||||
Print(std::ostream &stream, const std::string &format);
|
||||
Print(std::ostream &stream, const char *format);
|
||||
~Print();
|
||||
|
||||
int
|
||||
get_number(int data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int
|
||||
get_number(const T& data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
add_arg(const T &data)
|
||||
{
|
||||
if (!cont)
|
||||
process();
|
||||
|
||||
if (fmt.get_width) {
|
||||
fmt.get_width = false;
|
||||
cont = true;
|
||||
fmt.width = get_number(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fmt.get_precision) {
|
||||
fmt.get_precision = false;
|
||||
cont = true;
|
||||
fmt.precision = get_number(data);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (fmt.format) {
|
||||
case Format::character:
|
||||
format_char(stream, data, fmt);
|
||||
break;
|
||||
|
||||
case Format::integer:
|
||||
format_integer(stream, data, fmt);
|
||||
break;
|
||||
|
||||
case Format::floating:
|
||||
format_float(stream, data, fmt);
|
||||
break;
|
||||
|
||||
case Format::string:
|
||||
format_string(stream, data, fmt);
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "<bad format>";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void end_args();
|
||||
};
|
||||
|
||||
} // namespace cp
|
||||
|
||||
typedef VarArgs::List<cp::Print> CPrintfArgsList;
|
||||
|
||||
inline void
|
||||
ccprintf(std::ostream &stream, const char *format, const CPrintfArgsList &args)
|
||||
{
|
||||
cp::Print print(stream, format);
|
||||
args.add_args(print);
|
||||
}
|
||||
|
||||
inline void
|
||||
ccprintf(std::ostream &stream, const char *format, CPRINTF_DECLARATION)
|
||||
{
|
||||
cp::Print print(stream, format);
|
||||
VARARGS_ADDARGS(print);
|
||||
}
|
||||
|
||||
inline void
|
||||
cprintf(const char *format, CPRINTF_DECLARATION)
|
||||
{
|
||||
ccprintf(std::cout, format, VARARGS_ALLARGS);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
csprintf(const char *format, CPRINTF_DECLARATION)
|
||||
{
|
||||
std::stringstream stream;
|
||||
ccprintf(stream, format, VARARGS_ALLARGS);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
/*
|
||||
* functions again with std::string. We have both so we don't waste
|
||||
* time converting const char * to std::string since we don't take
|
||||
* advantage of it.
|
||||
*/
|
||||
inline void
|
||||
ccprintf(std::ostream &stream, const std::string &format,
|
||||
const CPrintfArgsList &args)
|
||||
{
|
||||
ccprintf(stream, format.c_str(), args);
|
||||
}
|
||||
|
||||
inline void
|
||||
ccprintf(std::ostream &stream, const std::string &format, CPRINTF_DECLARATION)
|
||||
{
|
||||
ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
|
||||
}
|
||||
|
||||
inline void
|
||||
cprintf(const std::string &format, CPRINTF_DECLARATION)
|
||||
{
|
||||
ccprintf(std::cout, format.c_str(), VARARGS_ALLARGS);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
csprintf(const std::string &format, CPRINTF_DECLARATION)
|
||||
{
|
||||
std::stringstream stream;
|
||||
ccprintf(stream, format.c_str(), VARARGS_ALLARGS);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
#endif // __CPRINTF_HH__
|
||||
360
simulators/gem5/src/base/cprintf_formats.hh
Normal file
360
simulators/gem5/src/base/cprintf_formats.hh
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_CPRINTF_FORMATS_HH__
|
||||
#define __BASE_CPRINTF_FORMATS_HH__
|
||||
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace cp {
|
||||
|
||||
struct Format
|
||||
{
|
||||
bool alternate_form;
|
||||
bool flush_left;
|
||||
bool print_sign;
|
||||
bool blank_space;
|
||||
bool fill_zero;
|
||||
bool uppercase;
|
||||
enum { dec, hex, oct } base;
|
||||
enum { none, string, integer, character, floating } format;
|
||||
enum { best, fixed, scientific } float_format;
|
||||
int precision;
|
||||
int width;
|
||||
bool get_precision;
|
||||
bool get_width;
|
||||
|
||||
Format() { clear(); }
|
||||
|
||||
void clear()
|
||||
{
|
||||
alternate_form = false;
|
||||
flush_left = false;
|
||||
print_sign = false;
|
||||
blank_space = false;
|
||||
fill_zero = false;
|
||||
uppercase = false;
|
||||
base = dec;
|
||||
format = none;
|
||||
precision = -1;
|
||||
width = 0;
|
||||
get_precision = false;
|
||||
get_width = false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
_format_char(std::ostream &out, const T &data, Format &fmt)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
out << data;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
_format_integer(std::ostream &out, const T &data, Format &fmt)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
switch (fmt.base) {
|
||||
case Format::hex:
|
||||
out.setf(std::ios::hex, std::ios::basefield);
|
||||
break;
|
||||
|
||||
case Format::oct:
|
||||
out.setf(std::ios::oct, std::ios::basefield);
|
||||
break;
|
||||
|
||||
case Format::dec:
|
||||
out.setf(std::ios::dec, std::ios::basefield);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fmt.alternate_form) {
|
||||
if (!fmt.fill_zero)
|
||||
out.setf(std::ios::showbase);
|
||||
else {
|
||||
switch (fmt.base) {
|
||||
case Format::hex:
|
||||
out << "0x";
|
||||
fmt.width -= 2;
|
||||
break;
|
||||
case Format::oct:
|
||||
out << "0";
|
||||
fmt.width -= 1;
|
||||
break;
|
||||
case Format::dec:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fmt.fill_zero)
|
||||
out.fill('0');
|
||||
|
||||
if (fmt.width > 0)
|
||||
out.width(fmt.width);
|
||||
|
||||
if (fmt.flush_left && !fmt.fill_zero)
|
||||
out.setf(std::ios::left);
|
||||
|
||||
if (fmt.print_sign)
|
||||
out.setf(std::ios::showpos);
|
||||
|
||||
if (fmt.uppercase)
|
||||
out.setf(std::ios::uppercase);
|
||||
|
||||
out << data;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
_format_float(std::ostream &out, const T &data, Format &fmt)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
switch (fmt.float_format) {
|
||||
case Format::scientific:
|
||||
if (fmt.precision != -1) {
|
||||
if (fmt.width > 0)
|
||||
out.width(fmt.width);
|
||||
|
||||
if (fmt.precision == 0)
|
||||
fmt.precision = 1;
|
||||
else
|
||||
out.setf(std::ios::scientific);
|
||||
|
||||
out.precision(fmt.precision);
|
||||
} else
|
||||
if (fmt.width > 0)
|
||||
out.width(fmt.width);
|
||||
|
||||
if (fmt.uppercase)
|
||||
out.setf(std::ios::uppercase);
|
||||
break;
|
||||
|
||||
case Format::fixed:
|
||||
if (fmt.precision != -1) {
|
||||
if (fmt.width > 0)
|
||||
out.width(fmt.width);
|
||||
|
||||
out.setf(std::ios::fixed);
|
||||
out.precision(fmt.precision);
|
||||
} else
|
||||
if (fmt.width > 0)
|
||||
out.width(fmt.width);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (fmt.precision != -1)
|
||||
out.precision(fmt.precision);
|
||||
|
||||
if (fmt.width > 0)
|
||||
out.width(fmt.width);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
out << data;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
_format_string(std::ostream &out, const T &data, Format &fmt)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3) || 1
|
||||
if (fmt.width > 0) {
|
||||
std::stringstream foo;
|
||||
foo << data;
|
||||
int flen = foo.str().size();
|
||||
|
||||
if (fmt.width > flen) {
|
||||
char *spaces = new char[fmt.width - flen + 1];
|
||||
memset(spaces, ' ', fmt.width - flen);
|
||||
spaces[fmt.width - flen] = 0;
|
||||
|
||||
if (fmt.flush_left)
|
||||
out << foo.str() << spaces;
|
||||
else
|
||||
out << spaces << foo.str();
|
||||
|
||||
delete [] spaces;
|
||||
} else
|
||||
out << data;
|
||||
} else
|
||||
out << data;
|
||||
#else
|
||||
if (fmt.width > 0)
|
||||
out.width(fmt.width);
|
||||
if (fmt.flush_left)
|
||||
out.setf(std::ios::left);
|
||||
|
||||
out << data;
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The code below controls the actual usage of formats for various types
|
||||
//
|
||||
|
||||
//
|
||||
// character formats
|
||||
//
|
||||
template <typename T>
|
||||
inline void
|
||||
format_char(std::ostream &out, const T &data, Format &fmt)
|
||||
{ out << "<bad arg type for char format>"; }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, char data, Format &fmt)
|
||||
{ _format_char(out, data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, unsigned char data, Format &fmt)
|
||||
{ _format_char(out, data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, signed char data, Format &fmt)
|
||||
{ _format_char(out, data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, short data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, unsigned short data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, int data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, unsigned int data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, long data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, unsigned long data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, long long data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
inline void
|
||||
format_char(std::ostream &out, unsigned long long data, Format &fmt)
|
||||
{ _format_char(out, (char)data, fmt); }
|
||||
|
||||
//
|
||||
// integer formats
|
||||
//
|
||||
template <typename T>
|
||||
inline void
|
||||
format_integer(std::ostream &out, const T &data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, char data, Format &fmt)
|
||||
{ _format_integer(out, (int)data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, unsigned char data, Format &fmt)
|
||||
{ _format_integer(out, (int)data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, signed char data, Format &fmt)
|
||||
{ _format_integer(out, (int)data, fmt); }
|
||||
#if 0
|
||||
inline void
|
||||
format_integer(std::ostream &out, short data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, unsigned short data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, int data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, unsigned int data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, long data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, unsigned long data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, long long data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
inline void
|
||||
format_integer(std::ostream &out, unsigned long long data, Format &fmt)
|
||||
{ _format_integer(out, data, fmt); }
|
||||
#endif
|
||||
|
||||
//
|
||||
// floating point formats
|
||||
//
|
||||
template <typename T>
|
||||
inline void
|
||||
format_float(std::ostream &out, const T &data, Format &fmt)
|
||||
{ out << "<bad arg type for float format>"; }
|
||||
|
||||
inline void
|
||||
format_float(std::ostream &out, float data, Format &fmt)
|
||||
{ _format_float(out, data, fmt); }
|
||||
|
||||
inline void
|
||||
format_float(std::ostream &out, double data, Format &fmt)
|
||||
{ _format_float(out, data, fmt); }
|
||||
|
||||
//
|
||||
// string formats
|
||||
//
|
||||
template <typename T>
|
||||
inline void
|
||||
format_string(std::ostream &out, const T &data, Format &fmt)
|
||||
{ _format_string(out, data, fmt); }
|
||||
|
||||
inline void
|
||||
format_string(std::ostream &out, const std::stringstream &data, Format &fmt)
|
||||
{ _format_string(out, data.str(), fmt); }
|
||||
|
||||
} // namespace cp
|
||||
|
||||
#endif // __CPRINTF_FORMATS_HH__
|
||||
31
simulators/gem5/src/base/date.cc
Normal file
31
simulators/gem5/src/base/date.cc
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
const char *compileDate = __DATE__ " " __TIME__;
|
||||
185
simulators/gem5/src/base/debug.cc
Normal file
185
simulators/gem5/src/base/debug.cc
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <csignal>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/debug.hh"
|
||||
#include "base/misc.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Debug {
|
||||
|
||||
//
|
||||
// This function will cause the process to signal itself with a
|
||||
// SIGTRAP which is ignored if not in gdb, but will cause the debugger
|
||||
// to break if in gdb.
|
||||
//
|
||||
void
|
||||
breakpoint()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
kill(getpid(), SIGTRAP);
|
||||
#else
|
||||
cprintf("Debug::breakpoint suppressed, compiled with NDEBUG\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Flags for debugging purposes. Primarily for trace.hh
|
||||
//
|
||||
typedef std::map<string, Flag *> FlagsMap;
|
||||
int allFlagsVersion = 0;
|
||||
FlagsMap &
|
||||
allFlags()
|
||||
{
|
||||
static FlagsMap flags;
|
||||
return flags;
|
||||
}
|
||||
|
||||
Flag *
|
||||
findFlag(const std::string &name)
|
||||
{
|
||||
FlagsMap::iterator i = allFlags().find(name);
|
||||
if (i == allFlags().end())
|
||||
return NULL;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
Flag::Flag(const char *name, const char *desc)
|
||||
: _name(name), _desc(desc)
|
||||
{
|
||||
pair<FlagsMap::iterator, bool> result =
|
||||
allFlags().insert(make_pair(name, this));
|
||||
|
||||
if (!result.second)
|
||||
panic("Flag %s already defined!", name);
|
||||
|
||||
++allFlagsVersion;
|
||||
}
|
||||
|
||||
Flag::~Flag()
|
||||
{
|
||||
// should find and remove flag.
|
||||
}
|
||||
|
||||
void
|
||||
CompoundFlag::enable()
|
||||
{
|
||||
SimpleFlag::enable();
|
||||
for_each(_kids.begin(), _kids.end(), mem_fun(&Flag::enable));
|
||||
}
|
||||
|
||||
void
|
||||
CompoundFlag::disable()
|
||||
{
|
||||
SimpleFlag::disable();
|
||||
for_each(_kids.begin(), _kids.end(), mem_fun(&Flag::disable));
|
||||
}
|
||||
|
||||
struct AllFlags : public Flag
|
||||
{
|
||||
AllFlags()
|
||||
: Flag("All", "All Flags")
|
||||
{}
|
||||
|
||||
void
|
||||
enable()
|
||||
{
|
||||
FlagsMap::iterator i = allFlags().begin();
|
||||
FlagsMap::iterator end = allFlags().end();
|
||||
for (; i != end; ++i)
|
||||
if (i->second != this)
|
||||
i->second->enable();
|
||||
}
|
||||
|
||||
void
|
||||
disable()
|
||||
{
|
||||
FlagsMap::iterator i = allFlags().begin();
|
||||
FlagsMap::iterator end = allFlags().end();
|
||||
for (; i != end; ++i)
|
||||
if (i->second != this)
|
||||
i->second->disable();
|
||||
}
|
||||
};
|
||||
|
||||
AllFlags theAllFlags;
|
||||
Flag *const All = &theAllFlags;
|
||||
|
||||
bool
|
||||
changeFlag(const char *s, bool value)
|
||||
{
|
||||
Flag *f = findFlag(s);
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
if (value)
|
||||
f->enable();
|
||||
else
|
||||
f->disable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Debug
|
||||
|
||||
// add a set of functions that can easily be invoked from gdb
|
||||
void
|
||||
setDebugFlag(const char *string)
|
||||
{
|
||||
Debug::changeFlag(string, true);
|
||||
}
|
||||
|
||||
void
|
||||
clearDebugFlag(const char *string)
|
||||
{
|
||||
Debug::changeFlag(string, false);
|
||||
}
|
||||
|
||||
void
|
||||
dumpDebugFlags()
|
||||
{
|
||||
using namespace Debug;
|
||||
FlagsMap::iterator i = allFlags().begin();
|
||||
FlagsMap::iterator end = allFlags().end();
|
||||
for (; i != end; ++i) {
|
||||
SimpleFlag *f = dynamic_cast<SimpleFlag *>(i->second);
|
||||
if (f && f->status())
|
||||
cprintf("%s\n", f->name());
|
||||
}
|
||||
}
|
||||
115
simulators/gem5/src/base/debug.hh
Normal file
115
simulators/gem5/src/base/debug.hh
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* Copyright (c) 2010 The Hewlett-Packard Development Company
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_DEBUG_HH__
|
||||
#define __BASE_DEBUG_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Debug {
|
||||
|
||||
void breakpoint();
|
||||
|
||||
class Flag
|
||||
{
|
||||
protected:
|
||||
const char *_name;
|
||||
const char *_desc;
|
||||
std::vector<Flag *> _kids;
|
||||
|
||||
public:
|
||||
Flag(const char *name, const char *desc);
|
||||
virtual ~Flag();
|
||||
|
||||
std::string name() const { return _name; }
|
||||
std::string desc() const { return _desc; }
|
||||
std::vector<Flag *> kids() { return _kids; }
|
||||
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
};
|
||||
|
||||
class SimpleFlag : public Flag
|
||||
{
|
||||
protected:
|
||||
bool _status;
|
||||
|
||||
public:
|
||||
SimpleFlag(const char *name, const char *desc)
|
||||
: Flag(name, desc)
|
||||
{ }
|
||||
|
||||
bool status() const { return _status; }
|
||||
operator bool() const { return _status; }
|
||||
bool operator!() const { return !_status; }
|
||||
|
||||
void enable() { _status = true; }
|
||||
void disable() { _status = false; }
|
||||
};
|
||||
|
||||
class CompoundFlag : public SimpleFlag
|
||||
{
|
||||
protected:
|
||||
void
|
||||
addFlag(Flag &f)
|
||||
{
|
||||
if (&f != NULL)
|
||||
_kids.push_back(&f);
|
||||
}
|
||||
|
||||
public:
|
||||
CompoundFlag(const char *name, const char *desc,
|
||||
Flag &f00 = *(Flag *)0, Flag &f01 = *(Flag *)0,
|
||||
Flag &f02 = *(Flag *)0, Flag &f03 = *(Flag *)0,
|
||||
Flag &f04 = *(Flag *)0, Flag &f05 = *(Flag *)0,
|
||||
Flag &f06 = *(Flag *)0, Flag &f07 = *(Flag *)0,
|
||||
Flag &f08 = *(Flag *)0, Flag &f09 = *(Flag *)0,
|
||||
Flag &f10 = *(Flag *)0, Flag &f11 = *(Flag *)0,
|
||||
Flag &f12 = *(Flag *)0, Flag &f13 = *(Flag *)0,
|
||||
Flag &f14 = *(Flag *)0, Flag &f15 = *(Flag *)0,
|
||||
Flag &f16 = *(Flag *)0, Flag &f17 = *(Flag *)0,
|
||||
Flag &f18 = *(Flag *)0, Flag &f19 = *(Flag *)0)
|
||||
: SimpleFlag(name, desc)
|
||||
{
|
||||
addFlag(f00); addFlag(f01); addFlag(f02); addFlag(f03); addFlag(f04);
|
||||
addFlag(f05); addFlag(f06); addFlag(f07); addFlag(f08); addFlag(f09);
|
||||
addFlag(f10); addFlag(f11); addFlag(f12); addFlag(f13); addFlag(f14);
|
||||
addFlag(f15); addFlag(f16); addFlag(f17); addFlag(f18); addFlag(f19);
|
||||
}
|
||||
|
||||
void enable();
|
||||
void disable();
|
||||
};
|
||||
|
||||
} // namespace Debug
|
||||
|
||||
#endif // __BASE_DEBUG_HH__
|
||||
56
simulators/gem5/src/base/fenv.c
Normal file
56
simulators/gem5/src/base/fenv.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void m5_fesetround(int rm);
|
||||
int m5_fegetround();
|
||||
|
||||
static const int m5_round_ops[] = {FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD};
|
||||
|
||||
void m5_fesetround(int rm)
|
||||
{
|
||||
assert(rm >= 0 && rm < 4);
|
||||
fesetround(m5_round_ops[rm]);
|
||||
}
|
||||
|
||||
int m5_fegetround()
|
||||
{
|
||||
int x;
|
||||
int rm = fegetround();
|
||||
for(x = 0; x < 4; x++)
|
||||
if (m5_round_ops[x] == rm)
|
||||
return x;
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
55
simulators/gem5/src/base/fenv.hh
Normal file
55
simulators/gem5/src/base/fenv.hh
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __BASE_FENV_HH__
|
||||
#define __BASE_FENV_HH__
|
||||
|
||||
#include "config/use_fenv.hh"
|
||||
|
||||
#define M5_FE_DOWNWARD 0
|
||||
#define M5_FE_TONEAREST 1
|
||||
#define M5_FE_TOWARDZERO 2
|
||||
#define M5_FE_UPWARD 3
|
||||
|
||||
#if USE_FENV
|
||||
extern "C" {
|
||||
void m5_fesetround(int rm);
|
||||
int m5_fegetround();
|
||||
}
|
||||
#else
|
||||
|
||||
// Dummy definitions to allow code to compile w/o a real <fenv.h>.
|
||||
inline void m5_fesetround(int rm) { ; }
|
||||
inline int m5_fegetround() {return 0; }
|
||||
|
||||
#endif // USE_FENV
|
||||
|
||||
|
||||
#endif // __BASE_FENV_HH__
|
||||
79
simulators/gem5/src/base/flags.hh
Normal file
79
simulators/gem5/src/base/flags.hh
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2008 The Hewlett-Packard Development Company
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_FLAGS_HH__
|
||||
#define __BASE_FLAGS_HH__
|
||||
|
||||
template <typename T>
|
||||
class Flags
|
||||
{
|
||||
private:
|
||||
T _flags;
|
||||
|
||||
public:
|
||||
typedef T Type;
|
||||
Flags() : _flags(0) {}
|
||||
Flags(Type flags) : _flags(flags) {}
|
||||
|
||||
operator const Type() const { return _flags; }
|
||||
|
||||
template <typename U>
|
||||
const Flags<T> &
|
||||
operator=(const Flags<U> &flags)
|
||||
{
|
||||
_flags = flags._flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Flags<T> &
|
||||
operator=(T flags)
|
||||
{
|
||||
_flags = flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isSet() const { return _flags; }
|
||||
bool isSet(Type flags) const { return (_flags & flags); }
|
||||
bool allSet() const { return !(~_flags); }
|
||||
bool allSet(Type flags) const { return (_flags & flags) == flags; }
|
||||
bool noneSet() const { return _flags == 0; }
|
||||
bool noneSet(Type flags) const { return (_flags & flags) == 0; }
|
||||
void clear() { _flags = 0; }
|
||||
void clear(Type flags) { _flags &= ~flags; }
|
||||
void set(Type flags) { _flags |= flags; }
|
||||
void set(Type f, bool val) { _flags = (_flags & ~f) | (val ? f : 0); }
|
||||
void
|
||||
update(Type flags, Type mask)
|
||||
{
|
||||
_flags = (_flags & ~mask) | (flags & mask);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __BASE_FLAGS_HH__
|
||||
193
simulators/gem5/src/base/hashmap.hh
Normal file
193
simulators/gem5/src/base/hashmap.hh
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2012 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Andreas Hansson
|
||||
*/
|
||||
|
||||
#ifndef __HASHMAP_HH__
|
||||
#define __HASHMAP_HH__
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
// for compilers that deprecate ext/hash_map, i.e. gcc >= 4.3 and
|
||||
// clang, use unordered_map
|
||||
|
||||
// we need to determine what is available, as in the non-c++0x case,
|
||||
// e.g. gcc >= 4.3 and <= 4.5, the containers are in the std::tr1
|
||||
// namespace, and only gcc >= 4.6 (with -std=c++0x) adds the final
|
||||
// container implementation in the std namespace
|
||||
|
||||
#if defined(__clang__)
|
||||
// align with -std=c++0x only for clang >= 3.0 in CCFLAGS and also
|
||||
// check if the header is present as this depends on what clang was
|
||||
// built against, using XCode clang 3.1, for example, the header is
|
||||
// not present without adding -stdlib=libc++
|
||||
#if (__clang_major__ >= 3 && __has_include(<unordered_map>))
|
||||
#define HAVE_STD_UNORDERED_MAP 1
|
||||
#else
|
||||
// we only support clang versions above 2.9 and these all have the tr1
|
||||
// unordered_map
|
||||
#define HAVE_STD_TR1_UNORDERED_MAP 1
|
||||
#endif
|
||||
#else
|
||||
// align with -std=c++0x only for gcc >= 4.6 in CCFLAGS, contrary to
|
||||
// clang we can rely entirely on the compiler version
|
||||
#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
|
||||
#define HAVE_STD_UNORDERED_MAP 1
|
||||
#else
|
||||
#define HAVE_STD_TR1_UNORDERED_MAP 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// set a default value of 0
|
||||
#ifndef HAVE_STD_UNORDERED_MAP
|
||||
#define HAVE_STD_UNORDERED_MAP 0
|
||||
#endif
|
||||
|
||||
// set a default value of 0
|
||||
#ifndef HAVE_STD_TR1_UNORDERED_MAP
|
||||
#define HAVE_STD_TR1_UNORDERED_MAP 0
|
||||
#endif
|
||||
|
||||
// now we are ready to deal with the actual includes based on what is
|
||||
// available
|
||||
#if (HAVE_STD_UNORDERED_MAP || HAVE_STD_TR1_UNORDERED_MAP)
|
||||
|
||||
#define hash_map unordered_map
|
||||
#define hash_multimap unordered_multimap
|
||||
#define hash_set unordered_set
|
||||
#define hash_multiset unordered_multiset
|
||||
|
||||
// these versions also have an existing hash function for strings and
|
||||
// 64-bit integer types
|
||||
#define HAVE_HASH_FUNCTIONS 1
|
||||
|
||||
#if HAVE_STD_UNORDERED_MAP
|
||||
|
||||
// clang or gcc >= 4.6
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
// note that this assumes that -std=c++0x is added to the command line
|
||||
// which is done in the SConstruct CXXFLAGS for gcc >= 4.6 and clang
|
||||
// >= 3.0
|
||||
#define __hash_namespace std
|
||||
#define __hash_namespace_begin namespace std {
|
||||
#define __hash_namespace_end }
|
||||
#else
|
||||
// clang <= 3.0, gcc >= 4.3 and < 4.6
|
||||
#include <tr1/unordered_map>
|
||||
#include <tr1/unordered_set>
|
||||
#define __hash_namespace std::tr1
|
||||
#define __hash_namespace_begin namespace std { namespace tr1 {
|
||||
#define __hash_namespace_end } }
|
||||
#endif
|
||||
#else
|
||||
// gcc < 4.3
|
||||
#include <ext/hash_map>
|
||||
#include <ext/hash_set>
|
||||
#define __hash_namespace __gnu_cxx
|
||||
#define __hash_namespace_begin namespace __gnu_cxx {
|
||||
#define __hash_namespace_end }
|
||||
#endif
|
||||
#else
|
||||
// non GNU compiler
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
#define __hash_namsepace std
|
||||
#define __hash_namespace_begin namespace std {
|
||||
#define __hash_namespace_end }
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
namespace m5 {
|
||||
using ::__hash_namespace::hash_multimap;
|
||||
using ::__hash_namespace::hash_multiset;
|
||||
using ::__hash_namespace::hash_map;
|
||||
using ::__hash_namespace::hash_set;
|
||||
using ::__hash_namespace::hash;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
// Some default Hashing Functions
|
||||
//
|
||||
|
||||
__hash_namespace_begin
|
||||
|
||||
// if the hash functions for 64-bit integer types and strings are not
|
||||
// already available, then declare them here
|
||||
#if !defined(HAVE_HASH_FUNCTIONS)
|
||||
|
||||
#if !defined(__LP64__) && !defined(__alpha__) && !defined(__SUNPRO_CC)
|
||||
template<>
|
||||
struct hash<uint64_t> {
|
||||
size_t operator()(uint64_t r) const {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<int64_t> {
|
||||
size_t operator()(int64_t r) const {
|
||||
return r;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct hash<std::string> {
|
||||
size_t operator()(const std::string &s) const {
|
||||
return(__stl_hash_string(s.c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<std::pair<std::string, uint64_t> > {
|
||||
size_t operator() (std::pair<std::string, uint64_t> r) const {
|
||||
return (__stl_hash_string(r.first.c_str())) ^ r.second;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
__hash_namespace_end
|
||||
|
||||
#endif // __HASHMAP_HH__
|
||||
118
simulators/gem5/src/base/hostinfo.cc
Normal file
118
simulators/gem5/src/base/hostinfo.cc
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/shared_region.h>
|
||||
#include <mach/task.h>
|
||||
#endif
|
||||
|
||||
#include <cctype>
|
||||
#include <cerrno>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string
|
||||
__get_hostname()
|
||||
{
|
||||
char host[256];
|
||||
if (gethostname(host, sizeof host) == -1)
|
||||
warn("could not get host name!");
|
||||
return host;
|
||||
}
|
||||
|
||||
string &
|
||||
hostname()
|
||||
{
|
||||
static string hostname = __get_hostname();
|
||||
return hostname;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
procInfo(const char *filename, const char *target)
|
||||
{
|
||||
int done = 0;
|
||||
char line[80];
|
||||
char format[80];
|
||||
long usage;
|
||||
|
||||
FILE *fp = fopen(filename, "r");
|
||||
|
||||
while (fp && !feof(fp) && !done) {
|
||||
if (fgets(line, 80, fp)) {
|
||||
if (strncmp(line, target, strlen(target)) == 0) {
|
||||
snprintf(format, sizeof(format), "%s %%ld", target);
|
||||
sscanf(line, format, &usage);
|
||||
|
||||
fclose(fp);
|
||||
return usage ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
memUsage()
|
||||
{
|
||||
// For the Mach-based Darwin kernel, use the task_info of the self task
|
||||
#ifdef __APPLE__
|
||||
struct task_basic_info t_info;
|
||||
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
|
||||
|
||||
if (KERN_SUCCESS != task_info(mach_task_self(),
|
||||
TASK_BASIC_INFO, (task_info_t)&t_info,
|
||||
&t_info_count)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Mimic Darwin's implementation of top and subtract
|
||||
// SHARED_REGION_SIZE from the tasks virtual size to account for the
|
||||
// shared memory submap that is incorporated into every process.
|
||||
return (t_info.virtual_size - SHARED_REGION_SIZE) / 1024;
|
||||
#else
|
||||
// Linux implementation
|
||||
return procInfo("/proc/self/status", "VmSize:");
|
||||
#endif
|
||||
}
|
||||
49
simulators/gem5/src/base/hostinfo.hh
Normal file
49
simulators/gem5/src/base/hostinfo.hh
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __HOSTINFO_HH__
|
||||
#define __HOSTINFO_HH__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
std::string &hostname();
|
||||
|
||||
uint64_t procInfo(const char *filename, const char *target);
|
||||
|
||||
/**
|
||||
* Determine the simulator process' total virtual memory usage.
|
||||
*
|
||||
* @return virtual memory usage in kilobytes
|
||||
*/
|
||||
uint64_t memUsage();
|
||||
|
||||
#endif // __HOSTINFO_HH__
|
||||
301
simulators/gem5/src/base/inet.cc
Normal file
301
simulators/gem5/src/base/inet.cc
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||
* Copyright (c) 2010 Advanced Micro Devices, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Gabe Black
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/inet.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
using namespace std;
|
||||
namespace Net {
|
||||
|
||||
EthAddr::EthAddr()
|
||||
{
|
||||
memset(data, 0, ETH_ADDR_LEN);
|
||||
}
|
||||
|
||||
EthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN])
|
||||
{
|
||||
*data = *ea;
|
||||
}
|
||||
|
||||
EthAddr::EthAddr(const eth_addr &ea)
|
||||
{
|
||||
*data = *ea.data;
|
||||
}
|
||||
|
||||
EthAddr::EthAddr(const std::string &addr)
|
||||
{
|
||||
parse(addr);
|
||||
}
|
||||
|
||||
const EthAddr &
|
||||
EthAddr::operator=(const eth_addr &ea)
|
||||
{
|
||||
*data = *ea.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const EthAddr &
|
||||
EthAddr::operator=(const std::string &addr)
|
||||
{
|
||||
parse(addr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
EthAddr::parse(const std::string &addr)
|
||||
{
|
||||
// the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise
|
||||
// the sscanf function won't work.
|
||||
int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1];
|
||||
if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1],
|
||||
&bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) {
|
||||
memset(data, 0xff, ETH_ADDR_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ETH_ADDR_LEN; ++i) {
|
||||
if (bytes[i] & ~0xff) {
|
||||
memset(data, 0xff, ETH_ADDR_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
data[i] = bytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
EthAddr::string() const
|
||||
{
|
||||
stringstream stream;
|
||||
stream << *this;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const EthAddr &left, const EthAddr &right)
|
||||
{
|
||||
return memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN);
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &stream, const EthAddr &ea)
|
||||
{
|
||||
const uint8_t *a = ea.addr();
|
||||
ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]);
|
||||
return stream;
|
||||
}
|
||||
|
||||
string
|
||||
IpAddress::string() const
|
||||
{
|
||||
stringstream stream;
|
||||
stream << *this;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const IpAddress &left, const IpAddress &right)
|
||||
{
|
||||
return left.ip() == right.ip();
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &stream, const IpAddress &ia)
|
||||
{
|
||||
uint32_t ip = ia.ip();
|
||||
ccprintf(stream, "%x.%x.%x.%x",
|
||||
(uint8_t)(ip >> 24), (uint8_t)(ip >> 16),
|
||||
(uint8_t)(ip >> 8), (uint8_t)(ip >> 0));
|
||||
return stream;
|
||||
}
|
||||
|
||||
string
|
||||
IpNetmask::string() const
|
||||
{
|
||||
stringstream stream;
|
||||
stream << *this;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const IpNetmask &left, const IpNetmask &right)
|
||||
{
|
||||
return (left.ip() == right.ip()) &&
|
||||
(left.netmask() == right.netmask());
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &stream, const IpNetmask &in)
|
||||
{
|
||||
ccprintf(stream, "%s/%d", (const IpAddress &)in, in.netmask());
|
||||
return stream;
|
||||
}
|
||||
|
||||
string
|
||||
IpWithPort::string() const
|
||||
{
|
||||
stringstream stream;
|
||||
stream << *this;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const IpWithPort &left, const IpWithPort &right)
|
||||
{
|
||||
return (left.ip() == right.ip()) && (left.port() == right.port());
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &stream, const IpWithPort &iwp)
|
||||
{
|
||||
ccprintf(stream, "%s:%d", (const IpAddress &)iwp, iwp.port());
|
||||
return stream;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
cksum(const IpPtr &ptr)
|
||||
{
|
||||
int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0);
|
||||
return ip_cksum_carry(sum);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
__tu_cksum(const IpPtr &ip)
|
||||
{
|
||||
int tcplen = ip->len() - ip->hlen();
|
||||
int sum = ip_cksum_add(ip->payload(), tcplen, 0);
|
||||
sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination
|
||||
sum += htons(ip->ip_p + tcplen);
|
||||
return ip_cksum_carry(sum);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
cksum(const TcpPtr &tcp)
|
||||
{ return __tu_cksum(IpPtr(tcp.packet())); }
|
||||
|
||||
uint16_t
|
||||
cksum(const UdpPtr &udp)
|
||||
{ return __tu_cksum(IpPtr(udp.packet())); }
|
||||
|
||||
bool
|
||||
IpHdr::options(vector<const IpOpt *> &vec) const
|
||||
{
|
||||
vec.clear();
|
||||
|
||||
const uint8_t *data = bytes() + sizeof(struct ip_hdr);
|
||||
int all = hlen() - sizeof(struct ip_hdr);
|
||||
while (all > 0) {
|
||||
const IpOpt *opt = (const IpOpt *)data;
|
||||
int len = opt->len();
|
||||
if (all < len)
|
||||
return false;
|
||||
|
||||
vec.push_back(opt);
|
||||
all -= len;
|
||||
data += len;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TcpHdr::options(vector<const TcpOpt *> &vec) const
|
||||
{
|
||||
vec.clear();
|
||||
|
||||
const uint8_t *data = bytes() + sizeof(struct tcp_hdr);
|
||||
int all = off() - sizeof(struct tcp_hdr);
|
||||
while (all > 0) {
|
||||
const TcpOpt *opt = (const TcpOpt *)data;
|
||||
int len = opt->len();
|
||||
if (all < len)
|
||||
return false;
|
||||
|
||||
vec.push_back(opt);
|
||||
all -= len;
|
||||
data += len;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TcpOpt::sack(vector<SackRange> &vec) const
|
||||
{
|
||||
vec.clear();
|
||||
|
||||
const uint8_t *data = bytes() + sizeof(struct tcp_hdr);
|
||||
int all = len() - offsetof(tcp_opt, opt_data.sack);
|
||||
while (all > 0) {
|
||||
const uint16_t *sack = (const uint16_t *)data;
|
||||
int len = sizeof(uint16_t) * 2;
|
||||
if (all < len) {
|
||||
vec.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
vec.push_back(RangeIn(ntohs(sack[0]), ntohs(sack[1])));
|
||||
all -= len;
|
||||
data += len;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
hsplit(const EthPacketPtr &ptr)
|
||||
{
|
||||
int split_point = 0;
|
||||
|
||||
IpPtr ip(ptr);
|
||||
if (ip) {
|
||||
split_point = ip.pstart();
|
||||
|
||||
TcpPtr tcp(ip);
|
||||
if (tcp)
|
||||
split_point = tcp.pstart();
|
||||
|
||||
UdpPtr udp(ip);
|
||||
if (udp)
|
||||
split_point = udp.pstart();
|
||||
}
|
||||
return split_point;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Net
|
||||
476
simulators/gem5/src/base/inet.hh
Normal file
476
simulators/gem5/src/base/inet.hh
Normal file
@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||
* Copyright (c) 2010 Advanced Micro Devices, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
* Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __BASE_INET_HH__
|
||||
#define __BASE_INET_HH__
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/range.hh"
|
||||
#include "base/types.hh"
|
||||
#include "dev/etherpkt.hh"
|
||||
#include "dnet/os.h"
|
||||
#include "dnet/eth.h"
|
||||
#include "dnet/ip.h"
|
||||
#include "dnet/ip6.h"
|
||||
#include "dnet/addr.h"
|
||||
#include "dnet/arp.h"
|
||||
#include "dnet/icmp.h"
|
||||
#include "dnet/tcp.h"
|
||||
#include "dnet/udp.h"
|
||||
#include "dnet/intf.h"
|
||||
#include "dnet/route.h"
|
||||
#include "dnet/fw.h"
|
||||
#include "dnet/blob.h"
|
||||
#include "dnet/rand.h"
|
||||
|
||||
namespace Net {
|
||||
|
||||
/*
|
||||
* Ethernet Stuff
|
||||
*/
|
||||
struct EthAddr : protected eth_addr
|
||||
{
|
||||
protected:
|
||||
void parse(const std::string &addr);
|
||||
|
||||
public:
|
||||
EthAddr();
|
||||
EthAddr(const uint8_t ea[ETH_ADDR_LEN]);
|
||||
EthAddr(const eth_addr &ea);
|
||||
EthAddr(const std::string &addr);
|
||||
const EthAddr &operator=(const eth_addr &ea);
|
||||
const EthAddr &operator=(const std::string &addr);
|
||||
|
||||
int size() const { return sizeof(eth_addr); }
|
||||
|
||||
const uint8_t *bytes() const { return &data[0]; }
|
||||
uint8_t *bytes() { return &data[0]; }
|
||||
|
||||
const uint8_t *addr() const { return &data[0]; }
|
||||
bool unicast() const { return data[0] == 0x00; }
|
||||
bool multicast() const { return data[0] == 0x01; }
|
||||
bool broadcast() const { return data[0] == 0xff; }
|
||||
std::string string() const;
|
||||
|
||||
operator uint64_t() const
|
||||
{
|
||||
uint64_t reg = 0;
|
||||
reg |= ((uint64_t)data[0]) << 40;
|
||||
reg |= ((uint64_t)data[1]) << 32;
|
||||
reg |= ((uint64_t)data[2]) << 24;
|
||||
reg |= ((uint64_t)data[3]) << 16;
|
||||
reg |= ((uint64_t)data[4]) << 8;
|
||||
reg |= ((uint64_t)data[5]) << 0;
|
||||
return reg;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const EthAddr &ea);
|
||||
bool operator==(const EthAddr &left, const EthAddr &right);
|
||||
|
||||
struct EthHdr : public eth_hdr
|
||||
{
|
||||
uint16_t type() const { return ntohs(eth_type); }
|
||||
const EthAddr &src() const { return *(EthAddr *)ð_src; }
|
||||
const EthAddr &dst() const { return *(EthAddr *)ð_dst; }
|
||||
|
||||
int size() const { return sizeof(eth_hdr); }
|
||||
|
||||
const uint8_t *bytes() const { return (const uint8_t *)this; }
|
||||
const uint8_t *payload() const { return bytes() + size(); }
|
||||
uint8_t *bytes() { return (uint8_t *)this; }
|
||||
uint8_t *payload() { return bytes() + size(); }
|
||||
};
|
||||
|
||||
class EthPtr
|
||||
{
|
||||
protected:
|
||||
friend class IpPtr;
|
||||
EthPacketPtr p;
|
||||
|
||||
public:
|
||||
EthPtr() {}
|
||||
EthPtr(const EthPacketPtr &ptr) : p(ptr) { }
|
||||
|
||||
EthHdr *operator->() { return (EthHdr *)p->data; }
|
||||
EthHdr &operator*() { return *(EthHdr *)p->data; }
|
||||
operator EthHdr *() { return (EthHdr *)p->data; }
|
||||
|
||||
const EthHdr *operator->() const { return (const EthHdr *)p->data; }
|
||||
const EthHdr &operator*() const { return *(const EthHdr *)p->data; }
|
||||
operator const EthHdr *() const { return (const EthHdr *)p->data; }
|
||||
|
||||
const EthPtr &operator=(const EthPacketPtr &ptr) { p = ptr; return *this; }
|
||||
|
||||
const EthPacketPtr packet() const { return p; }
|
||||
EthPacketPtr packet() { return p; }
|
||||
bool operator!() const { return !p; }
|
||||
operator bool() const { return p; }
|
||||
int off() const { return 0; }
|
||||
int pstart() const { return off() + ((const EthHdr*)p->data)->size(); }
|
||||
};
|
||||
|
||||
/*
|
||||
* IP Stuff
|
||||
*/
|
||||
struct IpAddress
|
||||
{
|
||||
protected:
|
||||
uint32_t _ip;
|
||||
|
||||
public:
|
||||
IpAddress() : _ip(0)
|
||||
{}
|
||||
IpAddress(const uint32_t __ip) : _ip(__ip)
|
||||
{}
|
||||
|
||||
uint32_t ip() const { return _ip; }
|
||||
|
||||
std::string string() const;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const IpAddress &ia);
|
||||
bool operator==(const IpAddress &left, const IpAddress &right);
|
||||
|
||||
struct IpNetmask : public IpAddress
|
||||
{
|
||||
protected:
|
||||
uint8_t _netmask;
|
||||
|
||||
public:
|
||||
IpNetmask() : IpAddress(), _netmask(0)
|
||||
{}
|
||||
IpNetmask(const uint32_t __ip, const uint8_t __netmask) :
|
||||
IpAddress(__ip), _netmask(__netmask)
|
||||
{}
|
||||
|
||||
uint8_t netmask() const { return _netmask; }
|
||||
|
||||
std::string string() const;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const IpNetmask &in);
|
||||
bool operator==(const IpNetmask &left, const IpNetmask &right);
|
||||
|
||||
struct IpWithPort : public IpAddress
|
||||
{
|
||||
protected:
|
||||
uint16_t _port;
|
||||
|
||||
public:
|
||||
IpWithPort() : IpAddress(), _port(0)
|
||||
{}
|
||||
IpWithPort(const uint32_t __ip, const uint16_t __port) :
|
||||
IpAddress(__ip), _port(__port)
|
||||
{}
|
||||
|
||||
uint8_t port() const { return _port; }
|
||||
|
||||
std::string string() const;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const IpWithPort &iwp);
|
||||
bool operator==(const IpWithPort &left, const IpWithPort &right);
|
||||
|
||||
struct IpOpt;
|
||||
struct IpHdr : public ip_hdr
|
||||
{
|
||||
uint8_t version() const { return ip_v; }
|
||||
uint8_t hlen() const { return ip_hl * 4; }
|
||||
uint8_t tos() const { return ip_tos; }
|
||||
uint16_t len() const { return ntohs(ip_len); }
|
||||
uint16_t id() const { return ntohs(ip_id); }
|
||||
uint16_t frag_flags() const { return ntohs(ip_off) >> 13; }
|
||||
uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; }
|
||||
uint8_t ttl() const { return ip_ttl; }
|
||||
uint8_t proto() const { return ip_p; }
|
||||
uint16_t sum() const { return ip_sum; }
|
||||
uint32_t src() const { return ntohl(ip_src); }
|
||||
uint32_t dst() const { return ntohl(ip_dst); }
|
||||
|
||||
void sum(uint16_t sum) { ip_sum = sum; }
|
||||
void id(uint16_t _id) { ip_id = htons(_id); }
|
||||
void len(uint16_t _len) { ip_len = htons(_len); }
|
||||
|
||||
|
||||
bool options(std::vector<const IpOpt *> &vec) const;
|
||||
|
||||
int size() const { return hlen(); }
|
||||
const uint8_t *bytes() const { return (const uint8_t *)this; }
|
||||
const uint8_t *payload() const { return bytes() + size(); }
|
||||
uint8_t *bytes() { return (uint8_t *)this; }
|
||||
uint8_t *payload() { return bytes() + size(); }
|
||||
};
|
||||
|
||||
class IpPtr
|
||||
{
|
||||
protected:
|
||||
friend class TcpPtr;
|
||||
friend class UdpPtr;
|
||||
EthPacketPtr p;
|
||||
|
||||
void set(const EthPacketPtr &ptr)
|
||||
{
|
||||
p = 0;
|
||||
|
||||
if (ptr) {
|
||||
EthHdr *eth = (EthHdr *)ptr->data;
|
||||
if (eth->type() == ETH_TYPE_IP)
|
||||
p = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
IpPtr() : p(0) {}
|
||||
IpPtr(const EthPacketPtr &ptr) : p(0) { set(ptr); }
|
||||
IpPtr(const EthPtr &ptr) : p(0) { set(ptr.p); }
|
||||
IpPtr(const IpPtr &ptr) : p(ptr.p) { }
|
||||
|
||||
IpHdr *get() { return (IpHdr *)(p->data + sizeof(eth_hdr)); }
|
||||
IpHdr *operator->() { return get(); }
|
||||
IpHdr &operator*() { return *get(); }
|
||||
|
||||
const IpHdr *get() const
|
||||
{ return (const IpHdr *)(p->data + sizeof(eth_hdr)); }
|
||||
const IpHdr *operator->() const { return get(); }
|
||||
const IpHdr &operator*() const { return *get(); }
|
||||
|
||||
const IpPtr &operator=(const EthPacketPtr &ptr) { set(ptr); return *this; }
|
||||
const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; }
|
||||
const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; }
|
||||
|
||||
const EthPacketPtr packet() const { return p; }
|
||||
EthPacketPtr packet() { return p; }
|
||||
bool operator!() const { return !p; }
|
||||
operator bool() const { return p; }
|
||||
int off() const { return sizeof(eth_hdr); }
|
||||
int pstart() const { return off() + get()->size(); }
|
||||
};
|
||||
|
||||
uint16_t cksum(const IpPtr &ptr);
|
||||
|
||||
struct IpOpt : public ip_opt
|
||||
{
|
||||
uint8_t type() const { return opt_type; }
|
||||
uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); }
|
||||
uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); }
|
||||
uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); }
|
||||
uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; }
|
||||
|
||||
bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); }
|
||||
bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); }
|
||||
bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); }
|
||||
|
||||
const uint8_t *data() const { return opt_data.data8; }
|
||||
void sec(ip_opt_data_sec &sec) const;
|
||||
void lsrr(ip_opt_data_rr &rr) const;
|
||||
void ssrr(ip_opt_data_rr &rr) const;
|
||||
void ts(ip_opt_data_ts &ts) const;
|
||||
uint16_t satid() const { return ntohs(opt_data.satid); }
|
||||
uint16_t mtup() const { return ntohs(opt_data.mtu); }
|
||||
uint16_t mtur() const { return ntohs(opt_data.mtu); }
|
||||
void tr(ip_opt_data_tr &tr) const;
|
||||
const uint32_t *addext() const { return &opt_data.addext[0]; }
|
||||
uint16_t rtralt() const { return ntohs(opt_data.rtralt); }
|
||||
void sdb(std::vector<uint32_t> &vec) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* TCP Stuff
|
||||
*/
|
||||
struct TcpOpt;
|
||||
struct TcpHdr : public tcp_hdr
|
||||
{
|
||||
uint16_t sport() const { return ntohs(th_sport); }
|
||||
uint16_t dport() const { return ntohs(th_dport); }
|
||||
uint32_t seq() const { return ntohl(th_seq); }
|
||||
uint32_t ack() const { return ntohl(th_ack); }
|
||||
uint8_t off() const { return th_off; }
|
||||
uint8_t flags() const { return th_flags & 0x3f; }
|
||||
uint16_t win() const { return ntohs(th_win); }
|
||||
uint16_t sum() const { return th_sum; }
|
||||
uint16_t urp() const { return ntohs(th_urp); }
|
||||
|
||||
void sum(uint16_t sum) { th_sum = sum; }
|
||||
void seq(uint32_t _seq) { th_seq = htonl(_seq); }
|
||||
void flags(uint8_t _flags) { th_flags = _flags; }
|
||||
|
||||
bool options(std::vector<const TcpOpt *> &vec) const;
|
||||
|
||||
int size() const { return off(); }
|
||||
const uint8_t *bytes() const { return (const uint8_t *)this; }
|
||||
const uint8_t *payload() const { return bytes() + size(); }
|
||||
uint8_t *bytes() { return (uint8_t *)this; }
|
||||
uint8_t *payload() { return bytes() + size(); }
|
||||
};
|
||||
|
||||
class TcpPtr
|
||||
{
|
||||
protected:
|
||||
EthPacketPtr p;
|
||||
int _off;
|
||||
|
||||
void set(const EthPacketPtr &ptr, int offset) { p = ptr; _off = offset; }
|
||||
void set(const IpPtr &ptr)
|
||||
{
|
||||
if (ptr && ptr->proto() == IP_PROTO_TCP)
|
||||
set(ptr.p, sizeof(eth_hdr) + ptr->hlen());
|
||||
else
|
||||
set(0, 0);
|
||||
}
|
||||
|
||||
public:
|
||||
TcpPtr() : p(0), _off(0) {}
|
||||
TcpPtr(const IpPtr &ptr) : p(0), _off(0) { set(ptr); }
|
||||
TcpPtr(const TcpPtr &ptr) : p(ptr.p), _off(ptr._off) {}
|
||||
|
||||
TcpHdr *get() { return (TcpHdr *)(p->data + _off); }
|
||||
TcpHdr *operator->() { return get(); }
|
||||
TcpHdr &operator*() { return *get(); }
|
||||
|
||||
const TcpHdr *get() const { return (const TcpHdr *)(p->data + _off); }
|
||||
const TcpHdr *operator->() const { return get(); }
|
||||
const TcpHdr &operator*() const { return *get(); }
|
||||
|
||||
const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; }
|
||||
const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t._off); return *this; }
|
||||
|
||||
const EthPacketPtr packet() const { return p; }
|
||||
EthPacketPtr packet() { return p; }
|
||||
bool operator!() const { return !p; }
|
||||
operator bool() const { return p; }
|
||||
int off() const { return _off; }
|
||||
int pstart() const { return off() + get()->size(); }
|
||||
};
|
||||
|
||||
uint16_t cksum(const TcpPtr &ptr);
|
||||
|
||||
typedef Range<uint16_t> SackRange;
|
||||
|
||||
struct TcpOpt : public tcp_opt
|
||||
{
|
||||
uint8_t type() const { return opt_type; }
|
||||
uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; }
|
||||
|
||||
bool isopt(int opt) const { return type() == opt; }
|
||||
|
||||
const uint8_t *data() const { return opt_data.data8; }
|
||||
|
||||
uint16_t mss() const { return ntohs(opt_data.mss); }
|
||||
uint8_t wscale() const { return opt_data.wscale; }
|
||||
bool sack(std::vector<SackRange> &vec) const;
|
||||
uint32_t echo() const { return ntohl(opt_data.echo); }
|
||||
uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); }
|
||||
uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); }
|
||||
uint32_t cc() const { return ntohl(opt_data.cc); }
|
||||
uint8_t cksum() const{ return opt_data.cksum; }
|
||||
const uint8_t *md5() const { return opt_data.md5; }
|
||||
|
||||
int size() const { return len(); }
|
||||
const uint8_t *bytes() const { return (const uint8_t *)this; }
|
||||
const uint8_t *payload() const { return bytes() + size(); }
|
||||
uint8_t *bytes() { return (uint8_t *)this; }
|
||||
uint8_t *payload() { return bytes() + size(); }
|
||||
};
|
||||
|
||||
/*
|
||||
* UDP Stuff
|
||||
*/
|
||||
struct UdpHdr : public udp_hdr
|
||||
{
|
||||
uint16_t sport() const { return ntohs(uh_sport); }
|
||||
uint16_t dport() const { return ntohs(uh_dport); }
|
||||
uint16_t len() const { return ntohs(uh_ulen); }
|
||||
uint16_t sum() const { return uh_sum; }
|
||||
|
||||
void sum(uint16_t sum) { uh_sum = sum; }
|
||||
void len(uint16_t _len) { uh_ulen = htons(_len); }
|
||||
|
||||
int size() const { return sizeof(udp_hdr); }
|
||||
const uint8_t *bytes() const { return (const uint8_t *)this; }
|
||||
const uint8_t *payload() const { return bytes() + size(); }
|
||||
uint8_t *bytes() { return (uint8_t *)this; }
|
||||
uint8_t *payload() { return bytes() + size(); }
|
||||
};
|
||||
|
||||
class UdpPtr
|
||||
{
|
||||
protected:
|
||||
EthPacketPtr p;
|
||||
int _off;
|
||||
|
||||
void set(const EthPacketPtr &ptr, int offset) { p = ptr; _off = offset; }
|
||||
void set(const IpPtr &ptr)
|
||||
{
|
||||
if (ptr && ptr->proto() == IP_PROTO_UDP)
|
||||
set(ptr.p, sizeof(eth_hdr) + ptr->hlen());
|
||||
else
|
||||
set(0, 0);
|
||||
}
|
||||
|
||||
public:
|
||||
UdpPtr() : p(0), _off(0) {}
|
||||
UdpPtr(const IpPtr &ptr) : p(0), _off(0) { set(ptr); }
|
||||
UdpPtr(const UdpPtr &ptr) : p(ptr.p), _off(ptr._off) {}
|
||||
|
||||
UdpHdr *get() { return (UdpHdr *)(p->data + _off); }
|
||||
UdpHdr *operator->() { return get(); }
|
||||
UdpHdr &operator*() { return *get(); }
|
||||
|
||||
const UdpHdr *get() const { return (const UdpHdr *)(p->data + _off); }
|
||||
const UdpHdr *operator->() const { return get(); }
|
||||
const UdpHdr &operator*() const { return *get(); }
|
||||
|
||||
const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; }
|
||||
const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t._off); return *this; }
|
||||
|
||||
const EthPacketPtr packet() const { return p; }
|
||||
EthPacketPtr packet() { return p; }
|
||||
bool operator!() const { return !p; }
|
||||
operator bool() const { return p; }
|
||||
int off() const { return _off; }
|
||||
int pstart() const { return off() + get()->size(); }
|
||||
};
|
||||
|
||||
uint16_t cksum(const UdpPtr &ptr);
|
||||
|
||||
int hsplit(const EthPacketPtr &ptr);
|
||||
|
||||
} // namespace Net
|
||||
|
||||
#endif // __BASE_INET_HH__
|
||||
328
simulators/gem5/src/base/inifile.cc
Normal file
328
simulators/gem5/src/base/inifile.cc
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/inifile.hh"
|
||||
#include "base/str.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
IniFile::IniFile()
|
||||
{}
|
||||
|
||||
IniFile::~IniFile()
|
||||
{
|
||||
SectionTable::iterator i = table.begin();
|
||||
SectionTable::iterator end = table.end();
|
||||
|
||||
while (i != end) {
|
||||
delete (*i).second;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IniFile::load(const string &file)
|
||||
{
|
||||
ifstream f(file.c_str());
|
||||
|
||||
if (!f.is_open())
|
||||
return false;
|
||||
|
||||
return load(f);
|
||||
}
|
||||
|
||||
|
||||
const string &
|
||||
IniFile::Entry::getValue() const
|
||||
{
|
||||
referenced = true;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IniFile::Section::addEntry(const std::string &entryName,
|
||||
const std::string &value,
|
||||
bool append)
|
||||
{
|
||||
EntryTable::iterator ei = table.find(entryName);
|
||||
|
||||
if (ei == table.end()) {
|
||||
// new entry
|
||||
table[entryName] = new Entry(value);
|
||||
}
|
||||
else if (append) {
|
||||
// append new reult to old entry
|
||||
ei->second->appendValue(value);
|
||||
}
|
||||
else {
|
||||
// override old entry
|
||||
ei->second->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IniFile::Section::add(const std::string &assignment)
|
||||
{
|
||||
string::size_type offset = assignment.find('=');
|
||||
if (offset == string::npos) {
|
||||
// no '=' found
|
||||
cerr << "Can't parse .ini line " << assignment << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if "+=" rather than just "=" then append value
|
||||
bool append = (assignment[offset-1] == '+');
|
||||
|
||||
string entryName = assignment.substr(0, append ? offset-1 : offset);
|
||||
string value = assignment.substr(offset + 1);
|
||||
|
||||
eat_white(entryName);
|
||||
eat_white(value);
|
||||
|
||||
addEntry(entryName, value, append);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IniFile::Entry *
|
||||
IniFile::Section::findEntry(const std::string &entryName) const
|
||||
{
|
||||
referenced = true;
|
||||
|
||||
EntryTable::const_iterator ei = table.find(entryName);
|
||||
|
||||
return (ei == table.end()) ? NULL : ei->second;
|
||||
}
|
||||
|
||||
|
||||
IniFile::Section *
|
||||
IniFile::addSection(const string §ionName)
|
||||
{
|
||||
SectionTable::iterator i = table.find(sectionName);
|
||||
|
||||
if (i != table.end()) {
|
||||
return i->second;
|
||||
}
|
||||
else {
|
||||
// new entry
|
||||
Section *sec = new Section();
|
||||
table[sectionName] = sec;
|
||||
return sec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IniFile::Section *
|
||||
IniFile::findSection(const string §ionName) const
|
||||
{
|
||||
SectionTable::const_iterator i = table.find(sectionName);
|
||||
|
||||
return (i == table.end()) ? NULL : i->second;
|
||||
}
|
||||
|
||||
|
||||
// Take string of the form "<section>:<parameter>=<value>" and add to
|
||||
// database. Return true if successful, false if parse error.
|
||||
bool
|
||||
IniFile::add(const string &str)
|
||||
{
|
||||
// find ':'
|
||||
string::size_type offset = str.find(':');
|
||||
if (offset == string::npos) // no ':' found
|
||||
return false;
|
||||
|
||||
string sectionName = str.substr(0, offset);
|
||||
string rest = str.substr(offset + 1);
|
||||
|
||||
eat_white(sectionName);
|
||||
Section *s = addSection(sectionName);
|
||||
|
||||
return s->add(rest);
|
||||
}
|
||||
|
||||
bool
|
||||
IniFile::load(istream &f)
|
||||
{
|
||||
Section *section = NULL;
|
||||
|
||||
while (!f.eof()) {
|
||||
f >> ws; // Eat whitespace
|
||||
if (f.eof()) {
|
||||
break;
|
||||
}
|
||||
|
||||
string line;
|
||||
getline(f, line);
|
||||
if (line.size() == 0)
|
||||
continue;
|
||||
|
||||
eat_end_white(line);
|
||||
int last = line.size() - 1;
|
||||
|
||||
if (line[0] == '[' && line[last] == ']') {
|
||||
string sectionName = line.substr(1, last - 1);
|
||||
eat_white(sectionName);
|
||||
section = addSection(sectionName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (section == NULL)
|
||||
continue;
|
||||
|
||||
if (!section->add(line))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IniFile::find(const string §ionName, const string &entryName,
|
||||
string &value) const
|
||||
{
|
||||
Section *section = findSection(sectionName);
|
||||
if (section == NULL)
|
||||
return false;
|
||||
|
||||
Entry *entry = section->findEntry(entryName);
|
||||
if (entry == NULL)
|
||||
return false;
|
||||
|
||||
value = entry->getValue();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IniFile::sectionExists(const string §ionName) const
|
||||
{
|
||||
return findSection(sectionName) != NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IniFile::Section::printUnreferenced(const string §ionName)
|
||||
{
|
||||
bool unref = false;
|
||||
bool search_unref_entries = false;
|
||||
vector<string> unref_ok_entries;
|
||||
|
||||
Entry *entry = findEntry("unref_entries_ok");
|
||||
if (entry != NULL) {
|
||||
tokenize(unref_ok_entries, entry->getValue(), ' ');
|
||||
if (unref_ok_entries.size()) {
|
||||
search_unref_entries = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (EntryTable::iterator ei = table.begin();
|
||||
ei != table.end(); ++ei) {
|
||||
const string &entryName = ei->first;
|
||||
Entry *entry = ei->second;
|
||||
|
||||
if (entryName == "unref_section_ok" ||
|
||||
entryName == "unref_entries_ok")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry->isReferenced()) {
|
||||
if (search_unref_entries &&
|
||||
(std::find(unref_ok_entries.begin(), unref_ok_entries.end(),
|
||||
entryName) != unref_ok_entries.end()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << "Parameter " << sectionName << ":" << entryName
|
||||
<< " not referenced." << endl;
|
||||
unref = true;
|
||||
}
|
||||
}
|
||||
|
||||
return unref;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IniFile::printUnreferenced()
|
||||
{
|
||||
bool unref = false;
|
||||
|
||||
for (SectionTable::iterator i = table.begin();
|
||||
i != table.end(); ++i) {
|
||||
const string §ionName = i->first;
|
||||
Section *section = i->second;
|
||||
|
||||
if (!section->isReferenced()) {
|
||||
if (section->findEntry("unref_section_ok") == NULL) {
|
||||
cerr << "Section " << sectionName << " not referenced."
|
||||
<< endl;
|
||||
unref = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (section->printUnreferenced(sectionName)) {
|
||||
unref = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return unref;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IniFile::Section::dump(const string §ionName)
|
||||
{
|
||||
for (EntryTable::iterator ei = table.begin();
|
||||
ei != table.end(); ++ei) {
|
||||
cout << sectionName << ": " << (*ei).first << " => "
|
||||
<< (*ei).second->getValue() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IniFile::dump()
|
||||
{
|
||||
for (SectionTable::iterator i = table.begin();
|
||||
i != table.end(); ++i) {
|
||||
i->second->dump(i->first);
|
||||
}
|
||||
}
|
||||
203
simulators/gem5/src/base/inifile.hh
Normal file
203
simulators/gem5/src/base/inifile.hh
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __INIFILE_HH__
|
||||
#define __INIFILE_HH__
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/hashmap.hh"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Declaration of IniFile object.
|
||||
* @todo Change comments to match documentation style.
|
||||
*/
|
||||
|
||||
///
|
||||
/// This class represents the contents of a ".ini" file.
|
||||
///
|
||||
/// It's basically a two level lookup table: a set of named sections,
|
||||
/// where each section is a set of key/value pairs. Section names,
|
||||
/// keys, and values are all uninterpreted strings.
|
||||
///
|
||||
class IniFile
|
||||
{
|
||||
protected:
|
||||
|
||||
///
|
||||
/// A single key/value pair.
|
||||
///
|
||||
class Entry
|
||||
{
|
||||
std::string value; ///< The entry value.
|
||||
mutable bool referenced; ///< Has this entry been used?
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
Entry(const std::string &v)
|
||||
: value(v), referenced(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// Has this entry been used?
|
||||
bool isReferenced() { return referenced; }
|
||||
|
||||
/// Fetch the value.
|
||||
const std::string &getValue() const;
|
||||
|
||||
/// Set the value.
|
||||
void setValue(const std::string &v) { value = v; }
|
||||
|
||||
/// Append the given string to the value. A space is inserted
|
||||
/// between the existing value and the new value. Since this
|
||||
/// operation is typically used with values that are
|
||||
/// space-separated lists of tokens, this keeps the tokens
|
||||
/// separate.
|
||||
void appendValue(const std::string &v) { value += " "; value += v; }
|
||||
};
|
||||
|
||||
///
|
||||
/// A section.
|
||||
///
|
||||
class Section
|
||||
{
|
||||
/// EntryTable type. Map of strings to Entry object pointers.
|
||||
typedef m5::hash_map<std::string, Entry *> EntryTable;
|
||||
|
||||
EntryTable table; ///< Table of entries.
|
||||
mutable bool referenced; ///< Has this section been used?
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
Section()
|
||||
: table(), referenced(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// Has this section been used?
|
||||
bool isReferenced() { return referenced; }
|
||||
|
||||
/// Add an entry to the table. If an entry with the same name
|
||||
/// already exists, the 'append' parameter is checked If true,
|
||||
/// the new value will be appended to the existing entry. If
|
||||
/// false, the new value will replace the existing entry.
|
||||
void addEntry(const std::string &entryName, const std::string &value,
|
||||
bool append);
|
||||
|
||||
/// Add an entry to the table given a string assigment.
|
||||
/// Assignment should be of the form "param=value" or
|
||||
/// "param+=value" (for append). This funciton parses the
|
||||
/// assignment statment and calls addEntry().
|
||||
/// @retval True for success, false if parse error.
|
||||
bool add(const std::string &assignment);
|
||||
|
||||
/// Find the entry with the given name.
|
||||
/// @retval Pointer to the entry object, or NULL if none.
|
||||
Entry *findEntry(const std::string &entryName) const;
|
||||
|
||||
/// Print the unreferenced entries in this section to cerr.
|
||||
/// Messages can be suppressed using "unref_section_ok" and
|
||||
/// "unref_entries_ok".
|
||||
/// @param sectionName Name of this section, for use in output message.
|
||||
/// @retval True if any entries were printed.
|
||||
bool printUnreferenced(const std::string §ionName);
|
||||
|
||||
/// Print the contents of this section to cout (for debugging).
|
||||
void dump(const std::string §ionName);
|
||||
};
|
||||
|
||||
/// SectionTable type. Map of strings to Section object pointers.
|
||||
typedef m5::hash_map<std::string, Section *> SectionTable;
|
||||
|
||||
protected:
|
||||
/// Hash of section names to Section object pointers.
|
||||
SectionTable table;
|
||||
|
||||
/// Look up section with the given name, creating a new section if
|
||||
/// not found.
|
||||
/// @retval Pointer to section object.
|
||||
Section *addSection(const std::string §ionName);
|
||||
|
||||
/// Look up section with the given name.
|
||||
/// @retval Pointer to section object, or NULL if not found.
|
||||
Section *findSection(const std::string §ionName) const;
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
IniFile();
|
||||
|
||||
/// Destructor.
|
||||
~IniFile();
|
||||
|
||||
/// Load parameter settings from given istream. This is a helper
|
||||
/// function for load(string) and loadCPP(), which open a file
|
||||
/// and then pass it here.
|
||||
/// @retval True if successful, false if errors were encountered.
|
||||
bool load(std::istream &f);
|
||||
|
||||
/// Load the specified file.
|
||||
/// Parameter settings found in the file will be merged with any
|
||||
/// already defined in this object.
|
||||
/// @param file The path of the file to load.
|
||||
/// @retval True if successful, false if errors were encountered.
|
||||
bool load(const std::string &file);
|
||||
|
||||
/// Take string of the form "<section>:<parameter>=<value>" or
|
||||
/// "<section>:<parameter>+=<value>" and add to database.
|
||||
/// @retval True if successful, false if parse error.
|
||||
bool add(const std::string &s);
|
||||
|
||||
/// Find value corresponding to given section and entry names.
|
||||
/// Value is returned by reference in 'value' param.
|
||||
/// @retval True if found, false if not.
|
||||
bool find(const std::string §ion, const std::string &entry,
|
||||
std::string &value) const;
|
||||
|
||||
/// Determine whether the named section exists in the .ini file.
|
||||
/// Note that the 'Section' class is (intentionally) not public,
|
||||
/// so all clients can do is get a bool that says whether there
|
||||
/// are any values in that section or not.
|
||||
/// @return True if the section exists.
|
||||
bool sectionExists(const std::string §ion) const;
|
||||
|
||||
/// Print unreferenced entries in object. Iteratively calls
|
||||
/// printUnreferend() on all the constituent sections.
|
||||
bool printUnreferenced();
|
||||
|
||||
/// Dump contents to cout. For debugging.
|
||||
void dump();
|
||||
};
|
||||
|
||||
#endif // __INIFILE_HH__
|
||||
61
simulators/gem5/src/base/intmath.cc
Normal file
61
simulators/gem5/src/base/intmath.cc
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#include "base/intmath.hh"
|
||||
|
||||
int
|
||||
prevPrime(int n)
|
||||
{
|
||||
int decr;
|
||||
|
||||
// If the number is even, let's start with the previous odd number.
|
||||
if (!(n & 1))
|
||||
--n;
|
||||
|
||||
// Lets test for divisibility by 3. Then we will be able to easily
|
||||
// avoid numbers that are divisible by 3 in the future.
|
||||
decr = n % 3;
|
||||
if (decr == 0) {
|
||||
n -= 2;
|
||||
decr = 2;
|
||||
}
|
||||
else if (decr == 1)
|
||||
decr = 4;
|
||||
|
||||
for (;;) {
|
||||
if (isPrime(n))
|
||||
return n;
|
||||
n -= decr;
|
||||
// Toggle between 2 and 4 to prevent trying numbers that are known
|
||||
// to be divisible by 3.
|
||||
decr = 6 - decr;
|
||||
}
|
||||
}
|
||||
254
simulators/gem5/src/base/intmath.hh
Normal file
254
simulators/gem5/src/base/intmath.hh
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_INTMATH_HH__
|
||||
#define __BASE_INTMATH_HH__
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
// Returns the prime number one less than n.
|
||||
int prevPrime(int n);
|
||||
|
||||
// Determine if a number is prime
|
||||
template <class T>
|
||||
inline bool
|
||||
isPrime(T n)
|
||||
{
|
||||
T i;
|
||||
|
||||
if (n == 2 || n == 3)
|
||||
return true;
|
||||
|
||||
// Don't try every odd number to prove if it is a prime.
|
||||
// Toggle between every 2nd and 4th number.
|
||||
// (This is because every 6th odd number is divisible by 3.)
|
||||
for (i = 5; i*i <= n; i += 6) {
|
||||
if (((n % i) == 0 ) || ((n % (i + 2)) == 0) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
leastSigBit(T n)
|
||||
{
|
||||
return n & ~(n - 1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool
|
||||
isPowerOf2(T n)
|
||||
{
|
||||
return n != 0 && leastSigBit(n) == n;
|
||||
}
|
||||
|
||||
inline uint64_t
|
||||
power(uint32_t n, uint32_t e)
|
||||
{
|
||||
if (e > 20)
|
||||
warn("Warning, power() function is quite slow for large exponents\n");
|
||||
|
||||
if (e == 0)
|
||||
return 1;
|
||||
|
||||
uint64_t result = n;
|
||||
uint64_t old_result = 0;
|
||||
for (int x = 1; x < e; x++) {
|
||||
old_result = result;
|
||||
result *= n;
|
||||
if (old_result > result)
|
||||
warn("power() overflowed!\n");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
floorLog2(unsigned x)
|
||||
{
|
||||
assert(x > 0);
|
||||
|
||||
int y = 0;
|
||||
|
||||
if (x & 0xffff0000) { y += 16; x >>= 16; }
|
||||
if (x & 0x0000ff00) { y += 8; x >>= 8; }
|
||||
if (x & 0x000000f0) { y += 4; x >>= 4; }
|
||||
if (x & 0x0000000c) { y += 2; x >>= 2; }
|
||||
if (x & 0x00000002) { y += 1; }
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
inline int
|
||||
floorLog2(unsigned long x)
|
||||
{
|
||||
assert(x > 0);
|
||||
|
||||
int y = 0;
|
||||
|
||||
#if defined(__LP64__)
|
||||
if (x & ULL(0xffffffff00000000)) { y += 32; x >>= 32; }
|
||||
#endif
|
||||
if (x & 0xffff0000) { y += 16; x >>= 16; }
|
||||
if (x & 0x0000ff00) { y += 8; x >>= 8; }
|
||||
if (x & 0x000000f0) { y += 4; x >>= 4; }
|
||||
if (x & 0x0000000c) { y += 2; x >>= 2; }
|
||||
if (x & 0x00000002) { y += 1; }
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
inline int
|
||||
floorLog2(unsigned long long x)
|
||||
{
|
||||
assert(x > 0);
|
||||
|
||||
int y = 0;
|
||||
|
||||
if (x & ULL(0xffffffff00000000)) { y += 32; x >>= 32; }
|
||||
if (x & ULL(0x00000000ffff0000)) { y += 16; x >>= 16; }
|
||||
if (x & ULL(0x000000000000ff00)) { y += 8; x >>= 8; }
|
||||
if (x & ULL(0x00000000000000f0)) { y += 4; x >>= 4; }
|
||||
if (x & ULL(0x000000000000000c)) { y += 2; x >>= 2; }
|
||||
if (x & ULL(0x0000000000000002)) { y += 1; }
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
inline int
|
||||
floorLog2(int x)
|
||||
{
|
||||
assert(x > 0);
|
||||
return floorLog2((unsigned)x);
|
||||
}
|
||||
|
||||
inline int
|
||||
floorLog2(long x)
|
||||
{
|
||||
assert(x > 0);
|
||||
return floorLog2((unsigned long)x);
|
||||
}
|
||||
|
||||
inline int
|
||||
floorLog2(long long x)
|
||||
{
|
||||
assert(x > 0);
|
||||
return floorLog2((unsigned long long)x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline int
|
||||
ceilLog2(T n)
|
||||
{
|
||||
if (n == 1)
|
||||
return 0;
|
||||
|
||||
return floorLog2(n - (T)1) + 1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
floorPow2(T n)
|
||||
{
|
||||
return (T)1 << floorLog2(n);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
ceilPow2(T n)
|
||||
{
|
||||
return (T)1 << ceilLog2(n);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
divCeil(T a, T b)
|
||||
{
|
||||
return (a + b - 1) / b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
roundUp(T val, int align)
|
||||
{
|
||||
T mask = (T)align - 1;
|
||||
return (val + mask) & ~mask;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
roundDown(T val, int align)
|
||||
{
|
||||
T mask = (T)align - 1;
|
||||
return val & ~mask;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isHex(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') ||
|
||||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= 'a' && c <= 'f');
|
||||
}
|
||||
|
||||
inline bool
|
||||
isOct(char c)
|
||||
{
|
||||
return c >= '0' && c <= '7';
|
||||
}
|
||||
|
||||
inline bool
|
||||
isDec(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
inline int
|
||||
hex2Int(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - '0');
|
||||
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return (c - 'A') + 10;
|
||||
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return (c - 'a') + 10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // __BASE_INTMATH_HH__
|
||||
94
simulators/gem5/src/base/loader/aout_object.cc
Normal file
94
simulators/gem5/src/base/loader/aout_object.cc
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/loader/aout_object.hh"
|
||||
#include "base/loader/exec_aout.h"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "debug/Loader.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ObjectFile *
|
||||
AoutObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
|
||||
{
|
||||
if (!N_BADMAG(*(aout_exechdr *)data)) {
|
||||
// right now this is only used for Alpha PAL code
|
||||
return new AoutObject(fname, fd, len, data,
|
||||
ObjectFile::Alpha, ObjectFile::UnknownOpSys);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AoutObject::AoutObject(const string &_filename, int _fd,
|
||||
size_t _len, uint8_t *_data,
|
||||
Arch _arch, OpSys _opSys)
|
||||
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
|
||||
{
|
||||
execHdr = (aout_exechdr *)fileData;
|
||||
|
||||
entry = execHdr->entry;
|
||||
|
||||
text.baseAddr = N_TXTADDR(*execHdr);
|
||||
text.size = execHdr->tsize;
|
||||
text.fileImage = fileData + N_TXTOFF(*execHdr);
|
||||
|
||||
data.baseAddr = N_DATADDR(*execHdr);
|
||||
data.size = execHdr->dsize;
|
||||
data.fileImage = fileData + N_DATOFF(*execHdr);
|
||||
|
||||
bss.baseAddr = N_BSSADDR(*execHdr);
|
||||
bss.size = execHdr->bsize;
|
||||
bss.fileImage = NULL;
|
||||
|
||||
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::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||
{
|
||||
// a.out symbols not supported yet
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AoutObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||
{
|
||||
// a.out symbols not supported yet
|
||||
return false;
|
||||
}
|
||||
60
simulators/gem5/src/base/loader/aout_object.hh
Normal file
60
simulators/gem5/src/base/loader/aout_object.hh
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __AOUT_OBJECT_HH__
|
||||
#define __AOUT_OBJECT_HH__
|
||||
|
||||
#include "base/loader/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,
|
||||
Arch _arch, OpSys _opSys);
|
||||
|
||||
public:
|
||||
virtual ~AoutObject() {}
|
||||
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
|
||||
static ObjectFile *tryFile(const std::string &fname, int fd,
|
||||
size_t len, uint8_t *data);
|
||||
};
|
||||
|
||||
#endif // __AOUT_OBJECT_HH__
|
||||
519
simulators/gem5/src/base/loader/coff_sym.h
Normal file
519
simulators/gem5/src/base/loader/coff_sym.h
Normal file
@ -0,0 +1,519 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005-2006 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
200
simulators/gem5/src/base/loader/coff_symconst.h
Normal file
200
simulators/gem5/src/base/loader/coff_symconst.h
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005-2006 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
161
simulators/gem5/src/base/loader/ecoff_object.cc
Normal file
161
simulators/gem5/src/base/loader/ecoff_object.cc
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/loader/ecoff_object.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "base/types.hh"
|
||||
#include "debug/Loader.hh"
|
||||
|
||||
// Only alpha will be able to load ecoff files for now.
|
||||
// base/types.hh and ecoff_machdep.h must be before the other .h files
|
||||
// because they are are gathered from other code bases and require some
|
||||
// typedefs from those files.
|
||||
#include "arch/alpha/ecoff_machdep.h"
|
||||
#include "base/loader/coff_sym.h"
|
||||
#include "base/loader/coff_symconst.h"
|
||||
#include "base/loader/exec_ecoff.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,
|
||||
ObjectFile::Alpha, ObjectFile::Tru64);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EcoffObject::EcoffObject(const string &_filename, int _fd,
|
||||
size_t _len, uint8_t *_data,
|
||||
Arch _arch, OpSys _opSys)
|
||||
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
|
||||
{
|
||||
execHdr = (ecoff_exechdr *)fileData;
|
||||
fileHdr = &(execHdr->f);
|
||||
aoutHdr = &(execHdr->a);
|
||||
|
||||
entry = aoutHdr->entry;
|
||||
|
||||
text.baseAddr = aoutHdr->text_start;
|
||||
text.size = aoutHdr->tsize;
|
||||
text.fileImage = fileData + ECOFF_TXTOFF(execHdr);
|
||||
|
||||
data.baseAddr = aoutHdr->data_start;
|
||||
data.size = aoutHdr->dsize;
|
||||
data.fileImage = fileData + ECOFF_DATOFF(execHdr);
|
||||
|
||||
bss.baseAddr = aoutHdr->bss_start;
|
||||
bss.size = aoutHdr->bsize;
|
||||
bss.fileImage = NULL;
|
||||
|
||||
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::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||
{
|
||||
if (!symtab)
|
||||
return false;
|
||||
|
||||
if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
|
||||
warn("loadGlobalSymbols: wrong magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
|
||||
if (syms->magic != magicSym2) {
|
||||
warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
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, Addr addrMask)
|
||||
{
|
||||
if (!symtab)
|
||||
return false;
|
||||
|
||||
if (fileHdr->f_magic != ECOFF_MAGIC_ALPHA) {
|
||||
warn("loadGlobalSymbols: wrong magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
ecoff_symhdr *syms = (ecoff_symhdr *)(fileData + fileHdr->f_symptr);
|
||||
if (syms->magic != magicSym2) {
|
||||
warn("loadGlobalSymbols: bad symbol header magic on %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
64
simulators/gem5/src/base/loader/ecoff_object.hh
Normal file
64
simulators/gem5/src/base/loader/ecoff_object.hh
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __ECOFF_OBJECT_HH__
|
||||
#define __ECOFF_OBJECT_HH__
|
||||
|
||||
#include "base/loader/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,
|
||||
Arch _arch, OpSys _opSys);
|
||||
|
||||
public:
|
||||
virtual ~EcoffObject() {}
|
||||
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
|
||||
static ObjectFile *tryFile(const std::string &fname, int fd,
|
||||
size_t len, uint8_t *data);
|
||||
};
|
||||
|
||||
#endif // __ECOFF_OBJECT_HH__
|
||||
476
simulators/gem5/src/base/loader/elf_object.cc
Normal file
476
simulators/gem5/src/base/loader/elf_object.cc
Normal file
@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
* Ali Saidi
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
#include "base/loader/elf_object.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "debug/Loader.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "gelf.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ObjectFile *
|
||||
ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
|
||||
{
|
||||
Elf *elf;
|
||||
GElf_Ehdr ehdr;
|
||||
Arch arch = UnknownArch;
|
||||
OpSys opSys = UnknownOpSys;
|
||||
|
||||
// check that header matches library version
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
panic("wrong elf version number!");
|
||||
|
||||
// get a pointer to elf structure
|
||||
elf = elf_memory((char*)data,len);
|
||||
// will only fail if fd is invalid
|
||||
assert(elf != NULL);
|
||||
|
||||
// Check that we actually have a elf file
|
||||
if (gelf_getehdr(elf, &ehdr) ==0) {
|
||||
DPRINTFR(Loader, "Not ELF\n");
|
||||
elf_end(elf);
|
||||
return NULL;
|
||||
} else {
|
||||
//Detect the architecture
|
||||
//Since we don't know how to check for alpha right now, we'll
|
||||
//just assume if it wasn't something else and it's 64 bit, that's
|
||||
//what it must be.
|
||||
if (ehdr.e_machine == EM_SPARC64 ||
|
||||
(ehdr.e_machine == EM_SPARC &&
|
||||
ehdr.e_ident[EI_CLASS] == ELFCLASS64)||
|
||||
ehdr.e_machine == EM_SPARCV9) {
|
||||
arch = ObjectFile::SPARC64;
|
||||
} else if (ehdr.e_machine == EM_SPARC32PLUS ||
|
||||
(ehdr.e_machine == EM_SPARC &&
|
||||
ehdr.e_ident[EI_CLASS] == ELFCLASS32)) {
|
||||
arch = ObjectFile::SPARC32;
|
||||
} else if (ehdr.e_machine == EM_MIPS
|
||||
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
|
||||
if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) {
|
||||
arch = ObjectFile::Mips;
|
||||
} else {
|
||||
fatal("The binary you're trying to load is compiled for big "
|
||||
"endian MIPS. M5\nonly supports little endian MIPS. "
|
||||
"Please recompile your binary.\n");
|
||||
}
|
||||
} else if (ehdr.e_machine == EM_X86_64 &&
|
||||
ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
|
||||
arch = ObjectFile::X86_64;
|
||||
} else if (ehdr.e_machine == EM_386 &&
|
||||
ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
|
||||
arch = ObjectFile::I386;
|
||||
} else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
|
||||
arch = ObjectFile::Alpha;
|
||||
} else if (ehdr.e_machine == EM_ARM) {
|
||||
if (bits(ehdr.e_entry, 0)) {
|
||||
arch = ObjectFile::Thumb;
|
||||
} else {
|
||||
arch = ObjectFile::Arm;
|
||||
}
|
||||
} else if (ehdr.e_machine == EM_PPC &&
|
||||
ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
|
||||
if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
|
||||
arch = ObjectFile::Power;
|
||||
} else {
|
||||
fatal("The binary you're trying to load is compiled for "
|
||||
"little endian Power.\nM5 only supports big "
|
||||
"endian Power. Please recompile your binary.\n");
|
||||
}
|
||||
} else if (ehdr.e_machine == EM_PPC64) {
|
||||
fatal("The binary you're trying to load is compiled for 64-bit "
|
||||
"Power. M5\n only supports 32-bit Power. Please "
|
||||
"recompile your binary.\n");
|
||||
} else {
|
||||
warn("Unknown architecture: %d\n", ehdr.e_machine);
|
||||
arch = ObjectFile::UnknownArch;
|
||||
}
|
||||
|
||||
//Detect the operating system
|
||||
switch (ehdr.e_ident[EI_OSABI])
|
||||
{
|
||||
|
||||
case ELFOSABI_LINUX:
|
||||
opSys = ObjectFile::Linux;
|
||||
break;
|
||||
case ELFOSABI_SOLARIS:
|
||||
opSys = ObjectFile::Solaris;
|
||||
break;
|
||||
case ELFOSABI_TRU64:
|
||||
opSys = ObjectFile::Tru64;
|
||||
break;
|
||||
case ELFOSABI_ARM:
|
||||
opSys = ObjectFile::LinuxArmOABI;
|
||||
break;
|
||||
default:
|
||||
opSys = ObjectFile::UnknownOpSys;
|
||||
}
|
||||
|
||||
//take a look at the .note.ABI section
|
||||
//It can let us know what's what.
|
||||
if (opSys == ObjectFile::UnknownOpSys) {
|
||||
Elf_Scn *section;
|
||||
GElf_Shdr shdr;
|
||||
Elf_Data *data;
|
||||
uint32_t osAbi;;
|
||||
int secIdx = 1;
|
||||
|
||||
// Get the first section
|
||||
section = elf_getscn(elf, secIdx);
|
||||
|
||||
// While there are no more sections
|
||||
while (section != NULL && opSys == ObjectFile::UnknownOpSys) {
|
||||
gelf_getshdr(section, &shdr);
|
||||
if (shdr.sh_type == SHT_NOTE && !strcmp(".note.ABI-tag",
|
||||
elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) {
|
||||
// we have found a ABI note section
|
||||
// Check the 5th 32bit word for OS 0 == linux, 1 == hurd,
|
||||
// 2 == solaris, 3 == freebsd
|
||||
data = elf_rawdata(section, NULL);
|
||||
assert(data->d_buf);
|
||||
if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
|
||||
osAbi = htole(((uint32_t*)data->d_buf)[4]);
|
||||
else
|
||||
osAbi = htobe(((uint32_t*)data->d_buf)[4]);
|
||||
|
||||
switch(osAbi) {
|
||||
case 0:
|
||||
opSys = ObjectFile::Linux;
|
||||
break;
|
||||
case 2:
|
||||
opSys = ObjectFile::Solaris;
|
||||
break;
|
||||
}
|
||||
} // if section found
|
||||
if (!strcmp(".SUNW_version", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)))
|
||||
opSys = ObjectFile::Solaris;
|
||||
if (!strcmp(".stab.index", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)))
|
||||
opSys = ObjectFile::Solaris;
|
||||
|
||||
section = elf_getscn(elf, ++secIdx);
|
||||
} // while sections
|
||||
}
|
||||
|
||||
ElfObject * result = new ElfObject(fname, fd, len, data, arch, opSys);
|
||||
|
||||
//The number of headers in the file
|
||||
result->_programHeaderCount = ehdr.e_phnum;
|
||||
//Record the size of each entry
|
||||
result->_programHeaderSize = ehdr.e_phentsize;
|
||||
if(result->_programHeaderCount) //If there is a program header table
|
||||
{
|
||||
//Figure out the virtual address of the header table in the
|
||||
//final memory image. We use the program headers themselves
|
||||
//to translate from a file offset to the address in the image.
|
||||
GElf_Phdr phdr;
|
||||
uint64_t e_phoff = ehdr.e_phoff;
|
||||
result->_programHeaderTable = 0;
|
||||
for(int hdrnum = 0; hdrnum < result->_programHeaderCount; hdrnum++)
|
||||
{
|
||||
gelf_getphdr(elf, hdrnum, &phdr);
|
||||
//Check if we've found the segment with the headers in it
|
||||
if(phdr.p_offset <= e_phoff &&
|
||||
phdr.p_offset + phdr.p_filesz > e_phoff)
|
||||
{
|
||||
result->_programHeaderTable = phdr.p_paddr + e_phoff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
result->_programHeaderTable = 0;
|
||||
|
||||
|
||||
elf_end(elf);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ElfObject::ElfObject(const string &_filename, int _fd,
|
||||
size_t _len, uint8_t *_data,
|
||||
Arch _arch, OpSys _opSys)
|
||||
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
|
||||
|
||||
{
|
||||
Elf *elf;
|
||||
GElf_Ehdr ehdr;
|
||||
|
||||
// check that header matches library version
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
panic("wrong elf version number!");
|
||||
|
||||
// get a pointer to elf structure
|
||||
elf = elf_memory((char*)fileData,len);
|
||||
// will only fail if fd is invalid
|
||||
assert(elf != NULL);
|
||||
|
||||
// Check that we actually have a elf file
|
||||
if (gelf_getehdr(elf, &ehdr) ==0) {
|
||||
panic("Not ELF, shouldn't be here");
|
||||
}
|
||||
|
||||
entry = ehdr.e_entry;
|
||||
|
||||
// initialize segment sizes to 0 in case they're not present
|
||||
text.size = data.size = bss.size = 0;
|
||||
|
||||
int secIdx = 1;
|
||||
Elf_Scn *section;
|
||||
GElf_Shdr shdr;
|
||||
|
||||
// The first address of some important sections.
|
||||
Addr textSecStart = 0;
|
||||
Addr dataSecStart = 0;
|
||||
Addr bssSecStart = 0;
|
||||
|
||||
// Get the first section
|
||||
section = elf_getscn(elf, secIdx);
|
||||
|
||||
// Find the beginning of the most interesting sections.
|
||||
while (section != NULL) {
|
||||
gelf_getshdr(section, &shdr);
|
||||
char * secName = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
|
||||
|
||||
if (secName) {
|
||||
if (!strcmp(".text", secName)) {
|
||||
textSecStart = shdr.sh_addr;
|
||||
} else if (!strcmp(".data", secName)) {
|
||||
dataSecStart = shdr.sh_addr;
|
||||
} else if (!strcmp(".bss", secName)) {
|
||||
bssSecStart = shdr.sh_addr;
|
||||
}
|
||||
} else {
|
||||
Elf_Error errorNum = (Elf_Error)elf_errno();
|
||||
if (errorNum != ELF_E_NONE) {
|
||||
const char *errorMessage = elf_errmsg(errorNum);
|
||||
fatal("Error from libelf: %s.\n", errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
section = elf_getscn(elf, ++secIdx);
|
||||
}
|
||||
|
||||
// Go through all the segments in the program, record them, and scrape
|
||||
// out information about the text, data, and bss areas needed by other
|
||||
// code.
|
||||
for (int i = 0; i < ehdr.e_phnum; ++i) {
|
||||
GElf_Phdr phdr;
|
||||
if (gelf_getphdr(elf, i, &phdr) == 0) {
|
||||
panic("gelf_getphdr failed for segment %d.", i);
|
||||
}
|
||||
|
||||
// for now we don't care about non-loadable segments
|
||||
if (!(phdr.p_type & PT_LOAD))
|
||||
continue;
|
||||
|
||||
// Check to see if this segment contains the bss section.
|
||||
if (phdr.p_paddr <= bssSecStart &&
|
||||
phdr.p_paddr + phdr.p_memsz > bssSecStart &&
|
||||
phdr.p_memsz - phdr.p_filesz > 0) {
|
||||
bss.baseAddr = phdr.p_paddr + phdr.p_filesz;
|
||||
bss.size = phdr.p_memsz - phdr.p_filesz;
|
||||
bss.fileImage = NULL;
|
||||
}
|
||||
|
||||
// Check to see if this is the text or data segment
|
||||
if (phdr.p_vaddr <= textSecStart &&
|
||||
phdr.p_vaddr + phdr.p_filesz > textSecStart) {
|
||||
text.baseAddr = phdr.p_paddr;
|
||||
text.size = phdr.p_filesz;
|
||||
text.fileImage = fileData + phdr.p_offset;
|
||||
} else if (phdr.p_vaddr <= dataSecStart &&
|
||||
phdr.p_vaddr + phdr.p_filesz > dataSecStart) {
|
||||
data.baseAddr = phdr.p_paddr;
|
||||
data.size = phdr.p_filesz;
|
||||
data.fileImage = fileData + phdr.p_offset;
|
||||
} else {
|
||||
// If it's none of the above but is loadable,
|
||||
// load the filesize worth of data
|
||||
Segment extra;
|
||||
extra.baseAddr = phdr.p_paddr;
|
||||
extra.size = phdr.p_filesz;
|
||||
extra.fileImage = fileData + phdr.p_offset;
|
||||
extraSegments.push_back(extra);
|
||||
}
|
||||
}
|
||||
|
||||
// should have found at least one loadable segment
|
||||
assert(text.size != 0);
|
||||
|
||||
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);
|
||||
|
||||
elf_end(elf);
|
||||
|
||||
// We will actually read the sections when we need to load them
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask)
|
||||
{
|
||||
Elf *elf;
|
||||
int sec_idx = 1; // there is a 0 but it is nothing, go figure
|
||||
Elf_Scn *section;
|
||||
GElf_Shdr shdr;
|
||||
Elf_Data *data;
|
||||
int count, ii;
|
||||
bool found = false;
|
||||
GElf_Sym sym;
|
||||
|
||||
if (!symtab)
|
||||
return false;
|
||||
|
||||
// check that header matches library version
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
panic("wrong elf version number!");
|
||||
|
||||
// get a pointer to elf structure
|
||||
elf = elf_memory((char*)fileData,len);
|
||||
|
||||
assert(elf != NULL);
|
||||
|
||||
// Get the first section
|
||||
section = elf_getscn(elf, sec_idx);
|
||||
|
||||
// While there are no more sections
|
||||
while (section != NULL) {
|
||||
gelf_getshdr(section, &shdr);
|
||||
|
||||
if (shdr.sh_type == SHT_SYMTAB) {
|
||||
found = true;
|
||||
data = elf_getdata(section, NULL);
|
||||
count = shdr.sh_size / shdr.sh_entsize;
|
||||
DPRINTF(Loader, "Found Symbol Table, %d symbols present\n", count);
|
||||
|
||||
// loop through all the symbols, only loading global ones
|
||||
for (ii = 0; ii < count; ++ii) {
|
||||
gelf_getsym(data, ii, &sym);
|
||||
if (GELF_ST_BIND(sym.st_info) == binding) {
|
||||
char *sym_name = elf_strptr(elf, shdr.sh_link, sym.st_name);
|
||||
if (sym_name && sym_name[0] != '$') {
|
||||
DPRINTF(Loader, "Symbol: %-40s value %#x\n",
|
||||
sym_name, sym.st_value);
|
||||
symtab->insert(sym.st_value & mask, sym_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++sec_idx;
|
||||
section = elf_getscn(elf, sec_idx);
|
||||
}
|
||||
|
||||
elf_end(elf);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
ElfObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||
{
|
||||
return loadSomeSymbols(symtab, STB_GLOBAL, addrMask);
|
||||
}
|
||||
|
||||
bool
|
||||
ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||
{
|
||||
return loadSomeSymbols(symtab, STB_LOCAL, addrMask);
|
||||
}
|
||||
|
||||
bool
|
||||
ElfObject::loadSections(PortProxy& memProxy, Addr addrMask)
|
||||
{
|
||||
if (!ObjectFile::loadSections(memProxy, addrMask))
|
||||
return false;
|
||||
|
||||
vector<Segment>::iterator extraIt;
|
||||
for (extraIt = extraSegments.begin();
|
||||
extraIt != extraSegments.end(); extraIt++) {
|
||||
if (!loadSection(&(*extraIt), memProxy, addrMask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ElfObject::getSections()
|
||||
{
|
||||
Elf *elf;
|
||||
int sec_idx = 1; // there is a 0 but it is nothing, go figure
|
||||
Elf_Scn *section;
|
||||
GElf_Shdr shdr;
|
||||
|
||||
GElf_Ehdr ehdr;
|
||||
|
||||
assert(!sectionNames.size());
|
||||
|
||||
// check that header matches library version
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
panic("wrong elf version number!");
|
||||
|
||||
// get a pointer to elf structure
|
||||
elf = elf_memory((char*)fileData,len);
|
||||
assert(elf != NULL);
|
||||
|
||||
// Check that we actually have a elf file
|
||||
if (gelf_getehdr(elf, &ehdr) ==0) {
|
||||
panic("Not ELF, shouldn't be here");
|
||||
}
|
||||
|
||||
// Get the first section
|
||||
section = elf_getscn(elf, sec_idx);
|
||||
|
||||
// While there are no more sections
|
||||
while (section != NULL) {
|
||||
gelf_getshdr(section, &shdr);
|
||||
sectionNames.insert(elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));
|
||||
section = elf_getscn(elf, ++sec_idx);
|
||||
} // while sections
|
||||
}
|
||||
|
||||
bool
|
||||
ElfObject::sectionExists(string sec)
|
||||
{
|
||||
if (!sectionNames.size())
|
||||
getSections();
|
||||
return sectionNames.find(sec) != sectionNames.end();
|
||||
}
|
||||
|
||||
|
||||
85
simulators/gem5/src/base/loader/elf_object.hh
Normal file
85
simulators/gem5/src/base/loader/elf_object.hh
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __ELF_OBJECT_HH__
|
||||
#define __ELF_OBJECT_HH__
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "base/loader/object_file.hh"
|
||||
|
||||
class ElfObject : public ObjectFile
|
||||
{
|
||||
protected:
|
||||
|
||||
//The global definition of a "Section" is closest to elf's segments.
|
||||
typedef ObjectFile::Section Segment;
|
||||
|
||||
//These values are provided to a linux process by the kernel, so we
|
||||
//need to keep them around.
|
||||
Addr _programHeaderTable;
|
||||
uint16_t _programHeaderSize;
|
||||
uint16_t _programHeaderCount;
|
||||
std::set<std::string> sectionNames;
|
||||
|
||||
/// Helper functions for loadGlobalSymbols() and loadLocalSymbols().
|
||||
bool loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask);
|
||||
|
||||
ElfObject(const std::string &_filename, int _fd,
|
||||
size_t _len, uint8_t *_data,
|
||||
Arch _arch, OpSys _opSys);
|
||||
|
||||
void getSections();
|
||||
bool sectionExists(std::string sec);
|
||||
|
||||
std::vector<Segment> extraSegments;
|
||||
|
||||
public:
|
||||
virtual ~ElfObject() {}
|
||||
|
||||
bool loadSections(PortProxy& memProxy,
|
||||
Addr addrMask = std::numeric_limits<Addr>::max());
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
|
||||
virtual bool isDynamic() { return sectionExists(".interp"); }
|
||||
virtual bool hasTLS() { return sectionExists(".tbss"); }
|
||||
|
||||
static ObjectFile *tryFile(const std::string &fname, int fd,
|
||||
size_t len, uint8_t *data);
|
||||
Addr programHeaderTable() {return _programHeaderTable;}
|
||||
uint16_t programHeaderSize() {return _programHeaderSize;}
|
||||
uint16_t programHeaderCount() {return _programHeaderCount;}
|
||||
};
|
||||
|
||||
#endif // __ELF_OBJECT_HH__
|
||||
61
simulators/gem5/src/base/loader/exec_aout.h
Normal file
61
simulators/gem5/src/base/loader/exec_aout.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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)
|
||||
|
||||
//Only alpha will be able to load aout for now
|
||||
#include "arch/alpha/aout_machdep.h"
|
||||
|
||||
#endif /* !_SYS_EXEC_AOUT_H_ */
|
||||
107
simulators/gem5/src/base/loader/exec_ecoff.h
Normal file
107
simulators/gem5/src/base/loader/exec_ecoff.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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_
|
||||
|
||||
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_ */
|
||||
138
simulators/gem5/src/base/loader/hex_file.cc
Executable file
138
simulators/gem5/src/base/loader/hex_file.cc
Executable file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2007 MIPS Technologies, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Authors: Jaidev Patwardhan
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "base/loader/hex_file.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
/*
|
||||
* Load a Hex File into memory. Currently only used with MIPS
|
||||
* BARE_IRON mode. A hex file consists of [Address Data] tuples that
|
||||
* get directly loaded into physical memory. The address specified is
|
||||
* a word address (i.e., to get the byte address, shift left by 2) The
|
||||
* data is a full 32-bit hex value.
|
||||
*/
|
||||
HexFile::HexFile(const string _filename)
|
||||
: filename(_filename)
|
||||
{
|
||||
fp = fopen(filename.c_str(), "r");
|
||||
if (fp == NULL)
|
||||
panic("Unable to open %s\n", filename.c_str());
|
||||
}
|
||||
|
||||
HexFile::~HexFile()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
HexFile::loadSections(PortProxy& memProxy)
|
||||
{
|
||||
char Line[64];
|
||||
Addr MemAddr;
|
||||
uint32_t Data;
|
||||
while (!feof(fp)) {
|
||||
char *ret = fgets(Line, sizeof(Line), fp);
|
||||
if (!ret)
|
||||
panic("malformed file");
|
||||
parseLine(Line, &MemAddr, &Data);
|
||||
if (MemAddr != 0) {
|
||||
// Now, write to memory
|
||||
memProxy.writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HexFile::parseLine(char *Str, Addr *A, uint32_t *D)
|
||||
{
|
||||
int i = 0;
|
||||
bool Flag = false;
|
||||
*A = 0;
|
||||
*D = 0;
|
||||
int Digit = 0;
|
||||
unsigned Number = 0;
|
||||
|
||||
/* Skip white spaces */
|
||||
while (Str[i] != '\0' && Str[i]==' ')
|
||||
i++;
|
||||
|
||||
/* Ok, we're at some character...process things */
|
||||
while (Str[i] != '\0') {
|
||||
if (Str[i] >= '0' && Str[i] <= '9') {
|
||||
Digit = Str[i] - '0';
|
||||
} else if (Str[i] >= 'a' && Str[i] <= 'f') {
|
||||
Digit = Str[i] - 'a' + 10;
|
||||
} else if (Str[i] >= 'A' && Str[i] <= 'F') {
|
||||
Digit=Str[i]-'A'+10;
|
||||
} else if (Str[i] == ' ' || Str[i] == '\n') {
|
||||
if (Number == 0)
|
||||
return;
|
||||
if (Flag == false) {
|
||||
*A = Number;
|
||||
Number = 0;
|
||||
Flag = true;
|
||||
} else {
|
||||
*D = Number;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Ok, we've encountered a non-hex character, cannot be a
|
||||
// valid line, skip and return 0's
|
||||
*A = 0;
|
||||
*D = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
Number <<= 4;
|
||||
Number += Digit;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (Flag != true) {
|
||||
*A = 0;
|
||||
*D = 0;
|
||||
} else {
|
||||
*D = Number;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HexFile::close()
|
||||
{
|
||||
fclose(fp);
|
||||
}
|
||||
58
simulators/gem5/src/base/loader/hex_file.hh
Executable file
58
simulators/gem5/src/base/loader/hex_file.hh
Executable file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2004 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.
|
||||
*
|
||||
* Authors: Jaidev Patwardhan
|
||||
*/
|
||||
|
||||
#ifndef __BASE_LOADER_HEX_FILE_HH__
|
||||
#define __BASE_LOADER_HEX_FILE_HH__
|
||||
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
class PortProxy;
|
||||
|
||||
class HexFile
|
||||
{
|
||||
protected:
|
||||
const std::string filename;
|
||||
FILE *fp;
|
||||
|
||||
void parseLine(char *, Addr *, uint32_t *);
|
||||
|
||||
public:
|
||||
HexFile(const std::string _filename);
|
||||
virtual ~HexFile();
|
||||
|
||||
void close();
|
||||
bool loadSections(PortProxy& memProxy);
|
||||
};
|
||||
|
||||
#endif // __BASE_LOADER_HEX_FILE_HH__
|
||||
150
simulators/gem5/src/base/loader/object_file.cc
Normal file
150
simulators/gem5/src/base/loader/object_file.cc
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2004 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "base/loader/aout_object.hh"
|
||||
#include "base/loader/ecoff_object.hh"
|
||||
#include "base/loader/elf_object.hh"
|
||||
#include "base/loader/object_file.hh"
|
||||
#include "base/loader/raw_object.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ObjectFile::ObjectFile(const string &_filename, int _fd,
|
||||
size_t _len, uint8_t *_data,
|
||||
Arch _arch, OpSys _opSys)
|
||||
: filename(_filename), descriptor(_fd), fileData(_data), len(_len),
|
||||
arch(_arch), opSys(_opSys)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ObjectFile::~ObjectFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSection(Section *sec, PortProxy& memProxy, Addr addrMask)
|
||||
{
|
||||
if (sec->size != 0) {
|
||||
Addr addr = sec->baseAddr & addrMask;
|
||||
if (sec->fileImage) {
|
||||
memProxy.writeBlob(addr, sec->fileImage, sec->size);
|
||||
}
|
||||
else {
|
||||
// no image: must be bss
|
||||
memProxy.memsetBlob(addr, 0, sec->size);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSections(PortProxy& memProxy, Addr addrMask)
|
||||
{
|
||||
return (loadSection(&text, memProxy, addrMask)
|
||||
&& loadSection(&data, memProxy, addrMask)
|
||||
&& loadSection(&bss, memProxy, addrMask));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ObjectFile::close()
|
||||
{
|
||||
if (descriptor >= 0) {
|
||||
::close(descriptor);
|
||||
descriptor = -1;
|
||||
}
|
||||
|
||||
if (fileData) {
|
||||
::munmap((char*)fileData, len);
|
||||
fileData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ObjectFile *
|
||||
createObjectFile(const string &fname, bool raw)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (raw)
|
||||
return RawObject::tryFile(fname, fd, len, fileData);
|
||||
|
||||
// don't know what it is
|
||||
close(fd);
|
||||
munmap((char*)fileData, len);
|
||||
return NULL;
|
||||
}
|
||||
136
simulators/gem5/src/base/loader/object_file.hh
Normal file
136
simulators/gem5/src/base/loader/object_file.hh
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2004 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __OBJECT_FILE_HH__
|
||||
#define __OBJECT_FILE_HH__
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
class PortProxy;
|
||||
class SymbolTable;
|
||||
|
||||
class ObjectFile
|
||||
{
|
||||
public:
|
||||
|
||||
enum Arch {
|
||||
UnknownArch,
|
||||
Alpha,
|
||||
SPARC64,
|
||||
SPARC32,
|
||||
Mips,
|
||||
X86_64,
|
||||
I386,
|
||||
Arm,
|
||||
Thumb,
|
||||
Power
|
||||
};
|
||||
|
||||
enum OpSys {
|
||||
UnknownOpSys,
|
||||
Tru64,
|
||||
Linux,
|
||||
Solaris,
|
||||
LinuxArmOABI
|
||||
};
|
||||
|
||||
protected:
|
||||
const std::string filename;
|
||||
int descriptor;
|
||||
uint8_t *fileData;
|
||||
size_t len;
|
||||
|
||||
Arch arch;
|
||||
OpSys opSys;
|
||||
|
||||
ObjectFile(const std::string &_filename, int _fd,
|
||||
size_t _len, uint8_t *_data,
|
||||
Arch _arch, OpSys _opSys);
|
||||
|
||||
public:
|
||||
virtual ~ObjectFile();
|
||||
|
||||
void close();
|
||||
|
||||
virtual bool loadSections(PortProxy& memProxy, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max()) = 0;
|
||||
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max()) = 0;
|
||||
|
||||
virtual bool isDynamic() { return false; }
|
||||
virtual bool hasTLS() { return false; }
|
||||
|
||||
Arch getArch() const { return arch; }
|
||||
OpSys getOpSys() const { return opSys; }
|
||||
|
||||
protected:
|
||||
|
||||
struct Section {
|
||||
Addr baseAddr;
|
||||
uint8_t *fileImage;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
Addr entry;
|
||||
Addr globalPtr;
|
||||
|
||||
Section text;
|
||||
Section data;
|
||||
Section bss;
|
||||
|
||||
bool loadSection(Section *sec, PortProxy& memProxy, Addr addrMask);
|
||||
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
|
||||
|
||||
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; }
|
||||
|
||||
void setTextBase(Addr a) { text.baseAddr = a; }
|
||||
};
|
||||
|
||||
ObjectFile *createObjectFile(const std::string &fname, bool raw = false);
|
||||
|
||||
|
||||
#endif // __OBJECT_FILE_HH__
|
||||
82
simulators/gem5/src/base/loader/raw_object.cc
Normal file
82
simulators/gem5/src/base/loader/raw_object.cc
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#include "base/loader/raw_object.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "debug/Loader.hh"
|
||||
|
||||
ObjectFile *
|
||||
RawObject::tryFile(const std::string &fname, int fd, size_t len, uint8_t *data)
|
||||
{
|
||||
return new RawObject(fname, fd, len, data, ObjectFile::UnknownArch,
|
||||
ObjectFile::UnknownOpSys);
|
||||
}
|
||||
|
||||
RawObject::RawObject(const std::string &_filename, int _fd, size_t _len,
|
||||
uint8_t *_data, Arch _arch, OpSys _opSys)
|
||||
: ObjectFile(_filename, _fd, _len, _data, _arch, _opSys)
|
||||
{
|
||||
text.baseAddr = 0;
|
||||
text.size = len;
|
||||
text.fileImage = fileData;
|
||||
|
||||
data.baseAddr = 0;
|
||||
data.size = 0;
|
||||
data.fileImage = NULL;
|
||||
|
||||
bss.baseAddr = 0;
|
||||
bss.size = 0;
|
||||
bss.fileImage = NULL;
|
||||
|
||||
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
|
||||
RawObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||
{
|
||||
/* int fnameStart = filename.rfind('/',filename.size()) + 1;
|
||||
int extStart = filename.rfind('.',filename.size());
|
||||
symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart,
|
||||
extStart-fnameStart) + "_start");*/
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RawObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||
{
|
||||
/* int fnameStart = filename.rfind('/',filename.size()) + 1;
|
||||
int extStart = filename.rfind('.',filename.size());
|
||||
symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart,
|
||||
extStart-fnameStart) + "_start");*/
|
||||
return true;
|
||||
}
|
||||
55
simulators/gem5/src/base/loader/raw_object.hh
Normal file
55
simulators/gem5/src/base/loader/raw_object.hh
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __BASE_LOADER_RAW_OBJECT_HH__
|
||||
#define __BASE_LOADER_RAW_OBJECT_HH__
|
||||
|
||||
#include "base/loader/object_file.hh"
|
||||
|
||||
class RawObject: public ObjectFile
|
||||
{
|
||||
protected:
|
||||
RawObject(const std::string &_filename, int _fd, size_t _len,
|
||||
uint8_t *_data, Arch _arch, OpSys _opSys);
|
||||
public:
|
||||
virtual ~RawObject() {}
|
||||
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||
std::numeric_limits<Addr>::max());
|
||||
|
||||
static ObjectFile *tryFile(const std::string &fname, int fd, size_t len,
|
||||
uint8_t *data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __BASE_LOADER_RAW_OBJECT_HH__
|
||||
139
simulators/gem5/src/base/loader/symtab.cc
Normal file
139
simulators/gem5/src/base/loader/symtab.cc
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/str.hh"
|
||||
#include "base/types.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SymbolTable *debugSymbolTable = NULL;
|
||||
|
||||
void
|
||||
SymbolTable::clear()
|
||||
{
|
||||
addrTable.clear();
|
||||
symbolTable.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
SymbolTable::insert(Addr address, string symbol)
|
||||
{
|
||||
if (symbol.empty())
|
||||
return false;
|
||||
|
||||
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)
|
||||
fatal("file error: Can't open symbol table file %s\n", filename);
|
||||
|
||||
while (!file.eof()) {
|
||||
getline(file, buffer);
|
||||
if (buffer.empty())
|
||||
continue;
|
||||
|
||||
string::size_type 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;
|
||||
}
|
||||
|
||||
void
|
||||
SymbolTable::serialize(const string &base, ostream &os)
|
||||
{
|
||||
paramOut(os, base + ".size", addrTable.size());
|
||||
|
||||
int i = 0;
|
||||
ATable::const_iterator p, end = addrTable.end();
|
||||
for (p = addrTable.begin(); p != end; ++p) {
|
||||
paramOut(os, csprintf("%s.addr_%d", base, i), p->first);
|
||||
paramOut(os, csprintf("%s.symbol_%d", base, i), p->second);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SymbolTable::unserialize(const string &base, Checkpoint *cp,
|
||||
const string §ion)
|
||||
{
|
||||
clear();
|
||||
int size;
|
||||
paramIn(cp, section, base + ".size", size);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
Addr addr;
|
||||
std::string symbol;
|
||||
|
||||
paramIn(cp, section, csprintf("%s.addr_%d", base, i), addr);
|
||||
paramIn(cp, section, csprintf("%s.symbol_%d", base, i), symbol);
|
||||
insert(addr, symbol);
|
||||
}
|
||||
}
|
||||
177
simulators/gem5/src/base/loader/symtab.hh
Normal file
177
simulators/gem5/src/base/loader/symtab.hh
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __SYMTAB_HH__
|
||||
#define __SYMTAB_HH__
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class SymbolTable
|
||||
{
|
||||
public:
|
||||
typedef std::map<Addr, std::string> ATable;
|
||||
typedef std::map<std::string, Addr> STable;
|
||||
|
||||
private:
|
||||
ATable addrTable;
|
||||
STable symbolTable;
|
||||
|
||||
private:
|
||||
bool
|
||||
upperBound(Addr addr, ATable::const_iterator &iter) const
|
||||
{
|
||||
// find first key *larger* than desired address
|
||||
iter = addrTable.upper_bound(addr);
|
||||
|
||||
// if very first key is larger, we're out of luck
|
||||
if (iter == addrTable.begin())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
SymbolTable() {}
|
||||
SymbolTable(const std::string &file) { load(file); }
|
||||
~SymbolTable() {}
|
||||
|
||||
void clear();
|
||||
bool insert(Addr address, std::string symbol);
|
||||
bool load(const std::string &file);
|
||||
|
||||
const ATable &getAddrTable() const { return addrTable; }
|
||||
const STable &getSymbolTable() const { return symbolTable; }
|
||||
|
||||
public:
|
||||
void serialize(const std::string &base, std::ostream &os);
|
||||
void unserialize(const std::string &base, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
|
||||
public:
|
||||
bool
|
||||
findSymbol(Addr address, std::string &symbol) const
|
||||
{
|
||||
ATable::const_iterator i = addrTable.find(address);
|
||||
if (i == addrTable.end())
|
||||
return false;
|
||||
|
||||
symbol = (*i).second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
findAddress(const std::string &symbol, Addr &address) const
|
||||
{
|
||||
STable::const_iterator i = symbolTable.find(symbol);
|
||||
if (i == symbolTable.end())
|
||||
return false;
|
||||
|
||||
address = (*i).second;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Find the nearest symbol equal to or less than the supplied
|
||||
/// address (e.g., the label for the enclosing function).
|
||||
/// @param addr The address to look up.
|
||||
/// @param symbol Return reference for symbol string.
|
||||
/// @param symaddr Return reference for symbol address.
|
||||
/// @param nextaddr Address of following symbol (for
|
||||
/// determining valid range of symbol).
|
||||
/// @retval True if a symbol was found.
|
||||
bool
|
||||
findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr,
|
||||
Addr &nextaddr) const
|
||||
{
|
||||
ATable::const_iterator i;
|
||||
if (!upperBound(addr, i))
|
||||
return false;
|
||||
|
||||
nextaddr = i->first;
|
||||
--i;
|
||||
symaddr = i->first;
|
||||
symbol = i->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Overload for findNearestSymbol() for callers who don't care
|
||||
/// about nextaddr.
|
||||
bool
|
||||
findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr) const
|
||||
{
|
||||
ATable::const_iterator i;
|
||||
if (!upperBound(addr, i))
|
||||
return false;
|
||||
|
||||
--i;
|
||||
symaddr = i->first;
|
||||
symbol = i->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
findNearestAddr(Addr addr, Addr &symaddr, Addr &nextaddr) const
|
||||
{
|
||||
ATable::const_iterator i;
|
||||
if (!upperBound(addr, i))
|
||||
return false;
|
||||
|
||||
nextaddr = i->first;
|
||||
--i;
|
||||
symaddr = i->first;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
findNearestAddr(Addr addr, Addr &symaddr) const
|
||||
{
|
||||
ATable::const_iterator i;
|
||||
if (!upperBound(addr, i))
|
||||
return false;
|
||||
|
||||
--i;
|
||||
symaddr = i->first;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// Global unified debugging symbol table (for target). Conceptually
|
||||
/// there should be one of these per System object for full system,
|
||||
/// and per Process object for non-full-system, but so far one big
|
||||
/// global one has worked well enough.
|
||||
extern SymbolTable *debugSymbolTable;
|
||||
|
||||
#endif // __SYMTAB_HH__
|
||||
98
simulators/gem5/src/base/match.cc
Normal file
98
simulators/gem5/src/base/match.cc
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include "base/match.hh"
|
||||
#include "base/str.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ObjectMatch::ObjectMatch()
|
||||
{
|
||||
}
|
||||
|
||||
ObjectMatch::ObjectMatch(const string &expr)
|
||||
{
|
||||
setExpression(expr);
|
||||
}
|
||||
|
||||
void
|
||||
ObjectMatch::setExpression(const string &expr)
|
||||
{
|
||||
tokens.resize(1);
|
||||
tokenize(tokens[0], expr, '.');
|
||||
}
|
||||
|
||||
void
|
||||
ObjectMatch::setExpression(const vector<string> &expr)
|
||||
{
|
||||
if (expr.empty()) {
|
||||
tokens.resize(0);
|
||||
} else {
|
||||
tokens.resize(expr.size());
|
||||
for (vector<string>::size_type i = 0; i < expr.size(); ++i)
|
||||
tokenize(tokens[i], expr[i], '.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo this should probably be changed to just use regular
|
||||
* expression code
|
||||
*/
|
||||
bool
|
||||
ObjectMatch::domatch(const string &name) const
|
||||
{
|
||||
vector<string> name_tokens;
|
||||
tokenize(name_tokens, name, '.');
|
||||
int ntsize = name_tokens.size();
|
||||
|
||||
int num_expr = tokens.size();
|
||||
for (int i = 0; i < num_expr; ++i) {
|
||||
const vector<string> &token = tokens[i];
|
||||
int jstop = token.size();
|
||||
|
||||
bool match = true;
|
||||
for (int j = 0; j < jstop; ++j) {
|
||||
if (j >= ntsize)
|
||||
break;
|
||||
|
||||
const string &var = token[j];
|
||||
if (var != "*" && var != name_tokens[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match == true)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
59
simulators/gem5/src/base/match.hh
Normal file
59
simulators/gem5/src/base/match.hh
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
/* @file
|
||||
* User Console Definitions
|
||||
*/
|
||||
|
||||
#ifndef __BASE_MATCH_HH__
|
||||
#define __BASE_MATCH_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ObjectMatch
|
||||
{
|
||||
protected:
|
||||
std::vector<std::vector<std::string> > tokens;
|
||||
bool domatch(const std::string &name) const;
|
||||
|
||||
public:
|
||||
ObjectMatch();
|
||||
ObjectMatch(const std::string &expression);
|
||||
void setExpression(const std::string &expression);
|
||||
void setExpression(const std::vector<std::string> &expression);
|
||||
bool match(const std::string &name) const
|
||||
{
|
||||
return tokens.empty() ? false : domatch(name);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __BASE_MATCH_HH__
|
||||
|
||||
116
simulators/gem5/src/base/misc.cc
Normal file
116
simulators/gem5/src/base/misc.cc
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/hostinfo.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/output.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "base/types.hh"
|
||||
#include "base/varargs.hh"
|
||||
#include "sim/core.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool want_warn = true;
|
||||
bool want_info = true;
|
||||
bool want_hack = true;
|
||||
|
||||
bool warn_verbose = false;
|
||||
bool info_verbose = false;
|
||||
bool hack_verbose = false;
|
||||
|
||||
void
|
||||
__exit_message(const char *prefix, int code,
|
||||
const char *func, const char *file, int line,
|
||||
const char *fmt, CPRINTF_DEFINITION)
|
||||
{
|
||||
CPrintfArgsList args(VARARGS_ALLARGS);
|
||||
|
||||
string format = prefix;
|
||||
format += ": ";
|
||||
format += fmt;
|
||||
switch (format[format.size() - 1]) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
format += "\n";
|
||||
}
|
||||
|
||||
format += " @ cycle %d\n[%s:%s, line %d]\n";
|
||||
format += "Memory Usage: %ld KBytes\n";
|
||||
|
||||
args.push_back(curTick());
|
||||
args.push_back(func);
|
||||
args.push_back(file);
|
||||
args.push_back(line);
|
||||
args.push_back(memUsage());
|
||||
|
||||
ccprintf(cerr, format.c_str(), args);
|
||||
|
||||
if (code < 0)
|
||||
abort();
|
||||
else
|
||||
exit(code);
|
||||
}
|
||||
|
||||
void
|
||||
__base_message(std::ostream &stream, const char *prefix, bool verbose,
|
||||
const char *func, const char *file, int line,
|
||||
const char *fmt, CPRINTF_DEFINITION)
|
||||
{
|
||||
CPrintfArgsList args(VARARGS_ALLARGS);
|
||||
|
||||
string format = prefix;
|
||||
format += ": ";
|
||||
format += fmt;
|
||||
switch (format[format.size() - 1]) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
format += "\n";
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
format += " @ cycle %d\n[%s:%s, line %d]\n";
|
||||
args.push_back(curTick());
|
||||
args.push_back(func);
|
||||
args.push_back(file);
|
||||
args.push_back(line);
|
||||
}
|
||||
|
||||
ccprintf(stream, format.c_str(), args);
|
||||
}
|
||||
150
simulators/gem5/src/base/misc.hh
Normal file
150
simulators/gem5/src/base/misc.hh
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Dave Greene
|
||||
*/
|
||||
|
||||
#ifndef __BASE_MISC_HH__
|
||||
#define __BASE_MISC_HH__
|
||||
|
||||
#include "base/compiler.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/varargs.hh"
|
||||
|
||||
#if defined(__SUNPRO_CC)
|
||||
#define __FUNCTION__ "how to fix me?"
|
||||
#endif
|
||||
|
||||
// General exit message, these functions will never return and will
|
||||
// either abort() if code is < 0 or exit with the code if >= 0
|
||||
void __exit_message(const char *prefix, int code,
|
||||
const char *func, const char *file, int line,
|
||||
const char *format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;
|
||||
|
||||
void __exit_message(const char *prefix, int code,
|
||||
const char *func, const char *file, int line,
|
||||
const std::string &format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;
|
||||
|
||||
inline void
|
||||
__exit_message(const char *prefix, int code,
|
||||
const char *func, const char *file, int line,
|
||||
const std::string& format, CPRINTF_DEFINITION)
|
||||
{
|
||||
__exit_message(prefix, code, func, file, line, format.c_str(),
|
||||
VARARGS_ALLARGS);
|
||||
}
|
||||
|
||||
M5_PRAGMA_NORETURN(__exit_message)
|
||||
#define exit_message(prefix, code, ...) \
|
||||
__exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__, \
|
||||
__VA_ARGS__)
|
||||
|
||||
//
|
||||
// This implements a cprintf based panic() function. panic() should
|
||||
// be called when something happens that should never ever happen
|
||||
// regardless of what the user does (i.e., an acutal m5 bug). panic()
|
||||
// calls abort which can dump core or enter the debugger.
|
||||
//
|
||||
//
|
||||
#define panic(...) exit_message("panic", -1, __VA_ARGS__)
|
||||
|
||||
//
|
||||
// This implements a cprintf based fatal() function. fatal() should
|
||||
// be called when the simulation cannot continue due to some condition
|
||||
// that is the user's fault (bad configuration, invalid arguments,
|
||||
// etc.) and not a simulator bug. fatal() calls exit(1), i.e., a
|
||||
// "normal" exit with an error code, as opposed to abort() like
|
||||
// panic() does.
|
||||
//
|
||||
#define fatal(...) exit_message("fatal", 1, __VA_ARGS__)
|
||||
|
||||
void
|
||||
__base_message(std::ostream &stream, const char *prefix, bool verbose,
|
||||
const char *func, const char *file, int line,
|
||||
const char *format, CPRINTF_DECLARATION);
|
||||
|
||||
inline void
|
||||
__base_message(std::ostream &stream, const char *prefix, bool verbose,
|
||||
const char *func, const char *file, int line,
|
||||
const std::string &format, CPRINTF_DECLARATION)
|
||||
{
|
||||
__base_message(stream, prefix, verbose, func, file, line, format.c_str(),
|
||||
VARARGS_ALLARGS);
|
||||
}
|
||||
|
||||
#define base_message(stream, prefix, verbose, ...) \
|
||||
__base_message(stream, prefix, verbose, __FUNCTION__, __FILE__, __LINE__, \
|
||||
__VA_ARGS__)
|
||||
|
||||
// Only print the message the first time this expression is
|
||||
// encountered. i.e. This doesn't check the string itself and
|
||||
// prevent duplicate strings, this prevents the statement from
|
||||
// happening more than once. So, even if the arguments change and that
|
||||
// would have resulted in a different message thoes messages would be
|
||||
// supressed.
|
||||
#define base_message_once(...) do { \
|
||||
static bool once = false; \
|
||||
if (!once) { \
|
||||
base_message(__VA_ARGS__); \
|
||||
once = true; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define cond_message(cond, ...) do { \
|
||||
if (cond) \
|
||||
base_message(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define cond_message_once(cond, ...) do { \
|
||||
static bool once = false; \
|
||||
if (!once && cond) { \
|
||||
base_message(__VA_ARGS__); \
|
||||
once = true; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
extern bool want_warn, warn_verbose;
|
||||
extern bool want_info, info_verbose;
|
||||
extern bool want_hack, hack_verbose;
|
||||
|
||||
#define warn(...) \
|
||||
cond_message(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
|
||||
#define inform(...) \
|
||||
cond_message(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
|
||||
#define hack(...) \
|
||||
cond_message(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)
|
||||
|
||||
#define warn_once(...) \
|
||||
cond_message_once(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
|
||||
#define inform_once(...) \
|
||||
cond_message_once(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
|
||||
#define hack_once(...) \
|
||||
cond_message_once(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)
|
||||
|
||||
#endif // __BASE_MISC_HH__
|
||||
203
simulators/gem5/src/base/mod_num.hh
Normal file
203
simulators/gem5/src/base/mod_num.hh
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Steve Raasch
|
||||
*/
|
||||
|
||||
template<class T, T MV>
|
||||
class ModNum {
|
||||
private:
|
||||
T value;
|
||||
|
||||
// Compiler should optimize this
|
||||
void setValue(T n) { value = n % MV; }
|
||||
|
||||
public:
|
||||
ModNum() {}
|
||||
ModNum(T n) { setValue(n); }
|
||||
ModNum(const ModNum<T, MV> &n) : value(n.value) {}
|
||||
|
||||
ModNum operator=(T n) {
|
||||
setValue(n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const ModNum operator=(ModNum n) {
|
||||
value = n.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return the value if object used as RHS
|
||||
operator T() const { return value; }
|
||||
|
||||
//
|
||||
// Operator "+="
|
||||
//
|
||||
const ModNum<T, MV> operator+=(ModNum<T, MV> r) {
|
||||
setValue(value + r.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const ModNum<T, MV> operator+=(T r) {
|
||||
setValue(value + r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// Operator "-="
|
||||
//
|
||||
const ModNum<T, MV> operator-=(ModNum<T, MV> r) {
|
||||
setValue(value - r.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const ModNum<T, MV> operator-=(T r) {
|
||||
setValue(value - r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// Operator "++"
|
||||
//
|
||||
// PREFIX (like ++a)
|
||||
const ModNum<T, MV> operator++() {
|
||||
*this += 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// POSTFIX (like a++)
|
||||
const ModNum<T, MV> operator++(int) {
|
||||
ModNum<T, MV> rv = *this;
|
||||
|
||||
*this += 1;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
// Operator "--"
|
||||
//
|
||||
// PREFIX (like --a)
|
||||
const ModNum<T, MV> operator--() {
|
||||
*this -= 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// POSTFIX (like a--)
|
||||
const ModNum<T, MV> operator--(int) {
|
||||
ModNum<T, MV> rv = *this;
|
||||
*this -= 1;
|
||||
return rv;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Define operator "+" like this to avoid creating a temporary
|
||||
//
|
||||
template<class T, T MV>
|
||||
inline ModNum<T, MV>
|
||||
operator+(ModNum<T, MV> l, ModNum<T, MV> r) {
|
||||
l += r;
|
||||
return l;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline ModNum<T, MV>
|
||||
operator+(ModNum<T, MV> l, T r) {
|
||||
l += r;
|
||||
return l;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline ModNum<T, MV>
|
||||
operator+(T l, ModNum<T, MV> r) {
|
||||
r += l;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Define operator "-" like this to avoid creating a temporary
|
||||
//
|
||||
template<class T, T MV>
|
||||
inline ModNum<T, MV>
|
||||
operator-(ModNum<T, MV> l, ModNum<T, MV> r) {
|
||||
l -= r;
|
||||
return l;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline ModNum<T, MV>
|
||||
operator-(ModNum<T, MV> l, T r) {
|
||||
l -= r;
|
||||
return l;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline ModNum<T, MV>
|
||||
operator-(T l, ModNum<T, MV> r) {
|
||||
r -= l;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Comparison operators
|
||||
// (all other cases are handled with conversons)
|
||||
//
|
||||
template<class T, T MV>
|
||||
inline bool
|
||||
operator<(ModNum<T, MV> l, ModNum<T, MV> r) {
|
||||
return l.value < r.value;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline bool
|
||||
operator>(ModNum<T, MV> l, ModNum<T, MV> r) {
|
||||
return l.value > r.value;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline bool
|
||||
operator==(ModNum<T, MV> l, ModNum<T, MV> r) {
|
||||
return l.value == r.value;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline bool
|
||||
operator<=(ModNum<T, MV> l, ModNum<T, MV> r) {
|
||||
return l.value <= r.value;
|
||||
}
|
||||
|
||||
template<class T, T MV>
|
||||
inline bool
|
||||
operator>=(ModNum<T, MV> l, ModNum<T, MV> r) {
|
||||
return l.value >= r.value;
|
||||
}
|
||||
|
||||
|
||||
267
simulators/gem5/src/base/output.cc
Normal file
267
simulators/gem5/src/base/output.cc
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Chris Emmons
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
|
||||
#include <gzstream.hh>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "base/output.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
OutputDirectory simout;
|
||||
|
||||
/**
|
||||
* @file This file manages creating / deleting output files for the simulator.
|
||||
*/
|
||||
OutputDirectory::OutputDirectory()
|
||||
{}
|
||||
|
||||
OutputDirectory::~OutputDirectory()
|
||||
{
|
||||
for (map_t::iterator i = files.begin(); i != files.end(); i++) {
|
||||
if (i->second)
|
||||
delete i->second;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream *
|
||||
OutputDirectory::checkForStdio(const string &name) const
|
||||
{
|
||||
if (name == "cerr" || name == "stderr")
|
||||
return &cerr;
|
||||
|
||||
if (name == "cout" || name == "stdout")
|
||||
return &cout;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ostream *
|
||||
OutputDirectory::openFile(const string &filename,
|
||||
ios_base::openmode mode)
|
||||
{
|
||||
if (filename.find(".gz", filename.length()-3) < filename.length()) {
|
||||
ogzstream *file = new ogzstream(filename.c_str(), mode);
|
||||
if (!file->is_open())
|
||||
fatal("Cannot open file %s", filename);
|
||||
assert(files.find(filename) == files.end());
|
||||
files[filename] = file;
|
||||
return file;
|
||||
} else {
|
||||
ofstream *file = new ofstream(filename.c_str(), mode);
|
||||
if (!file->is_open())
|
||||
fatal("Cannot open file %s", filename);
|
||||
assert(files.find(filename) == files.end());
|
||||
files[filename] = file;
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OutputDirectory::close(ostream *openStream) {
|
||||
map_t::iterator i;
|
||||
for (i = files.begin(); i != files.end(); i++) {
|
||||
if (i->second != openStream)
|
||||
continue;
|
||||
|
||||
ofstream *fs = dynamic_cast<ofstream*>(i->second);
|
||||
if (fs) {
|
||||
fs->close();
|
||||
delete i->second;
|
||||
break;
|
||||
} else {
|
||||
ogzstream *gfs = dynamic_cast<ogzstream*>(i->second);
|
||||
if (gfs) {
|
||||
gfs->close();
|
||||
delete i->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == files.end())
|
||||
fatal("Attempted to close an unregistred file stream");
|
||||
|
||||
files.erase(i);
|
||||
}
|
||||
|
||||
void
|
||||
OutputDirectory::setDirectory(const string &d)
|
||||
{
|
||||
if (!dir.empty())
|
||||
panic("Output directory already set!\n");
|
||||
|
||||
dir = d;
|
||||
|
||||
// guarantee that directory ends with a path separator
|
||||
if (dir[dir.size() - 1] != PATH_SEPARATOR)
|
||||
dir += PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
const string &
|
||||
OutputDirectory::directory() const
|
||||
{
|
||||
if (dir.empty())
|
||||
panic("Output directory not set!");
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
inline string
|
||||
OutputDirectory::resolve(const string &name) const
|
||||
{
|
||||
return (name[0] != PATH_SEPARATOR) ? dir + name : name;
|
||||
}
|
||||
|
||||
ostream *
|
||||
OutputDirectory::create(const string &name, bool binary)
|
||||
{
|
||||
ostream *file = checkForStdio(name);
|
||||
if (file)
|
||||
return file;
|
||||
|
||||
string filename = resolve(name);
|
||||
ios_base::openmode mode =
|
||||
ios::trunc | (binary ? ios::binary : (ios::openmode)0);
|
||||
file = openFile(filename, mode);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
ostream *
|
||||
OutputDirectory::find(const string &name) const
|
||||
{
|
||||
ostream *file = checkForStdio(name);
|
||||
if (file)
|
||||
return file;
|
||||
|
||||
const string filename = resolve(name);
|
||||
map_t::const_iterator i = files.find(filename);
|
||||
if (i != files.end())
|
||||
return (*i).second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
OutputDirectory::isFile(const std::ostream *os)
|
||||
{
|
||||
return os && os != &cerr && os != &cout;
|
||||
}
|
||||
|
||||
bool
|
||||
OutputDirectory::isFile(const string &name) const
|
||||
{
|
||||
// definitely a file if in our data structure
|
||||
if (find(name) != NULL) return true;
|
||||
|
||||
struct stat st_buf;
|
||||
int st = stat(name.c_str(), &st_buf);
|
||||
return (st == 0) && S_ISREG(st_buf.st_mode);
|
||||
}
|
||||
|
||||
string
|
||||
OutputDirectory::createSubdirectory(const string &name) const
|
||||
{
|
||||
const string new_dir = resolve(name);
|
||||
if (new_dir.find(directory()) == string::npos)
|
||||
fatal("Attempting to create subdirectory not in m5 output dir\n");
|
||||
|
||||
// if it already exists, that's ok; otherwise, fail if we couldn't create
|
||||
if ((mkdir(new_dir.c_str(), 0755) != 0) && (errno != EEXIST))
|
||||
fatal("Failed to create new output subdirectory '%s'\n", new_dir);
|
||||
|
||||
return name + PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
void
|
||||
OutputDirectory::remove(const string &name, bool recursive)
|
||||
{
|
||||
const string fname = resolve(name);
|
||||
|
||||
if (fname.find(directory()) == string::npos)
|
||||
fatal("Attempting to remove file/dir not in output dir\n");
|
||||
|
||||
if (isFile(fname)) {
|
||||
// close and release file if we have it open
|
||||
map_t::iterator itr = files.find(fname);
|
||||
if (itr != files.end()) {
|
||||
delete itr->second;
|
||||
files.erase(itr);
|
||||
}
|
||||
|
||||
if (::remove(fname.c_str()) != 0)
|
||||
fatal("Could not erase file '%s'\n", fname);
|
||||
} else {
|
||||
// assume 'name' is a directory
|
||||
if (recursive) {
|
||||
DIR *dir = opendir(fname.c_str());
|
||||
|
||||
// silently ignore removal request for non-existent directory
|
||||
if ((!dir) && (errno == ENOENT))
|
||||
return;
|
||||
|
||||
// fail on other errors
|
||||
if (!dir) {
|
||||
perror("opendir");
|
||||
fatal("Error opening directory for recursive removal '%s'\n",
|
||||
fname);
|
||||
}
|
||||
|
||||
struct dirent *de = readdir(dir);
|
||||
while (de != NULL) {
|
||||
// ignore files starting with a '.'; user must delete those
|
||||
// manually if they really want to
|
||||
if (de->d_name[0] != '.')
|
||||
remove(name + PATH_SEPARATOR + de->d_name, recursive);
|
||||
|
||||
de = readdir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
// try to force recognition that we deleted the files in the directory
|
||||
sync();
|
||||
|
||||
if (::remove(fname.c_str()) != 0) {
|
||||
perror("Warning! 'remove' failed. Could not erase directory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
184
simulators/gem5/src/base/output.hh
Normal file
184
simulators/gem5/src/base/output.hh
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Chris Emmons
|
||||
*/
|
||||
|
||||
#ifndef __BASE_OUTPUT_HH__
|
||||
#define __BASE_OUTPUT_HH__
|
||||
|
||||
#include <ios>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
/** Interface for creating files in a gem5 output directory. */
|
||||
class OutputDirectory
|
||||
{
|
||||
private:
|
||||
/** File names and associated stream handles */
|
||||
typedef std::map<std::string, std::ostream *> map_t;
|
||||
|
||||
/** Open file streams within this directory */
|
||||
map_t files;
|
||||
|
||||
/** Name of this directory */
|
||||
std::string dir;
|
||||
|
||||
/** System-specific path separator character */
|
||||
static const char PATH_SEPARATOR = '/';
|
||||
|
||||
/**
|
||||
* Returns relative file names prepended with name of this directory.
|
||||
* Returns absolute file names unaltered.
|
||||
*
|
||||
* @param name file name to prepend with directory name
|
||||
* @return file name prepended with base directory name or unaltered
|
||||
* absolute file name
|
||||
*/
|
||||
std::string resolve(const std::string &name) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Determines whether given file name corresponds to standard output
|
||||
* streams.
|
||||
*
|
||||
* @param name name of file to check
|
||||
* @return output stream for standard output or error stream if name
|
||||
* corresponds to one or the other; NULL otherwise
|
||||
*/
|
||||
std::ostream *checkForStdio(const std::string &name) const;
|
||||
|
||||
public:
|
||||
/** Constructor. */
|
||||
OutputDirectory();
|
||||
|
||||
/** Destructor. */
|
||||
~OutputDirectory();
|
||||
|
||||
/** Opens a file (optionally compressed).
|
||||
*
|
||||
* Will open a file as a compressed stream if filename ends in .gz.
|
||||
*
|
||||
* @param filename file to open
|
||||
* @param mode attributes to open file with
|
||||
* @return stream pointer to opened file; will cause sim fail on error
|
||||
*/
|
||||
std::ostream *openFile(const std::string &filename,
|
||||
std::ios_base::openmode mode = std::ios::trunc);
|
||||
|
||||
/**
|
||||
* Sets name of this directory.
|
||||
* @param dir name of this directory
|
||||
*/
|
||||
void setDirectory(const std::string &dir);
|
||||
|
||||
/**
|
||||
* Gets name of this directory.
|
||||
* @return name of this directory
|
||||
*/
|
||||
const std::string &directory() const;
|
||||
|
||||
/**
|
||||
* Creates a file in this directory (optionally compressed).
|
||||
*
|
||||
* Will open a file as a compressed stream if filename ends in .gz.
|
||||
*
|
||||
* @param name name of file to create (without this directory's name
|
||||
* leading it)
|
||||
* @param binary true to create a binary file; false otherwise
|
||||
* @return stream to the opened file
|
||||
*/
|
||||
std::ostream *create(const std::string &name, bool binary = false);
|
||||
|
||||
/**
|
||||
* Closes a file stream.
|
||||
*
|
||||
* Stream must have been opened through this interface, or sim will fail.
|
||||
*
|
||||
* @param openStream open stream to close
|
||||
*/
|
||||
void close(std::ostream *openStream);
|
||||
|
||||
/**
|
||||
* Finds stream associated with a file.
|
||||
* @param name of file
|
||||
* @return stream to specified file or NULL if file does not exist
|
||||
*/
|
||||
std::ostream *find(const std::string &name) const;
|
||||
|
||||
/**
|
||||
* Returns true if stream is open and not standard output or error.
|
||||
* @param os output stream to evaluate
|
||||
* @return true if os is non-NULL and not cout or cerr
|
||||
*/
|
||||
static bool isFile(const std::ostream *os);
|
||||
|
||||
/**
|
||||
* Determines whether a file name corresponds to a file in this directory.
|
||||
* @param name name of file to evaluate
|
||||
* @return true iff file has been opened in this directory or exists on the
|
||||
* file system within this directory
|
||||
*/
|
||||
bool isFile(const std::string &name) const;
|
||||
|
||||
/**
|
||||
* Returns true if stream is open and not standard output or error.
|
||||
* @param os output stream to evaluate
|
||||
* @return true if os is non-NULL and not cout or cerr
|
||||
*/
|
||||
static inline bool isFile(const std::ostream &os) {
|
||||
return isFile(&os);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a subdirectory within this directory.
|
||||
* @param name name of subdirectory
|
||||
* @return the new subdirectory's name suffixed with a path separator
|
||||
*/
|
||||
std::string createSubdirectory(const std::string &name) const;
|
||||
|
||||
/**
|
||||
* Removes a specified file or subdirectory.
|
||||
*
|
||||
* Will cause sim to fail for most errors. However, it will only warn the
|
||||
* user if a directory could not be removed. This is in place to
|
||||
* accommodate slow file systems where file deletions within a subdirectory
|
||||
* may not be recognized quickly enough thereby causing the subsequent call
|
||||
* to remove the directory to fail (seemingly unempty directory).
|
||||
*
|
||||
* @param name name of file or subdirectory to remove; name should not
|
||||
* be prepended with the name of this directory object
|
||||
* @param recursive set to true to attempt to recursively delete a
|
||||
* subdirectory and its contents
|
||||
*/
|
||||
void remove(const std::string &name, bool recursive=false);
|
||||
};
|
||||
|
||||
extern OutputDirectory simout;
|
||||
|
||||
#endif // __BASE_OUTPUT_HH__
|
||||
279
simulators/gem5/src/base/pollevent.cc
Normal file
279
simulators/gem5/src/base/pollevent.cc
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#if defined(__sun__) || defined(__SUNPRO_CC)
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <csignal>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "base/pollevent.hh"
|
||||
#include "base/types.hh"
|
||||
#include "sim/async.hh"
|
||||
#include "sim/core.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
PollQueue pollQueue;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
PollEvent::PollEvent(int _fd, int _events)
|
||||
: queue(NULL), enabled(true)
|
||||
{
|
||||
pfd.fd = _fd;
|
||||
pfd.events = _events;
|
||||
}
|
||||
|
||||
PollEvent::~PollEvent()
|
||||
{
|
||||
if (queue)
|
||||
queue->remove(this);
|
||||
}
|
||||
|
||||
void
|
||||
PollEvent::disable()
|
||||
{
|
||||
if (!enabled) return;
|
||||
enabled = false;
|
||||
|
||||
if (queue)
|
||||
queue->copy();
|
||||
}
|
||||
|
||||
void
|
||||
PollEvent::enable()
|
||||
{
|
||||
if (enabled) return;
|
||||
enabled = true;
|
||||
|
||||
if (queue)
|
||||
queue->copy();
|
||||
}
|
||||
|
||||
void
|
||||
PollEvent::serialize(ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(pfd.fd);
|
||||
SERIALIZE_SCALAR(pfd.events);
|
||||
SERIALIZE_SCALAR(enabled);
|
||||
}
|
||||
|
||||
void
|
||||
PollEvent::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(pfd.fd);
|
||||
UNSERIALIZE_SCALAR(pfd.events);
|
||||
UNSERIALIZE_SCALAR(enabled);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
PollQueue::PollQueue()
|
||||
: poll_fds(NULL), max_size(0), num_fds(0)
|
||||
{ }
|
||||
|
||||
PollQueue::~PollQueue()
|
||||
{
|
||||
removeHandler();
|
||||
for (int i = 0; i < num_fds; i++)
|
||||
setupAsyncIO(poll_fds[0].fd, false);
|
||||
|
||||
delete [] poll_fds;
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::copy()
|
||||
{
|
||||
eventvec_t::iterator i = events.begin();
|
||||
eventvec_t::iterator end = events.end();
|
||||
|
||||
num_fds = 0;
|
||||
|
||||
while (i < end) {
|
||||
if ((*i)->enabled)
|
||||
poll_fds[num_fds++] = (*i)->pfd;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::remove(PollEvent *event)
|
||||
{
|
||||
eventvec_t::iterator i = events.begin();
|
||||
eventvec_t::iterator end = events.end();
|
||||
|
||||
while (i < end) {
|
||||
if (*i == event) {
|
||||
events.erase(i);
|
||||
copy();
|
||||
event->queue = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
panic("Event does not exist. Cannot remove.");
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::schedule(PollEvent *event)
|
||||
{
|
||||
if (event->queue)
|
||||
panic("Event already scheduled!");
|
||||
|
||||
event->queue = this;
|
||||
events.push_back(event);
|
||||
setupAsyncIO(event->pfd.fd, true);
|
||||
|
||||
// if we ran out of space in the fd array, double the capacity
|
||||
// if this is the first time that we've scheduled an event, create
|
||||
// the array with an initial size of 16
|
||||
if (++num_fds > max_size) {
|
||||
if (max_size > 0) {
|
||||
delete [] poll_fds;
|
||||
max_size *= 2;
|
||||
} else {
|
||||
max_size = 16;
|
||||
setupHandler();
|
||||
}
|
||||
|
||||
poll_fds = new pollfd[max_size];
|
||||
}
|
||||
|
||||
copy();
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::service()
|
||||
{
|
||||
int ret = poll(poll_fds, num_fds, 0);
|
||||
|
||||
if (ret <= 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < num_fds; i++) {
|
||||
int revents = poll_fds[i].revents;
|
||||
if (revents) {
|
||||
events[i]->process(revents);
|
||||
if (--ret <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct sigaction PollQueue::oldio;
|
||||
struct sigaction PollQueue::oldalrm;
|
||||
bool PollQueue::handler = false;
|
||||
|
||||
void
|
||||
PollQueue::setupAsyncIO(int fd, bool set)
|
||||
{
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
if (flags == -1)
|
||||
panic("Could not set up async IO");
|
||||
|
||||
if (set)
|
||||
flags |= FASYNC;
|
||||
else
|
||||
flags &= ~(FASYNC);
|
||||
|
||||
if (fcntl(fd, F_SETFL, flags) == -1)
|
||||
panic("Could not set up async IO");
|
||||
|
||||
if (set) {
|
||||
if (fcntl(fd, F_SETOWN, getpid()) == -1)
|
||||
panic("Could not set up async IO");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::setupHandler()
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = handleIO;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_RESTART;
|
||||
|
||||
if (sigaction(SIGIO, &act, &oldio) == -1)
|
||||
panic("could not do sigaction");
|
||||
|
||||
act.sa_handler = handleALRM;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_RESTART;
|
||||
|
||||
if (sigaction(SIGALRM, &act, &oldalrm) == -1)
|
||||
panic("could not do sigaction");
|
||||
|
||||
alarm(1);
|
||||
|
||||
handler = true;
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::removeHandler()
|
||||
{
|
||||
if (sigaction(SIGIO, &oldio, NULL) == -1)
|
||||
panic("could not remove handler");
|
||||
|
||||
if (sigaction(SIGIO, &oldalrm, NULL) == -1)
|
||||
panic("could not remove handler");
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::handleIO(int sig)
|
||||
{
|
||||
if (sig != SIGIO)
|
||||
panic("Wrong Handler");
|
||||
|
||||
async_event = true;
|
||||
async_io = true;
|
||||
}
|
||||
|
||||
void
|
||||
PollQueue::handleALRM(int sig)
|
||||
{
|
||||
if (sig != SIGALRM)
|
||||
panic("Wrong Handler");
|
||||
|
||||
async_event = true;
|
||||
async_alarm = true;
|
||||
alarm(1);
|
||||
}
|
||||
|
||||
101
simulators/gem5/src/base/pollevent.hh
Normal file
101
simulators/gem5/src/base/pollevent.hh
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __POLLEVENT_H__
|
||||
#define __POLLEVENT_H__
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "sim/core.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class PollQueue;
|
||||
|
||||
class PollEvent
|
||||
{
|
||||
private:
|
||||
friend class PollQueue;
|
||||
|
||||
protected:
|
||||
pollfd pfd;
|
||||
PollQueue *queue;
|
||||
bool enabled;
|
||||
|
||||
public:
|
||||
PollEvent(int fd, int event);
|
||||
virtual ~PollEvent();
|
||||
|
||||
void disable();
|
||||
void enable();
|
||||
virtual void process(int revent) = 0;
|
||||
|
||||
bool queued() { return queue != 0; }
|
||||
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
class PollQueue
|
||||
{
|
||||
private:
|
||||
typedef std::vector<PollEvent *> eventvec_t;
|
||||
eventvec_t events;
|
||||
|
||||
pollfd *poll_fds;
|
||||
int max_size;
|
||||
int num_fds;
|
||||
|
||||
public:
|
||||
PollQueue();
|
||||
~PollQueue();
|
||||
|
||||
void copy();
|
||||
void remove(PollEvent *event);
|
||||
void schedule(PollEvent *event);
|
||||
void service();
|
||||
|
||||
protected:
|
||||
static bool handler;
|
||||
static struct sigaction oldio;
|
||||
static struct sigaction oldalrm;
|
||||
|
||||
public:
|
||||
static void setupAsyncIO(int fd, bool set);
|
||||
static void handleIO(int);
|
||||
static void handleALRM(int);
|
||||
static void removeHandler();
|
||||
static void setupHandler();
|
||||
};
|
||||
|
||||
extern PollQueue pollQueue;
|
||||
|
||||
#endif // __POLLEVENT_H__
|
||||
55
simulators/gem5/src/base/printable.hh
Normal file
55
simulators/gem5/src/base/printable.hh
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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
|
||||
* Printable Object Base Class Declaration
|
||||
*/
|
||||
|
||||
#ifndef __PRINTABLE_HH__
|
||||
#define __PRINTABLE_HH__
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Abstract base class for objects which support being printed
|
||||
* to a stream for debugging. Primarily used to support PrintReq
|
||||
* in memory system.
|
||||
*/
|
||||
class Printable
|
||||
{
|
||||
public:
|
||||
Printable() {}
|
||||
virtual ~Printable() {}
|
||||
|
||||
virtual void print(std::ostream &os,
|
||||
int verbosity = 0,
|
||||
const std::string &prefix = "") const = 0;
|
||||
};
|
||||
|
||||
#endif // __PRINTABLE_HH__
|
||||
127
simulators/gem5/src/base/random.cc
Normal file
127
simulators/gem5/src/base/random.cc
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Ali Saidi
|
||||
*/
|
||||
|
||||
#include <limits>
|
||||
#include "base/fenv.hh"
|
||||
#include "base/intmath.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/random.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Random::Random()
|
||||
{
|
||||
// default random seed taken from original source
|
||||
init(5489);
|
||||
}
|
||||
|
||||
Random::Random(uint32_t s)
|
||||
{
|
||||
init(s);
|
||||
}
|
||||
|
||||
Random::Random(uint32_t init_key[], int key_length)
|
||||
{
|
||||
init(init_key, key_length);
|
||||
}
|
||||
|
||||
Random::~Random()
|
||||
{
|
||||
}
|
||||
|
||||
// To preserve the uniform random distribution between min and max,
|
||||
// and allow all numbers to be represented, we generate a uniform
|
||||
// random number to the nearest power of two greater than max. If
|
||||
// this number doesn't fall between 0 and max, we try again. Anything
|
||||
// else would skew the distribution.
|
||||
uint32_t
|
||||
Random::genrand(uint32_t max)
|
||||
{
|
||||
if (max == 0)
|
||||
return 0;
|
||||
if (max == std::numeric_limits<uint32_t>::max())
|
||||
return genrand();
|
||||
|
||||
int log = ceilLog2(max + 1);
|
||||
int shift = (sizeof(uint32_t) * 8 - log);
|
||||
uint32_t random;
|
||||
|
||||
do {
|
||||
random = genrand() >> shift;
|
||||
} while (random > max);
|
||||
|
||||
return random;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
Random::genrand(uint64_t max)
|
||||
{
|
||||
if (max == 0)
|
||||
return 0;
|
||||
if (max == std::numeric_limits<uint64_t>::max())
|
||||
return genrand();
|
||||
|
||||
int log = ceilLog2(max + 1);
|
||||
int shift = (sizeof(uint64_t) * 8 - log);
|
||||
uint64_t random;
|
||||
|
||||
do {
|
||||
random = (uint64_t)genrand() << 32 | (uint64_t)genrand();
|
||||
random = random >> shift;
|
||||
} while (random > max);
|
||||
|
||||
return random;
|
||||
}
|
||||
|
||||
void
|
||||
Random::serialize(const string &base, ostream &os)
|
||||
{
|
||||
int length = N;
|
||||
paramOut(os, base + ".mti", mti);
|
||||
paramOut(os, base + ".length", length);
|
||||
arrayParamOut(os, base + ".data", mt, length);
|
||||
}
|
||||
|
||||
void
|
||||
Random::unserialize(const string &base, Checkpoint *cp, const string §ion)
|
||||
{
|
||||
int length;
|
||||
|
||||
paramIn(cp, section, base + ".mti", mti);
|
||||
paramIn(cp, section, base + ".length", length);
|
||||
if (length != N)
|
||||
panic("cant unserialize random number data. length != %d\n", length);
|
||||
|
||||
arrayParamIn(cp, section, base + ".data", mt, length);
|
||||
}
|
||||
|
||||
Random random_mt;
|
||||
249
simulators/gem5/src/base/random.hh
Normal file
249
simulators/gem5/src/base/random.hh
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Ali Saidi
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mersenne Twister random number generator has a period of
|
||||
* 2^19937-1.
|
||||
*
|
||||
* The actual math is in its own file to keep the license clear.
|
||||
*/
|
||||
|
||||
#ifndef __BASE_RANDOM_HH__
|
||||
#define __BASE_RANDOM_HH__
|
||||
|
||||
#include <ios>
|
||||
#include <string>
|
||||
|
||||
#include "base/range.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
class Checkpoint;
|
||||
|
||||
class Random
|
||||
{
|
||||
protected:
|
||||
static const int N = 624;
|
||||
static const int M = 397;
|
||||
static const uint32_t MATRIX_A = (uint32_t)0x9908b0df;
|
||||
static const uint32_t UPPER_MASK = (uint32_t)0x80000000;
|
||||
static const uint32_t LOWER_MASK = (uint32_t)0x7fffffff;
|
||||
|
||||
uint32_t mt[N];
|
||||
int mti;
|
||||
|
||||
uint32_t genrand();
|
||||
uint32_t genrand(uint32_t max);
|
||||
uint64_t genrand(uint64_t max);
|
||||
|
||||
void
|
||||
_random(int8_t &value)
|
||||
{
|
||||
value = genrand() & (int8_t)-1;
|
||||
}
|
||||
|
||||
void
|
||||
_random(int16_t &value)
|
||||
{
|
||||
value = genrand() & (int16_t)-1;
|
||||
}
|
||||
|
||||
void
|
||||
_random(int32_t &value)
|
||||
{
|
||||
value = (int32_t)genrand();
|
||||
}
|
||||
|
||||
void
|
||||
_random(int64_t &value)
|
||||
{
|
||||
value = (int64_t)genrand() << 32 | (int64_t)genrand();
|
||||
}
|
||||
|
||||
void
|
||||
_random(uint8_t &value)
|
||||
{
|
||||
value = genrand() & (uint8_t)-1;
|
||||
}
|
||||
|
||||
void
|
||||
_random(uint16_t &value)
|
||||
{
|
||||
value = genrand() & (uint16_t)-1;
|
||||
}
|
||||
|
||||
void
|
||||
_random(uint32_t &value)
|
||||
{
|
||||
value = genrand();
|
||||
}
|
||||
|
||||
void
|
||||
_random(uint64_t &value)
|
||||
{
|
||||
value = (uint64_t)genrand() << 32 | (uint64_t)genrand();
|
||||
}
|
||||
|
||||
// [0,1]
|
||||
void
|
||||
_random(float &value)
|
||||
{
|
||||
// ieee floats have 23 bits of mantissa
|
||||
value = (genrand() >> 9) / 8388608.0;
|
||||
}
|
||||
|
||||
// [0,1]
|
||||
void
|
||||
_random(double &value)
|
||||
{
|
||||
double number = genrand() * 2097152.0 + (genrand() >> 11);
|
||||
value = number / 9007199254740992.0;
|
||||
}
|
||||
|
||||
|
||||
// Range based versions of the random number generator
|
||||
int8_t
|
||||
_random(int8_t min, int8_t max)
|
||||
{
|
||||
uint32_t diff = max - min;
|
||||
return static_cast<int8_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
int16_t
|
||||
_random(int16_t min, int16_t max)
|
||||
{
|
||||
uint32_t diff = max - min;
|
||||
return static_cast<int16_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
int32_t
|
||||
_random(int32_t min, int32_t max)
|
||||
{
|
||||
uint32_t diff = max - min;
|
||||
return static_cast<int32_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
int64_t
|
||||
_random(int64_t min, int64_t max)
|
||||
{
|
||||
uint64_t diff = max - min;
|
||||
return static_cast<int64_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
uint8_t
|
||||
_random(uint8_t min, uint8_t max)
|
||||
{
|
||||
uint32_t diff = max - min;
|
||||
return static_cast<uint8_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
uint16_t
|
||||
_random(uint16_t min, uint16_t max)
|
||||
{
|
||||
uint32_t diff = max - min;
|
||||
return static_cast<uint16_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
_random(uint32_t min, uint32_t max)
|
||||
{
|
||||
uint32_t diff = max - min;
|
||||
return static_cast<uint32_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
_random(uint64_t min, uint64_t max)
|
||||
{
|
||||
uint64_t diff = max - min;
|
||||
return static_cast<uint64_t>(min + genrand(diff));
|
||||
}
|
||||
|
||||
public:
|
||||
Random();
|
||||
Random(uint32_t s);
|
||||
Random(uint32_t init_key[], int key_length);
|
||||
~Random();
|
||||
|
||||
void init(uint32_t s);
|
||||
void init(uint32_t init_key[], int key_length);
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
random()
|
||||
{
|
||||
T value;
|
||||
_random(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
random(T min, T max)
|
||||
{
|
||||
return _random(min, max);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
random(const Range<T> &range)
|
||||
{
|
||||
return _random(range.start, range.end);
|
||||
}
|
||||
|
||||
// [0,1]
|
||||
double
|
||||
gen_real1()
|
||||
{
|
||||
return genrand() / 4294967296.0;
|
||||
}
|
||||
|
||||
// [0,1)
|
||||
double
|
||||
gen_real2()
|
||||
{
|
||||
return genrand() / 4294967295.0;
|
||||
}
|
||||
|
||||
// (0,1)
|
||||
double
|
||||
gen_real3()
|
||||
{
|
||||
return ((double)genrand() + 0.5) / 4294967296.0;
|
||||
}
|
||||
|
||||
public:
|
||||
void serialize(const std::string &base, std::ostream &os);
|
||||
void unserialize(const std::string &base, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
};
|
||||
|
||||
extern Random random_mt;
|
||||
|
||||
#endif // __BASE_RANDOM_HH__
|
||||
149
simulators/gem5/src/base/random_mt.cc
Normal file
149
simulators/gem5/src/base/random_mt.cc
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* A C-program for MT19937, with initialization improved 2002/1/26.
|
||||
* Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
*
|
||||
* Before using, initialize the state by using init_genrand(seed)
|
||||
* or init_by_array(init_key, key_length).
|
||||
*
|
||||
* Copyright (C) 1997-2002 Makoto Matsumoto and Takuji Nishimura
|
||||
* 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. The names of its contributors may not 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.
|
||||
*
|
||||
*
|
||||
* Any feedback is very welcome.
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
* email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
|
||||
*/
|
||||
|
||||
#include "base/random.hh"
|
||||
|
||||
/* initializes mt[N] with a seed */
|
||||
void
|
||||
Random::init(uint32_t s)
|
||||
{
|
||||
mti = N + 1;
|
||||
mt[0] = s & (uint32_t)0xffffffff;
|
||||
|
||||
for (mti = 1; mti < N; mti++) {
|
||||
mt[mti] = 1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti;
|
||||
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
||||
/* In the previous versions, MSBs of the seed affect */
|
||||
/* only MSBs of the array mt[]. */
|
||||
/* 2002/01/09 modified by Makoto Matsumoto */
|
||||
mt[mti] &= (uint32_t)0xffffffff;
|
||||
/* for >32 bit machines */
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize by an array with array-length */
|
||||
/* init_key is the array for initializing keys */
|
||||
/* key_length is its length */
|
||||
/* slight change for C++, 2004/2/26 */
|
||||
void
|
||||
Random::init(uint32_t init_key[], int key_length)
|
||||
{
|
||||
int i = 1;
|
||||
int j = 0;
|
||||
int k = (N > key_length) ? N : key_length;
|
||||
|
||||
init(19650218);
|
||||
|
||||
for (; k; k--) {
|
||||
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * (uint32_t)1664525))
|
||||
+ init_key[j] + j; /* non linear */
|
||||
|
||||
mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
|
||||
|
||||
i++;
|
||||
j++;
|
||||
|
||||
if (i >= N) {
|
||||
mt[0] = mt[N - 1];
|
||||
i = 1;
|
||||
}
|
||||
|
||||
if (j >= key_length)
|
||||
j = 0;
|
||||
}
|
||||
|
||||
for (k = N - 1; k; k--) {
|
||||
/* non linear */
|
||||
mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941UL)) - i;
|
||||
|
||||
/* for WORDSIZE > 32 machines */
|
||||
mt[i] &= (uint32_t)0xffffffff;
|
||||
i++;
|
||||
|
||||
if (i >= N) {
|
||||
mt[0] = mt[N - 1];
|
||||
i = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* MSB is 1; assuring non-zero initial array */
|
||||
mt[0] = (uint32_t)0x80000000;
|
||||
}
|
||||
|
||||
/* generates a random number on [0,0xffffffff]-interval */
|
||||
uint32_t
|
||||
Random::genrand()
|
||||
{
|
||||
uint32_t y;
|
||||
static uint32_t mag01[2] = { 0, MATRIX_A};
|
||||
|
||||
if (mti >= N) { /* generate N words at one time */
|
||||
int kk;
|
||||
|
||||
for (kk = 0; kk < N - M; kk++) {
|
||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||
mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||
}
|
||||
for (; kk < N - 1; kk++) {
|
||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||
mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||
}
|
||||
|
||||
y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||
mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||
|
||||
mti = 0;
|
||||
}
|
||||
|
||||
y = mt[mti++];
|
||||
|
||||
/* Tempering */
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & (uint32_t)0x9d2c5680;
|
||||
y ^= (y << 15) & (uint32_t)0xefc60000;
|
||||
y ^= (y >> 18);
|
||||
|
||||
return y;
|
||||
}
|
||||
85
simulators/gem5/src/base/range.cc
Normal file
85
simulators/gem5/src/base/range.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include "base/intmath.hh"
|
||||
#include "base/range.hh"
|
||||
#include "base/str.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <class T>
|
||||
bool
|
||||
__x_parse_range(const std::string &str, T &first, T &last)
|
||||
{
|
||||
std::vector<std::string> values;
|
||||
tokenize(values, str, ':');
|
||||
|
||||
T thefirst, thelast;
|
||||
|
||||
if (values.size() != 2)
|
||||
return false;
|
||||
|
||||
std::string s = values[0];
|
||||
std::string e = values[1];
|
||||
|
||||
if (!to_number(s, thefirst))
|
||||
return false;
|
||||
|
||||
bool increment = (e[0] == '+');
|
||||
if (increment)
|
||||
e = e.substr(1);
|
||||
|
||||
if (!to_number(e, thelast))
|
||||
return false;
|
||||
|
||||
if (increment)
|
||||
thelast += thefirst - 1;
|
||||
|
||||
first = thefirst;
|
||||
last = thelast;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define RANGE_PARSE(type) \
|
||||
template<> bool \
|
||||
__parse_range(const std::string &s, type &first, type &last) \
|
||||
{ return __x_parse_range(s, first, last); }
|
||||
|
||||
RANGE_PARSE(unsigned long long)
|
||||
RANGE_PARSE(signed long long)
|
||||
RANGE_PARSE(unsigned long)
|
||||
RANGE_PARSE(signed long)
|
||||
RANGE_PARSE(unsigned int)
|
||||
RANGE_PARSE(signed int)
|
||||
RANGE_PARSE(unsigned short)
|
||||
RANGE_PARSE(signed short)
|
||||
RANGE_PARSE(unsigned char)
|
||||
RANGE_PARSE(signed char)
|
||||
364
simulators/gem5/src/base/range.hh
Normal file
364
simulators/gem5/src/base/range.hh
Normal file
@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __BASE_RANGE_HH__
|
||||
#define __BASE_RANGE_HH__
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @param s range string
|
||||
* EndExclusive Ranges are in the following format:
|
||||
* @verbatim
|
||||
* <range> := {<start_val>}:{<end>}
|
||||
* <start> := <end_val> | +<delta>
|
||||
* @endverbatim
|
||||
*/
|
||||
template <class T>
|
||||
bool __parse_range(const std::string &s, T &start, T &end);
|
||||
|
||||
template <class T>
|
||||
struct Range
|
||||
{
|
||||
T start;
|
||||
T end;
|
||||
|
||||
Range() { invalidate(); }
|
||||
|
||||
template <class U>
|
||||
Range(const std::pair<U, U> &r)
|
||||
: start(r.first), end(r.second)
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
Range(const Range<U> &r)
|
||||
: start(r.start), end(r.end)
|
||||
{}
|
||||
|
||||
Range(const std::string &s)
|
||||
{
|
||||
if (!__parse_range(s, start, end))
|
||||
invalidate();
|
||||
}
|
||||
|
||||
template <class U>
|
||||
const Range<T> &operator=(const Range<U> &r)
|
||||
{
|
||||
start = r.start;
|
||||
end = r.end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
const Range<T> &operator=(const std::pair<U, U> &r)
|
||||
{
|
||||
start = r.first;
|
||||
end = r.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Range &operator=(const std::string &s)
|
||||
{
|
||||
if (!__parse_range(s, start, end))
|
||||
invalidate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void invalidate() { start = 1; end = 0; }
|
||||
T size() const { return end - start + 1; }
|
||||
bool valid() const { return start < end; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &o, const Range<T> &r)
|
||||
{
|
||||
o << '[' << r.start << "," << r.end << ']';
|
||||
return o;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline Range<T>
|
||||
RangeEx(T start, T end)
|
||||
{ return std::make_pair(start, end - 1); }
|
||||
|
||||
template <class T>
|
||||
inline Range<T>
|
||||
RangeIn(T start, T end)
|
||||
{ return std::make_pair(start, end); }
|
||||
|
||||
template <class T, class U>
|
||||
inline Range<T>
|
||||
RangeSize(T start, U size)
|
||||
{ return std::make_pair(start, start + size - 1); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Range to Range Comparisons
|
||||
//
|
||||
|
||||
/**
|
||||
* @param range1 is a range.
|
||||
* @param range2 is a range.
|
||||
* @return if range1 and range2 are identical.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator==(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
return range1.start == range2.start && range1.end == range2.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range1 is a range.
|
||||
* @param range2 is a range.
|
||||
* @return if range1 and range2 are not identical.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator!=(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
return range1.start != range2.start || range1.end != range2.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range1 is a range.
|
||||
* @param range2 is a range.
|
||||
* @return if range1 is less than range2 and does not overlap range1.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
return range1.start < range2.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range1 is a range.
|
||||
* @param range2 is a range.
|
||||
* @return if range1 is less than range2. range1 may overlap range2,
|
||||
* but not extend beyond the end of range2.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<=(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
return range1.start <= range2.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range1 is a range.
|
||||
* @param range2 is a range.
|
||||
* @return if range1 is greater than range2 and does not overlap range2.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator>(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
return range1.start > range2.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range1 is a range.
|
||||
* @param range2 is a range.
|
||||
* @return if range1 is greater than range2. range1 may overlap range2,
|
||||
* but not extend beyond the beginning of range2.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator>=(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
return range1.start >= range2.start;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Position to Range Comparisons
|
||||
//
|
||||
|
||||
/**
|
||||
* @param pos position compared to the range.
|
||||
* @param range range compared against.
|
||||
* @return indicates that position pos is within the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator==(const T &pos, const Range<U> &range)
|
||||
{
|
||||
return pos >= range.start && pos <= range.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos position compared to the range.
|
||||
* @param range range compared against.
|
||||
* @return indicates that position pos is not within the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator!=(const T &pos, const Range<U> &range)
|
||||
{
|
||||
return pos < range.start || pos > range.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos position compared to the range.
|
||||
* @param range range compared against.
|
||||
* @return indicates that position pos is below the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<(const T &pos, const Range<U> &range)
|
||||
{
|
||||
return pos < range.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos position compared to the range.
|
||||
* @param range range compared against.
|
||||
* @return indicates that position pos is below or in the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<=(const T &pos, const Range<U> &range)
|
||||
{
|
||||
return pos <= range.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos position compared to the range.
|
||||
* @param range range compared against.
|
||||
* @return indicates that position pos is above the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator>(const T &pos, const Range<U> &range)
|
||||
{
|
||||
return pos > range.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pos position compared to the range.
|
||||
* @param range range compared against.
|
||||
* @return indicates that position pos is above or in the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator>=(const T &pos, const Range<U> &range)
|
||||
{
|
||||
return pos >= range.start;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Range to Position Comparisons (for symmetry)
|
||||
//
|
||||
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* @return indicates that position pos is within the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator==(const Range<T> &range, const U &pos)
|
||||
{
|
||||
return pos >= range.start && pos <= range.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* @return indicates that position pos is not within the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator!=(const Range<T> &range, const U &pos)
|
||||
{
|
||||
return pos < range.start || pos > range.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* @return indicates that position pos is above the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<(const Range<T> &range, const U &pos)
|
||||
{
|
||||
// with -std=gnu++0x, gcc and clang get confused when range.end is
|
||||
// compared to pos using the operator "<", and the parser expects it
|
||||
// to be the opening bracket for a template parameter,
|
||||
// i.e. range.end<pos>(...);, the reason seems to be the range-type
|
||||
// iteration introduced in c++11 where begin and end are members
|
||||
// that return iterators
|
||||
return operator<(range.end, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* @return indicates that position pos is above or in the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<=(const Range<T> &range, const U &pos)
|
||||
{
|
||||
return range.start <= pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* 'range > pos' indicates that position pos is below the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator>(const Range<T> &range, const U &pos)
|
||||
{
|
||||
return range.start > pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* 'range >= pos' indicates that position pos is below or in the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator>=(const Range<T> &range, const U &pos)
|
||||
{
|
||||
return range.end >= pos;
|
||||
}
|
||||
|
||||
#endif // __BASE_RANGE_HH__
|
||||
324
simulators/gem5/src/base/range_map.hh
Normal file
324
simulators/gem5/src/base/range_map.hh
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __BASE_RANGE_MAP_HH__
|
||||
#define __BASE_RANGE_MAP_HH__
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "base/range.hh"
|
||||
|
||||
/**
|
||||
* The range_map uses an STL map to implement an interval tree. The
|
||||
* type of both the key (range) and the value are template
|
||||
* parameters. It can, for example, be used for address decoding,
|
||||
* using a range of addresses to map to ports.
|
||||
*/
|
||||
template <class T,class V>
|
||||
class range_map
|
||||
{
|
||||
private:
|
||||
typedef std::map<Range<T>,V> RangeMap;
|
||||
RangeMap tree;
|
||||
|
||||
public:
|
||||
typedef typename RangeMap::iterator iterator;
|
||||
typedef typename RangeMap::const_iterator const_iterator;
|
||||
|
||||
template <class U>
|
||||
const_iterator
|
||||
find(const Range<U> &r) const
|
||||
{
|
||||
const_iterator i;
|
||||
|
||||
i = tree.upper_bound(r);
|
||||
|
||||
if (i == tree.begin()) {
|
||||
if (i->first.start <= r.end && i->first.end >= r.start)
|
||||
return i;
|
||||
else
|
||||
// Nothing could match, so return end()
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
--i;
|
||||
|
||||
if (i->first.start <= r.end && i->first.end >= r.start)
|
||||
return i;
|
||||
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
template <class U>
|
||||
iterator
|
||||
find(const Range<U> &r)
|
||||
{
|
||||
iterator i;
|
||||
|
||||
i = tree.upper_bound(r);
|
||||
|
||||
if (i == tree.begin()) {
|
||||
if (i->first.start <= r.end && i->first.end >= r.start)
|
||||
return i;
|
||||
else
|
||||
// Nothing could match, so return end()
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
--i;
|
||||
|
||||
if (i->first.start <= r.end && i->first.end >= r.start)
|
||||
return i;
|
||||
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
template <class U>
|
||||
const_iterator
|
||||
find(const U &r) const
|
||||
{
|
||||
return find(RangeSize(r, 1));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
iterator
|
||||
find(const U &r)
|
||||
{
|
||||
return find(RangeSize(r, 1));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
bool
|
||||
intersect(const Range<U> &r)
|
||||
{
|
||||
iterator i;
|
||||
i = find(r);
|
||||
if (i != tree.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class U,class W>
|
||||
iterator
|
||||
insert(const Range<U> &r, const W d)
|
||||
{
|
||||
if (intersect(r))
|
||||
return tree.end();
|
||||
|
||||
return tree.insert(std::make_pair(r, d)).first;
|
||||
}
|
||||
|
||||
size_t
|
||||
erase(T k)
|
||||
{
|
||||
return tree.erase(k);
|
||||
}
|
||||
|
||||
void
|
||||
erase(iterator p)
|
||||
{
|
||||
tree.erase(p);
|
||||
}
|
||||
|
||||
void
|
||||
erase(iterator p, iterator q)
|
||||
{
|
||||
tree.erase(p,q);
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
tree.erase(tree.begin(), tree.end());
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return tree.begin();
|
||||
}
|
||||
|
||||
iterator
|
||||
begin()
|
||||
{
|
||||
return tree.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
iterator
|
||||
end()
|
||||
{
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
size_t
|
||||
size() const
|
||||
{
|
||||
return tree.size();
|
||||
}
|
||||
|
||||
bool
|
||||
empty() const
|
||||
{
|
||||
return tree.empty();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T,class V>
|
||||
class range_multimap
|
||||
{
|
||||
private:
|
||||
typedef std::multimap<Range<T>,V> RangeMap;
|
||||
RangeMap tree;
|
||||
|
||||
public:
|
||||
typedef typename RangeMap::iterator iterator;
|
||||
|
||||
template <class U>
|
||||
std::pair<iterator,iterator> find(const Range<U> &r)
|
||||
{
|
||||
iterator i;
|
||||
iterator j;
|
||||
|
||||
i = tree.lower_bound(r);
|
||||
|
||||
if (i == tree.begin()) {
|
||||
if (i->first.start <= r.end && i->first.end >= r.start)
|
||||
return std::make_pair<iterator, iterator>(i,i);
|
||||
else
|
||||
// Nothing could match, so return end()
|
||||
return std::make_pair<iterator, iterator>(tree.end(), tree.end());
|
||||
}
|
||||
i--;
|
||||
|
||||
if (i->first.start <= r.end && i->first.end >= r.start) {
|
||||
// we have at least one match
|
||||
j = i;
|
||||
|
||||
i--;
|
||||
while (i->first.start <= r.end && i->first.end >=
|
||||
r.start) {
|
||||
if (i == tree.begin())
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
if (i == tree.begin() && i->first.start <= r.end && i->first.end >=
|
||||
r.start)
|
||||
return std::make_pair<iterator, iterator>(i,j);
|
||||
i++;
|
||||
return std::make_pair<iterator, iterator>(i,j);
|
||||
|
||||
}
|
||||
|
||||
return std::make_pair<iterator, iterator>(tree.end(), tree.end());
|
||||
}
|
||||
|
||||
template <class U>
|
||||
bool
|
||||
intersect(const Range<U> &r)
|
||||
{
|
||||
std::pair<iterator,iterator> p;
|
||||
p = find(r);
|
||||
if (p.first != tree.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <class U,class W>
|
||||
iterator
|
||||
insert(const Range<U> &r, const W d)
|
||||
{
|
||||
std::pair<iterator,iterator> p;
|
||||
p = find(r);
|
||||
if ((p.first->first.start == r.start && p.first->first.end == r.end) ||
|
||||
p.first == tree.end())
|
||||
return tree.insert(std::make_pair<Range<T>,V>(r, d));
|
||||
else
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
size_t
|
||||
erase(T k)
|
||||
{
|
||||
return tree.erase(k);
|
||||
}
|
||||
|
||||
void
|
||||
erase(iterator p)
|
||||
{
|
||||
tree.erase(p);
|
||||
}
|
||||
|
||||
void
|
||||
erase(iterator p, iterator q)
|
||||
{
|
||||
tree.erase(p,q);
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
tree.erase(tree.begin(), tree.end());
|
||||
}
|
||||
|
||||
iterator
|
||||
begin()
|
||||
{
|
||||
return tree.begin();
|
||||
}
|
||||
|
||||
iterator
|
||||
end()
|
||||
{
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
size_t
|
||||
size()
|
||||
{
|
||||
return tree.size();
|
||||
}
|
||||
|
||||
bool
|
||||
empty()
|
||||
{
|
||||
return tree.empty();
|
||||
}
|
||||
};
|
||||
|
||||
#endif //__BASE_RANGE_MAP_HH__
|
||||
59
simulators/gem5/src/base/range_ops.hh
Normal file
59
simulators/gem5/src/base/range_ops.hh
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __BASE_RANGE_OPS_HH__
|
||||
#define __BASE_RANGE_OPS_HH__
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "base/range.hh"
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
FilterRangeList(std::vector<Range<T> > filter_list,
|
||||
std::list<Range<T> > &range_list)
|
||||
{
|
||||
typedef typename std::list<Range<T> > RangeList;
|
||||
|
||||
for (typename RangeList::size_type x = 0; x < filter_list.size(); x++) {
|
||||
typename RangeList::iterator i = range_list.begin();
|
||||
while (i != range_list.end()) {
|
||||
// Is the range within one of our filter ranges?
|
||||
if (filter_list[x] == i->start || filter_list[x] == i->end)
|
||||
i = range_list.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__BASE_RANGE_OPS_HH__
|
||||
|
||||
230
simulators/gem5/src/base/refcnt.hh
Normal file
230
simulators/gem5/src/base/refcnt.hh
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_REFCNT_HH__
|
||||
#define __BASE_REFCNT_HH__
|
||||
|
||||
/**
|
||||
* @file base/refcnt.hh
|
||||
*
|
||||
* Classes for managing reference counted objects.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Derive from RefCounted if you want to enable reference counting of
|
||||
* this class. If you want to use automatic reference counting, you
|
||||
* should use RefCountingPtr<T> instead of regular pointers.
|
||||
*/
|
||||
class RefCounted
|
||||
{
|
||||
private:
|
||||
// The reference count is mutable because one may want to
|
||||
// reference count a const pointer. This really is OK because
|
||||
// const is about logical constness of the object not really about
|
||||
// strictly disallowing an object to change.
|
||||
mutable int count;
|
||||
|
||||
private:
|
||||
// Don't allow a default copy constructor or copy operator on
|
||||
// these objects because the default operation will copy the
|
||||
// reference count as well and we certainly don't want that.
|
||||
RefCounted(const RefCounted &);
|
||||
RefCounted &operator=(const RefCounted &);
|
||||
|
||||
public:
|
||||
/**
|
||||
* We initialize the reference count to zero and the first object
|
||||
* to take ownership of it must increment it to one.
|
||||
*
|
||||
* @attention A memory leak will occur if you never assign a newly
|
||||
* constructed object to a reference counting pointer.
|
||||
*/
|
||||
RefCounted() : count(0) {}
|
||||
|
||||
/**
|
||||
* We make the destructor virtual because we're likely to have
|
||||
* virtual functions on reference counted objects.
|
||||
*
|
||||
* @todo Even if this were true, does it matter? Shouldn't the
|
||||
* derived class indicate this? This only matters if we would
|
||||
* ever choose to delete a "RefCounted *" which I doubt we'd ever
|
||||
* do. We don't ever delete a "void *".
|
||||
*/
|
||||
virtual ~RefCounted() {}
|
||||
|
||||
/// Increment the reference count
|
||||
void incref() { ++count; }
|
||||
|
||||
/// Decrement the reference count and destroy the object if all
|
||||
/// references are gone.
|
||||
void decref() { if (--count <= 0) delete this; }
|
||||
};
|
||||
|
||||
/**
|
||||
* If you want a reference counting pointer to a mutable object,
|
||||
* create it like this:
|
||||
* @code
|
||||
* typedef RefCountingPtr<Foo> FooPtr;
|
||||
* @endcode
|
||||
*
|
||||
* @attention Do not use "const FooPtr"
|
||||
* To create a reference counting pointer to a const object, use this:
|
||||
* @code
|
||||
* typedef RefCountingPtr<const Foo> ConstFooPtr;
|
||||
* @endcode
|
||||
*
|
||||
* These two usages are analogous to iterator and const_iterator in the stl.
|
||||
*/
|
||||
template <class T>
|
||||
class RefCountingPtr
|
||||
{
|
||||
protected:
|
||||
/// The stored pointer.
|
||||
/// Arguably this should be private.
|
||||
T *data;
|
||||
|
||||
/**
|
||||
* Copy a new pointer value and increment the reference count if
|
||||
* it is a valid pointer. Note, this does not delete the
|
||||
* reference any existing object.
|
||||
* @param d Pointer to store.
|
||||
*/
|
||||
void
|
||||
copy(T *d)
|
||||
{
|
||||
data = d;
|
||||
if (data)
|
||||
data->incref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the reference to any existing object if it is non NULL.
|
||||
* @attention this doesn't clear the pointer value, so a double
|
||||
* decref could happen if not careful.
|
||||
*/
|
||||
void
|
||||
del()
|
||||
{
|
||||
if (data)
|
||||
data->decref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the old reference and change it to something new.
|
||||
*/
|
||||
void
|
||||
set(T *d)
|
||||
{
|
||||
// Need to check if we're actually changing because otherwise
|
||||
// we could delete the last reference before adding the new
|
||||
// reference.
|
||||
if (data != d) {
|
||||
del();
|
||||
copy(d);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/// Create an empty reference counting pointer.
|
||||
RefCountingPtr() : data(0) {}
|
||||
|
||||
/// Create a new reference counting pointer to some object
|
||||
/// (probably something newly created). Adds a reference.
|
||||
RefCountingPtr(T *data) { copy(data); }
|
||||
|
||||
/// Create a new reference counting pointer by copying another
|
||||
/// one. Adds a reference.
|
||||
RefCountingPtr(const RefCountingPtr &r) { copy(r.data); }
|
||||
|
||||
/// Destroy the pointer and any reference it may hold.
|
||||
~RefCountingPtr() { del(); }
|
||||
|
||||
// The following pointer access functions are const because they
|
||||
// don't actually change the pointer, though the user could change
|
||||
// what is pointed to. This is analagous to a "Foo * const".
|
||||
|
||||
/// Access a member variable.
|
||||
T *operator->() const { return data; }
|
||||
|
||||
/// Dereference the pointer.
|
||||
T &operator*() const { return *data; }
|
||||
|
||||
/// Directly access the pointer itself without taking a reference.
|
||||
T *get() const { return data; }
|
||||
|
||||
/// Assign a new value to the pointer
|
||||
const RefCountingPtr &operator=(T *p) { set(p); return *this; }
|
||||
|
||||
/// Copy the pointer from another RefCountingPtr
|
||||
const RefCountingPtr &operator=(const RefCountingPtr &r)
|
||||
{ return operator=(r.data); }
|
||||
|
||||
/// Check if the pointer is empty
|
||||
bool operator!() const { return data == 0; }
|
||||
|
||||
/// Check if the pointer is non-empty
|
||||
operator bool() const { return data != 0; }
|
||||
};
|
||||
|
||||
/// Check for equality of two reference counting pointers.
|
||||
template<class T>
|
||||
inline bool operator==(const RefCountingPtr<T> &l, const RefCountingPtr<T> &r)
|
||||
{ return l.get() == r.get(); }
|
||||
|
||||
/// Check for equality of of a reference counting pointers and a
|
||||
/// regular pointer
|
||||
template<class T>
|
||||
inline bool operator==(const RefCountingPtr<T> &l, const T *r)
|
||||
{ return l.get() == r; }
|
||||
|
||||
/// Check for equality of of a reference counting pointers and a
|
||||
/// regular pointer
|
||||
template<class T>
|
||||
inline bool operator==(const T *l, const RefCountingPtr<T> &r)
|
||||
{ return l == r.get(); }
|
||||
|
||||
/// Check for inequality of two reference counting pointers.
|
||||
template<class T>
|
||||
inline bool operator!=(const RefCountingPtr<T> &l, const RefCountingPtr<T> &r)
|
||||
{ return l.get() != r.get(); }
|
||||
|
||||
/// Check for inequality of of a reference counting pointers and a
|
||||
/// regular pointer
|
||||
template<class T>
|
||||
inline bool operator!=(const RefCountingPtr<T> &l, const T *r)
|
||||
{ return l.get() != r; }
|
||||
|
||||
/// Check for inequality of of a reference counting pointers and a
|
||||
/// regular pointer
|
||||
template<class T>
|
||||
inline bool operator!=(const T *l, const RefCountingPtr<T> &r)
|
||||
{ return l != r.get(); }
|
||||
|
||||
#endif // __BASE_REFCNT_HH__
|
||||
1019
simulators/gem5/src/base/remote_gdb.cc
Normal file
1019
simulators/gem5/src/base/remote_gdb.cc
Normal file
File diff suppressed because it is too large
Load Diff
272
simulators/gem5/src/base/remote_gdb.hh
Normal file
272
simulators/gem5/src/base/remote_gdb.hh
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __REMOTE_GDB_HH__
|
||||
#define __REMOTE_GDB_HH__
|
||||
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "arch/types.hh"
|
||||
#include "base/pollevent.hh"
|
||||
#include "base/socket.hh"
|
||||
#include "cpu/pc_event.hh"
|
||||
|
||||
class System;
|
||||
class ThreadContext;
|
||||
|
||||
class GDBListener;
|
||||
|
||||
enum GDBCommands
|
||||
{
|
||||
GDBSignal = '?', // last signal
|
||||
GDBSetBaud = 'b', // set baud (depracated)
|
||||
GDBSetBreak = 'B', // set breakpoint (depracated)
|
||||
GDBCont = 'c', // resume
|
||||
GDBAsyncCont = 'C', // continue with signal
|
||||
GDBDebug = 'd', // toggle debug flags (deprecated)
|
||||
GDBDetach = 'D', // detach remote gdb
|
||||
GDBRegR = 'g', // read general registers
|
||||
GDBRegW = 'G', // write general registers
|
||||
GDBSetThread = 'H', // set thread
|
||||
GDBCycleStep = 'i', // step a single cycle
|
||||
GDBSigCycleStep = 'I', // signal then cycle step
|
||||
GDBKill = 'k', // kill program
|
||||
GDBMemR = 'm', // read memory
|
||||
GDBMemW = 'M', // write memory
|
||||
GDBReadReg = 'p', // read register
|
||||
GDBSetReg = 'P', // write register
|
||||
GDBQueryVar = 'q', // query variable
|
||||
GDBSetVar = 'Q', // set variable
|
||||
GDBReset = 'r', // reset system. (Deprecated)
|
||||
GDBStep = 's', // step
|
||||
GDBAsyncStep = 'S', // signal and step
|
||||
GDBThreadAlive = 'T', // find out if the thread is alive
|
||||
GDBTargetExit = 'W', // target exited
|
||||
GDBBinaryDload = 'X', // write memory
|
||||
GDBClrHwBkpt = 'z', // remove breakpoint or watchpoint
|
||||
GDBSetHwBkpt = 'Z' // insert breakpoint or watchpoint
|
||||
};
|
||||
|
||||
const char GDBStart = '$';
|
||||
const char GDBEnd = '#';
|
||||
const char GDBGoodP = '+';
|
||||
const char GDBBadP = '-';
|
||||
|
||||
const int GDBPacketBufLen = 1024;
|
||||
|
||||
class BaseRemoteGDB
|
||||
{
|
||||
private:
|
||||
friend void debugger();
|
||||
friend class GDBListener;
|
||||
|
||||
//Helper functions
|
||||
protected:
|
||||
int digit2i(char);
|
||||
char i2digit(int);
|
||||
Addr hex2i(const char **);
|
||||
//Address formats, break types, and gdb commands may change
|
||||
//between architectures, so they're defined as virtual
|
||||
//functions.
|
||||
virtual void mem2hex(void *, const void *, int);
|
||||
virtual const char * hex2mem(void *, const char *, int);
|
||||
virtual const char * break_type(char c);
|
||||
virtual const char * gdb_command(char cmd);
|
||||
|
||||
protected:
|
||||
class Event : public PollEvent
|
||||
{
|
||||
protected:
|
||||
BaseRemoteGDB *gdb;
|
||||
|
||||
public:
|
||||
Event(BaseRemoteGDB *g, int fd, int e);
|
||||
void process(int revent);
|
||||
};
|
||||
|
||||
friend class Event;
|
||||
Event *event;
|
||||
GDBListener *listener;
|
||||
int number;
|
||||
|
||||
protected:
|
||||
//The socket commands come in through
|
||||
int fd;
|
||||
|
||||
protected:
|
||||
#ifdef notyet
|
||||
label_t recover;
|
||||
#endif
|
||||
bool active;
|
||||
bool attached;
|
||||
|
||||
System *system;
|
||||
ThreadContext *context;
|
||||
|
||||
protected:
|
||||
class GdbRegCache
|
||||
{
|
||||
public:
|
||||
GdbRegCache(size_t newSize) : regs(new uint64_t[newSize]), size(newSize)
|
||||
{}
|
||||
~GdbRegCache()
|
||||
{
|
||||
delete [] regs;
|
||||
}
|
||||
|
||||
uint64_t * regs;
|
||||
size_t size;
|
||||
size_t bytes() { return size * sizeof(uint64_t); }
|
||||
};
|
||||
|
||||
GdbRegCache gdbregs;
|
||||
|
||||
protected:
|
||||
uint8_t getbyte();
|
||||
void putbyte(uint8_t b);
|
||||
|
||||
int recv(char *data, int len);
|
||||
void send(const char *data);
|
||||
|
||||
protected:
|
||||
// Machine memory
|
||||
virtual bool read(Addr addr, size_t size, char *data);
|
||||
virtual bool write(Addr addr, size_t size, const char *data);
|
||||
|
||||
template <class T> T read(Addr addr);
|
||||
template <class T> void write(Addr addr, T data);
|
||||
|
||||
public:
|
||||
BaseRemoteGDB(System *system, ThreadContext *context, size_t cacheSize);
|
||||
virtual ~BaseRemoteGDB();
|
||||
|
||||
void replaceThreadContext(ThreadContext *tc) { context = tc; }
|
||||
|
||||
void attach(int fd);
|
||||
void detach();
|
||||
bool isattached();
|
||||
|
||||
virtual bool acc(Addr addr, size_t len) = 0;
|
||||
bool trap(int type);
|
||||
virtual bool breakpoint()
|
||||
{
|
||||
return trap(SIGTRAP);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void getregs() = 0;
|
||||
virtual void setregs() = 0;
|
||||
|
||||
virtual void clearSingleStep() = 0;
|
||||
virtual void setSingleStep() = 0;
|
||||
|
||||
PCEventQueue *getPcEventQueue();
|
||||
|
||||
protected:
|
||||
class HardBreakpoint : public PCEvent
|
||||
{
|
||||
private:
|
||||
BaseRemoteGDB *gdb;
|
||||
|
||||
public:
|
||||
int refcount;
|
||||
|
||||
public:
|
||||
HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr);
|
||||
const std::string name() const { return gdb->name() + ".hwbkpt"; }
|
||||
|
||||
virtual void process(ThreadContext *tc);
|
||||
};
|
||||
friend class HardBreakpoint;
|
||||
|
||||
typedef std::map<Addr, HardBreakpoint *> break_map_t;
|
||||
typedef break_map_t::iterator break_iter_t;
|
||||
break_map_t hardBreakMap;
|
||||
|
||||
bool insertSoftBreak(Addr addr, size_t len);
|
||||
bool removeSoftBreak(Addr addr, size_t len);
|
||||
virtual bool insertHardBreak(Addr addr, size_t len);
|
||||
bool removeHardBreak(Addr addr, size_t len);
|
||||
|
||||
protected:
|
||||
void clearTempBreakpoint(Addr &bkpt);
|
||||
void setTempBreakpoint(Addr bkpt);
|
||||
|
||||
public:
|
||||
std::string name();
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T
|
||||
BaseRemoteGDB::read(Addr addr)
|
||||
{
|
||||
T temp;
|
||||
read(addr, sizeof(T), (char *)&temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
BaseRemoteGDB::write(Addr addr, T data)
|
||||
{ write(addr, sizeof(T), (const char *)&data); }
|
||||
|
||||
class GDBListener
|
||||
{
|
||||
protected:
|
||||
class Event : public PollEvent
|
||||
{
|
||||
protected:
|
||||
GDBListener *listener;
|
||||
|
||||
public:
|
||||
Event(GDBListener *l, int fd, int e);
|
||||
void process(int revent);
|
||||
};
|
||||
|
||||
friend class Event;
|
||||
Event *event;
|
||||
|
||||
protected:
|
||||
ListenSocket listener;
|
||||
BaseRemoteGDB *gdb;
|
||||
int port;
|
||||
|
||||
public:
|
||||
GDBListener(BaseRemoteGDB *g, int p);
|
||||
~GDBListener();
|
||||
|
||||
void accept();
|
||||
void listen();
|
||||
std::string name();
|
||||
};
|
||||
|
||||
#endif /* __REMOTE_GDB_H__ */
|
||||
130
simulators/gem5/src/base/socket.cc
Normal file
130
simulators/gem5/src/base/socket.cc
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "base/socket.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool ListenSocket::listeningDisabled = false;
|
||||
bool ListenSocket::anyListening = false;
|
||||
|
||||
void
|
||||
ListenSocket::disableAll()
|
||||
{
|
||||
if (anyListening)
|
||||
panic("Too late to disable all listeners, already have a listener");
|
||||
listeningDisabled = true;
|
||||
}
|
||||
|
||||
bool
|
||||
ListenSocket::allDisabled()
|
||||
{
|
||||
return listeningDisabled;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
ListenSocket::ListenSocket()
|
||||
: listening(false), fd(-1)
|
||||
{}
|
||||
|
||||
ListenSocket::~ListenSocket()
|
||||
{
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
// Create a socket and configure it for listening
|
||||
bool
|
||||
ListenSocket::listen(int port, bool reuse)
|
||||
{
|
||||
if (listening)
|
||||
panic("Socket already listening!");
|
||||
|
||||
fd = ::socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
panic("Can't create socket:%s !", strerror(errno));
|
||||
|
||||
if (reuse) {
|
||||
int i = 1;
|
||||
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&i,
|
||||
sizeof(i)) < 0)
|
||||
panic("ListenSocket(listen): setsockopt() SO_REUSEADDR failed!");
|
||||
}
|
||||
|
||||
struct sockaddr_in sockaddr;
|
||||
sockaddr.sin_family = PF_INET;
|
||||
sockaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
sockaddr.sin_port = htons(port);
|
||||
int ret = ::bind(fd, (struct sockaddr *)&sockaddr, sizeof (sockaddr));
|
||||
if (ret != 0) {
|
||||
if (ret == -1 && errno != EADDRINUSE)
|
||||
panic("ListenSocket(listen): bind() failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::listen(fd, 1) == -1)
|
||||
panic("ListenSocket(listen): listen() failed!");
|
||||
|
||||
listening = true;
|
||||
|
||||
anyListening = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Open a connection. Accept will block, so if you don't want it to,
|
||||
// make sure a connection is ready before you call accept.
|
||||
int
|
||||
ListenSocket::accept(bool nodelay)
|
||||
{
|
||||
struct sockaddr_in sockaddr;
|
||||
socklen_t slen = sizeof (sockaddr);
|
||||
int sfd = ::accept(fd, (struct sockaddr *)&sockaddr, &slen);
|
||||
if (sfd != -1 && nodelay) {
|
||||
int i = 1;
|
||||
::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i));
|
||||
}
|
||||
|
||||
return sfd;
|
||||
}
|
||||
59
simulators/gem5/src/base/socket.hh
Normal file
59
simulators/gem5/src/base/socket.hh
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __SOCKET_HH__
|
||||
#define __SOCKET_HH__
|
||||
|
||||
class ListenSocket
|
||||
{
|
||||
protected:
|
||||
static bool listeningDisabled;
|
||||
static bool anyListening;
|
||||
|
||||
public:
|
||||
static void disableAll();
|
||||
static bool allDisabled();
|
||||
|
||||
protected:
|
||||
bool listening;
|
||||
int fd;
|
||||
|
||||
public:
|
||||
ListenSocket();
|
||||
virtual ~ListenSocket();
|
||||
|
||||
virtual int accept(bool nodelay = false);
|
||||
virtual bool listen(int port, bool reuse = true);
|
||||
|
||||
int getfd() const { return fd; }
|
||||
bool islistening() const { return listening; }
|
||||
};
|
||||
|
||||
#endif //__SOCKET_HH__
|
||||
474
simulators/gem5/src/base/statistics.cc
Normal file
474
simulators/gem5/src/base/statistics.cc
Normal file
@ -0,0 +1,474 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/callback.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/debug.hh"
|
||||
#include "base/hostinfo.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "base/str.hh"
|
||||
#include "base/time.hh"
|
||||
#include "base/trace.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Stats {
|
||||
|
||||
std::string Info::separatorString = "::";
|
||||
typedef map<const void *, Info *> MapType;
|
||||
|
||||
// We wrap these in a function to make sure they're built in time.
|
||||
list<Info *> &
|
||||
statsList()
|
||||
{
|
||||
static list<Info *> the_list;
|
||||
return the_list;
|
||||
}
|
||||
|
||||
MapType &
|
||||
statsMap()
|
||||
{
|
||||
static MapType the_map;
|
||||
return the_map;
|
||||
}
|
||||
|
||||
void
|
||||
InfoAccess::setInfo(Info *info)
|
||||
{
|
||||
if (statsMap().find(this) != statsMap().end())
|
||||
panic("shouldn't register stat twice!");
|
||||
|
||||
statsList().push_back(info);
|
||||
|
||||
#ifndef NDEBUG
|
||||
pair<MapType::iterator, bool> result =
|
||||
#endif
|
||||
statsMap().insert(make_pair(this, info));
|
||||
assert(result.second && "this should never fail");
|
||||
assert(statsMap().find(this) != statsMap().end());
|
||||
}
|
||||
|
||||
void
|
||||
InfoAccess::setParams(const StorageParams *params)
|
||||
{
|
||||
info()->storageParams = params;
|
||||
}
|
||||
|
||||
void
|
||||
InfoAccess::setInit()
|
||||
{
|
||||
info()->flags.set(init);
|
||||
}
|
||||
|
||||
Info *
|
||||
InfoAccess::info()
|
||||
{
|
||||
MapType::const_iterator i = statsMap().find(this);
|
||||
assert(i != statsMap().end());
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
const Info *
|
||||
InfoAccess::info() const
|
||||
{
|
||||
MapType::const_iterator i = statsMap().find(this);
|
||||
assert(i != statsMap().end());
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
StorageParams::~StorageParams()
|
||||
{
|
||||
}
|
||||
|
||||
typedef map<std::string, Info *> NameMapType;
|
||||
NameMapType &
|
||||
nameMap()
|
||||
{
|
||||
static NameMapType the_map;
|
||||
return the_map;
|
||||
}
|
||||
|
||||
int Info::id_count = 0;
|
||||
|
||||
int debug_break_id = -1;
|
||||
|
||||
Info::Info()
|
||||
: flags(none), precision(-1), prereq(0), storageParams(NULL)
|
||||
{
|
||||
id = id_count++;
|
||||
if (debug_break_id >= 0 and debug_break_id == id)
|
||||
Debug::breakpoint();
|
||||
}
|
||||
|
||||
Info::~Info()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
validateStatName(const string &name)
|
||||
{
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
vector<string> vec;
|
||||
tokenize(vec, name, '.');
|
||||
vector<string>::const_iterator item = vec.begin();
|
||||
while (item != vec.end()) {
|
||||
if (item->empty())
|
||||
return false;
|
||||
|
||||
string::const_iterator c = item->begin();
|
||||
|
||||
// The first character is different
|
||||
if (!isalpha(*c) && *c != '_')
|
||||
return false;
|
||||
|
||||
// The rest of the characters have different rules.
|
||||
while (++c != item->end()) {
|
||||
if (!isalnum(*c) && *c != '_')
|
||||
return false;
|
||||
}
|
||||
|
||||
++item;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Info::setName(const string &name)
|
||||
{
|
||||
if (!validateStatName(name))
|
||||
panic("invalid stat name '%s'", name);
|
||||
|
||||
pair<NameMapType::iterator, bool> p =
|
||||
nameMap().insert(make_pair(name, this));
|
||||
|
||||
Info *other = p.first->second;
|
||||
bool result = p.second;
|
||||
|
||||
if (!result) {
|
||||
// using other->name instead of just name to avoid a compiler
|
||||
// warning. They should be the same.
|
||||
panic("same statistic name used twice! name=%s\n", other->name);
|
||||
}
|
||||
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
bool
|
||||
Info::less(Info *stat1, Info *stat2)
|
||||
{
|
||||
const string &name1 = stat1->name;
|
||||
const string &name2 = stat2->name;
|
||||
|
||||
vector<string> v1;
|
||||
vector<string> v2;
|
||||
|
||||
tokenize(v1, name1, '.');
|
||||
tokenize(v2, name2, '.');
|
||||
|
||||
size_type last = min(v1.size(), v2.size()) - 1;
|
||||
for (off_type i = 0; i < last; ++i)
|
||||
if (v1[i] != v2[i])
|
||||
return v1[i] < v2[i];
|
||||
|
||||
// Special compare for last element.
|
||||
if (v1[last] == v2[last])
|
||||
return v1.size() < v2.size();
|
||||
else
|
||||
return v1[last] < v2[last];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Info::baseCheck() const
|
||||
{
|
||||
if (!(flags & Stats::init)) {
|
||||
#ifdef DEBUG
|
||||
cprintf("this is stat number %d\n", id);
|
||||
#endif
|
||||
panic("Not all stats have been initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((flags & display) && name.empty()) {
|
||||
panic("all printable stats must be named");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Info::enable()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
VectorInfo::enable()
|
||||
{
|
||||
size_type s = size();
|
||||
if (subnames.size() < s)
|
||||
subnames.resize(s);
|
||||
if (subdescs.size() < s)
|
||||
subdescs.resize(s);
|
||||
}
|
||||
|
||||
void
|
||||
VectorDistInfo::enable()
|
||||
{
|
||||
size_type s = size();
|
||||
if (subnames.size() < s)
|
||||
subnames.resize(s);
|
||||
if (subdescs.size() < s)
|
||||
subdescs.resize(s);
|
||||
}
|
||||
|
||||
void
|
||||
Vector2dInfo::enable()
|
||||
{
|
||||
if (subnames.size() < x)
|
||||
subnames.resize(x);
|
||||
if (subdescs.size() < x)
|
||||
subdescs.resize(x);
|
||||
if (y_subnames.size() < y)
|
||||
y_subnames.resize(y);
|
||||
}
|
||||
|
||||
void
|
||||
HistStor::grow_out()
|
||||
{
|
||||
int size = cvec.size();
|
||||
int zero = size / 2; // round down!
|
||||
int top_half = zero + (size - zero + 1) / 2; // round up!
|
||||
int bottom_half = (size - zero) / 2; // round down!
|
||||
|
||||
// grow down
|
||||
int low_pair = zero - 1;
|
||||
for (int i = zero - 1; i >= bottom_half; i--) {
|
||||
cvec[i] = cvec[low_pair];
|
||||
if (low_pair - 1 >= 0)
|
||||
cvec[i] += cvec[low_pair - 1];
|
||||
low_pair -= 2;
|
||||
}
|
||||
assert(low_pair == 0 || low_pair == -1 || low_pair == -2);
|
||||
|
||||
for (int i = bottom_half - 1; i >= 0; i--)
|
||||
cvec[i] = Counter();
|
||||
|
||||
// grow up
|
||||
int high_pair = zero;
|
||||
for (int i = zero; i < top_half; i++) {
|
||||
cvec[i] = cvec[high_pair];
|
||||
if (high_pair + 1 < size)
|
||||
cvec[i] += cvec[high_pair + 1];
|
||||
high_pair += 2;
|
||||
}
|
||||
assert(high_pair == size || high_pair == size + 1);
|
||||
|
||||
for (int i = top_half; i < size; i++)
|
||||
cvec[i] = Counter();
|
||||
|
||||
max_bucket *= 2;
|
||||
min_bucket *= 2;
|
||||
bucket_size *= 2;
|
||||
}
|
||||
|
||||
void
|
||||
HistStor::grow_convert()
|
||||
{
|
||||
int size = cvec.size();
|
||||
int half = (size + 1) / 2; // round up!
|
||||
//bool even = (size & 1) == 0;
|
||||
|
||||
int pair = size - 1;
|
||||
for (int i = size - 1; i >= half; --i) {
|
||||
cvec[i] = cvec[pair];
|
||||
if (pair - 1 >= 0)
|
||||
cvec[i] += cvec[pair - 1];
|
||||
pair -= 2;
|
||||
}
|
||||
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
cvec[i] = Counter();
|
||||
|
||||
min_bucket = -max_bucket;// - (even ? bucket_size : 0);
|
||||
bucket_size *= 2;
|
||||
}
|
||||
|
||||
void
|
||||
HistStor::grow_up()
|
||||
{
|
||||
int size = cvec.size();
|
||||
int half = (size + 1) / 2; // round up!
|
||||
|
||||
int pair = 0;
|
||||
for (int i = 0; i < half; i++) {
|
||||
cvec[i] = cvec[pair];
|
||||
if (pair + 1 < size)
|
||||
cvec[i] += cvec[pair + 1];
|
||||
pair += 2;
|
||||
}
|
||||
assert(pair == size || pair == size + 1);
|
||||
|
||||
for (int i = half; i < size; i++)
|
||||
cvec[i] = Counter();
|
||||
|
||||
max_bucket *= 2;
|
||||
bucket_size *= 2;
|
||||
}
|
||||
|
||||
Formula::Formula()
|
||||
{
|
||||
}
|
||||
|
||||
Formula::Formula(Temp r)
|
||||
{
|
||||
root = r;
|
||||
setInit();
|
||||
assert(size());
|
||||
}
|
||||
|
||||
const Formula &
|
||||
Formula::operator=(Temp r)
|
||||
{
|
||||
assert(!root && "Can't change formulas");
|
||||
root = r;
|
||||
setInit();
|
||||
assert(size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Formula &
|
||||
Formula::operator+=(Temp r)
|
||||
{
|
||||
if (root)
|
||||
root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
|
||||
else {
|
||||
root = r;
|
||||
setInit();
|
||||
}
|
||||
|
||||
assert(size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
Formula::result(VResult &vec) const
|
||||
{
|
||||
if (root)
|
||||
vec = root->result();
|
||||
}
|
||||
|
||||
Result
|
||||
Formula::total() const
|
||||
{
|
||||
return root ? root->total() : 0.0;
|
||||
}
|
||||
|
||||
size_type
|
||||
Formula::size() const
|
||||
{
|
||||
if (!root)
|
||||
return 0;
|
||||
else
|
||||
return root->size();
|
||||
}
|
||||
|
||||
void
|
||||
Formula::reset()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Formula::zero() const
|
||||
{
|
||||
VResult vec;
|
||||
result(vec);
|
||||
for (VResult::size_type i = 0; i < vec.size(); ++i)
|
||||
if (vec[i] != 0.0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
string
|
||||
Formula::str() const
|
||||
{
|
||||
return root ? root->str() : "";
|
||||
}
|
||||
|
||||
CallbackQueue dumpQueue;
|
||||
CallbackQueue resetQueue;
|
||||
|
||||
void
|
||||
registerResetCallback(Callback *cb)
|
||||
{
|
||||
resetQueue.add(cb);
|
||||
}
|
||||
|
||||
bool _enabled = false;
|
||||
|
||||
bool
|
||||
enabled()
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
void
|
||||
enable()
|
||||
{
|
||||
if (_enabled)
|
||||
fatal("Stats are already enabled");
|
||||
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
void
|
||||
registerDumpCallback(Callback *cb)
|
||||
{
|
||||
dumpQueue.add(cb);
|
||||
}
|
||||
|
||||
} // namespace Stats
|
||||
|
||||
void
|
||||
debugDumpStats()
|
||||
{
|
||||
Stats::dump();
|
||||
}
|
||||
3170
simulators/gem5/src/base/statistics.hh
Normal file
3170
simulators/gem5/src/base/statistics.hh
Normal file
File diff suppressed because it is too large
Load Diff
255
simulators/gem5/src/base/stats/info.hh
Normal file
255
simulators/gem5/src/base/stats/info.hh
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_STATS_INFO_HH__
|
||||
#define __BASE_STATS_INFO_HH__
|
||||
|
||||
#include "base/stats/types.hh"
|
||||
#include "base/flags.hh"
|
||||
|
||||
namespace Stats {
|
||||
|
||||
typedef uint16_t FlagsType;
|
||||
typedef ::Flags<FlagsType> Flags;
|
||||
|
||||
/** Nothing extra to print. */
|
||||
const FlagsType none = 0x0000;
|
||||
/** This Stat is Initialized */
|
||||
const FlagsType init = 0x0001;
|
||||
/** Print this stat. */
|
||||
const FlagsType display = 0x0002;
|
||||
/** Print the total. */
|
||||
const FlagsType total = 0x0010;
|
||||
/** Print the percent of the total that this entry represents. */
|
||||
const FlagsType pdf = 0x0020;
|
||||
/** Print the cumulative percentage of total upto this entry. */
|
||||
const FlagsType cdf = 0x0040;
|
||||
/** Print the distribution. */
|
||||
const FlagsType dist = 0x0080;
|
||||
/** Don't print if this is zero. */
|
||||
const FlagsType nozero = 0x0100;
|
||||
/** Don't print if this is NAN */
|
||||
const FlagsType nonan = 0x0200;
|
||||
|
||||
/** Mask of flags that can't be set directly */
|
||||
const FlagsType __reserved = init | display;
|
||||
|
||||
struct StorageParams;
|
||||
struct Output;
|
||||
|
||||
class Info
|
||||
{
|
||||
public:
|
||||
/** The name of the stat. */
|
||||
std::string name;
|
||||
/** The separator string used for vectors, dist, etc. */
|
||||
static std::string separatorString;
|
||||
/** The description of the stat. */
|
||||
std::string desc;
|
||||
/** The formatting flags. */
|
||||
Flags flags;
|
||||
/** The display precision. */
|
||||
int precision;
|
||||
/** A pointer to a prerequisite Stat. */
|
||||
const Info *prereq;
|
||||
/**
|
||||
* A unique stat ID for each stat in the simulator.
|
||||
* Can be used externally for lookups as well as for debugging.
|
||||
*/
|
||||
static int id_count;
|
||||
int id;
|
||||
|
||||
public:
|
||||
const StorageParams *storageParams;
|
||||
|
||||
public:
|
||||
Info();
|
||||
virtual ~Info();
|
||||
|
||||
/** Set the name of this statistic */
|
||||
void setName(const std::string &name);
|
||||
void setSeparator(std::string _sep) { separatorString = _sep;}
|
||||
|
||||
/**
|
||||
* Check that this stat has been set up properly and is ready for
|
||||
* use
|
||||
* @return true for success
|
||||
*/
|
||||
virtual bool check() const = 0;
|
||||
bool baseCheck() const;
|
||||
|
||||
/**
|
||||
* Enable the stat for use
|
||||
*/
|
||||
virtual void enable();
|
||||
|
||||
/**
|
||||
* Prepare the stat for dumping.
|
||||
*/
|
||||
virtual void prepare() = 0;
|
||||
|
||||
/**
|
||||
* Reset the stat to the default state.
|
||||
*/
|
||||
virtual void reset() = 0;
|
||||
|
||||
/**
|
||||
* @return true if this stat has a value and satisfies its
|
||||
* requirement as a prereq
|
||||
*/
|
||||
virtual bool zero() const = 0;
|
||||
|
||||
/**
|
||||
* Visitor entry for outputing statistics data
|
||||
*/
|
||||
virtual void visit(Output &visitor) = 0;
|
||||
|
||||
/**
|
||||
* Checks if the first stat's name is alphabetically less than the second.
|
||||
* This function breaks names up at periods and considers each subname
|
||||
* separately.
|
||||
* @param stat1 The first stat.
|
||||
* @param stat2 The second stat.
|
||||
* @return stat1's name is alphabetically before stat2's
|
||||
*/
|
||||
static bool less(Info *stat1, Info *stat2);
|
||||
};
|
||||
|
||||
class ScalarInfo : public Info
|
||||
{
|
||||
public:
|
||||
virtual Counter value() const = 0;
|
||||
virtual Result result() const = 0;
|
||||
virtual Result total() const = 0;
|
||||
};
|
||||
|
||||
class VectorInfo : public Info
|
||||
{
|
||||
public:
|
||||
/** Names and descriptions of subfields. */
|
||||
std::vector<std::string> subnames;
|
||||
std::vector<std::string> subdescs;
|
||||
|
||||
public:
|
||||
void enable();
|
||||
|
||||
public:
|
||||
virtual size_type size() const = 0;
|
||||
virtual const VCounter &value() const = 0;
|
||||
virtual const VResult &result() const = 0;
|
||||
virtual Result total() const = 0;
|
||||
};
|
||||
|
||||
enum DistType { Deviation, Dist, Hist };
|
||||
|
||||
struct DistData
|
||||
{
|
||||
DistType type;
|
||||
Counter min;
|
||||
Counter max;
|
||||
Counter bucket_size;
|
||||
|
||||
Counter min_val;
|
||||
Counter max_val;
|
||||
Counter underflow;
|
||||
Counter overflow;
|
||||
VCounter cvec;
|
||||
Counter sum;
|
||||
Counter squares;
|
||||
Counter logs;
|
||||
Counter samples;
|
||||
};
|
||||
|
||||
class DistInfo : public Info
|
||||
{
|
||||
public:
|
||||
/** Local storage for the entry values, used for printing. */
|
||||
DistData data;
|
||||
};
|
||||
|
||||
class VectorDistInfo : public Info
|
||||
{
|
||||
public:
|
||||
std::vector<DistData> data;
|
||||
|
||||
/** Names and descriptions of subfields. */
|
||||
std::vector<std::string> subnames;
|
||||
std::vector<std::string> subdescs;
|
||||
void enable();
|
||||
|
||||
protected:
|
||||
/** Local storage for the entry values, used for printing. */
|
||||
mutable VResult rvec;
|
||||
|
||||
public:
|
||||
virtual size_type size() const = 0;
|
||||
};
|
||||
|
||||
class Vector2dInfo : public Info
|
||||
{
|
||||
public:
|
||||
/** Names and descriptions of subfields. */
|
||||
std::vector<std::string> subnames;
|
||||
std::vector<std::string> subdescs;
|
||||
std::vector<std::string> y_subnames;
|
||||
|
||||
size_type x;
|
||||
size_type y;
|
||||
|
||||
/** Local storage for the entry values, used for printing. */
|
||||
mutable VCounter cvec;
|
||||
|
||||
void enable();
|
||||
};
|
||||
|
||||
class FormulaInfo : public VectorInfo
|
||||
{
|
||||
public:
|
||||
virtual std::string str() const = 0;
|
||||
};
|
||||
|
||||
/** Data structure of sparse histogram */
|
||||
struct SparseHistData
|
||||
{
|
||||
MCounter cmap;
|
||||
Counter samples;
|
||||
};
|
||||
|
||||
|
||||
class SparseHistInfo : public Info
|
||||
{
|
||||
public:
|
||||
/** Local storage for the entry values, used for printing. */
|
||||
SparseHistData data;
|
||||
};
|
||||
|
||||
} // namespace Stats
|
||||
|
||||
#endif // __BASE_STATS_INFO_HH__
|
||||
66
simulators/gem5/src/base/stats/output.hh
Normal file
66
simulators/gem5/src/base/stats/output.hh
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_STATS_OUTPUT_HH__
|
||||
#define __BASE_STATS_OUTPUT_HH__
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
namespace Stats {
|
||||
|
||||
class Info;
|
||||
class ScalarInfo;
|
||||
class VectorInfo;
|
||||
class DistInfo;
|
||||
class VectorDistInfo;
|
||||
class Vector2dInfo;
|
||||
class FormulaInfo;
|
||||
class SparseHistInfo; // Sparse histogram
|
||||
|
||||
struct Output
|
||||
{
|
||||
virtual ~Output() {}
|
||||
virtual void begin() = 0;
|
||||
virtual void end() = 0;
|
||||
virtual bool valid() const = 0;
|
||||
|
||||
virtual void visit(const ScalarInfo &info) = 0;
|
||||
virtual void visit(const VectorInfo &info) = 0;
|
||||
virtual void visit(const DistInfo &info) = 0;
|
||||
virtual void visit(const VectorDistInfo &info) = 0;
|
||||
virtual void visit(const Vector2dInfo &info) = 0;
|
||||
virtual void visit(const FormulaInfo &info) = 0;
|
||||
virtual void visit(const SparseHistInfo &info) = 0; // Sparse histogram
|
||||
};
|
||||
|
||||
} // namespace Stats
|
||||
|
||||
#endif // __BASE_STATS_OUTPUT_HH__
|
||||
702
simulators/gem5/src/base/stats/text.cc
Normal file
702
simulators/gem5/src/base/stats/text.cc
Normal file
@ -0,0 +1,702 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define _GLIBCPP_USE_C99 1
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#ifdef __SUNPRO_CC
|
||||
#include <math.h>
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "base/stats/info.hh"
|
||||
#include "base/stats/text.hh"
|
||||
#include "base/cast.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/str.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef NAN
|
||||
float __nan();
|
||||
/** Define Not a number. */
|
||||
#define NAN (__nan())
|
||||
/** Need to define __nan() */
|
||||
#define __M5_NAN
|
||||
#endif
|
||||
|
||||
#ifdef __M5_NAN
|
||||
float
|
||||
__nan()
|
||||
{
|
||||
union {
|
||||
uint32_t ui;
|
||||
float f;
|
||||
} nan;
|
||||
|
||||
nan.ui = 0x7fc00000;
|
||||
return nan.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace Stats {
|
||||
|
||||
std::list<Info *> &statsList();
|
||||
|
||||
Text::Text()
|
||||
: mystream(false), stream(NULL), descriptions(false)
|
||||
{
|
||||
}
|
||||
|
||||
Text::Text(std::ostream &stream)
|
||||
: mystream(false), stream(NULL), descriptions(false)
|
||||
{
|
||||
open(stream);
|
||||
}
|
||||
|
||||
Text::Text(const std::string &file)
|
||||
: mystream(false), stream(NULL), descriptions(false)
|
||||
{
|
||||
open(file);
|
||||
}
|
||||
|
||||
|
||||
Text::~Text()
|
||||
{
|
||||
if (mystream) {
|
||||
assert(stream);
|
||||
delete stream;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Text::open(std::ostream &_stream)
|
||||
{
|
||||
if (stream)
|
||||
panic("stream already set!");
|
||||
|
||||
mystream = false;
|
||||
stream = &_stream;
|
||||
if (!valid())
|
||||
fatal("Unable to open output stream for writing\n");
|
||||
}
|
||||
|
||||
void
|
||||
Text::open(const std::string &file)
|
||||
{
|
||||
if (stream)
|
||||
panic("stream already set!");
|
||||
|
||||
mystream = true;
|
||||
stream = new ofstream(file.c_str(), ios::trunc);
|
||||
if (!valid())
|
||||
fatal("Unable to open statistics file for writing\n");
|
||||
}
|
||||
|
||||
bool
|
||||
Text::valid() const
|
||||
{
|
||||
return stream != NULL && stream->good();
|
||||
}
|
||||
|
||||
void
|
||||
Text::begin()
|
||||
{
|
||||
ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
|
||||
}
|
||||
|
||||
void
|
||||
Text::end()
|
||||
{
|
||||
ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n");
|
||||
stream->flush();
|
||||
}
|
||||
|
||||
bool
|
||||
Text::noOutput(const Info &info)
|
||||
{
|
||||
if (!info.flags.isSet(display))
|
||||
return true;
|
||||
|
||||
if (info.prereq && info.prereq->zero())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string
|
||||
ValueToString(Result value, int precision)
|
||||
{
|
||||
stringstream val;
|
||||
|
||||
if (!std::isnan(value)) {
|
||||
if (precision != -1)
|
||||
val.precision(precision);
|
||||
else if (value == rint(value))
|
||||
val.precision(0);
|
||||
|
||||
val.unsetf(ios::showpoint);
|
||||
val.setf(ios::fixed);
|
||||
val << value;
|
||||
} else {
|
||||
val << "nan";
|
||||
}
|
||||
|
||||
return val.str();
|
||||
}
|
||||
|
||||
struct ScalarPrint
|
||||
{
|
||||
Result value;
|
||||
string name;
|
||||
string desc;
|
||||
Flags flags;
|
||||
bool descriptions;
|
||||
int precision;
|
||||
Result pdf;
|
||||
Result cdf;
|
||||
|
||||
void update(Result val, Result total);
|
||||
void operator()(ostream &stream) const;
|
||||
};
|
||||
|
||||
void
|
||||
ScalarPrint::update(Result val, Result total)
|
||||
{
|
||||
value = val;
|
||||
if (total) {
|
||||
pdf = val / total;
|
||||
cdf += pdf;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScalarPrint::operator()(ostream &stream) const
|
||||
{
|
||||
if ((flags.isSet(nozero) && value == 0.0) ||
|
||||
(flags.isSet(nonan) && std::isnan(value)))
|
||||
return;
|
||||
|
||||
stringstream pdfstr, cdfstr;
|
||||
|
||||
if (!std::isnan(pdf))
|
||||
ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
|
||||
|
||||
if (!std::isnan(cdf))
|
||||
ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
|
||||
|
||||
ccprintf(stream, "%-40s %12s %10s %10s", name,
|
||||
ValueToString(value, precision), pdfstr, cdfstr);
|
||||
|
||||
if (descriptions) {
|
||||
if (!desc.empty())
|
||||
ccprintf(stream, " # %s", desc);
|
||||
}
|
||||
stream << endl;
|
||||
}
|
||||
|
||||
struct VectorPrint
|
||||
{
|
||||
string name;
|
||||
string separatorString;
|
||||
string desc;
|
||||
vector<string> subnames;
|
||||
vector<string> subdescs;
|
||||
Flags flags;
|
||||
bool descriptions;
|
||||
int precision;
|
||||
VResult vec;
|
||||
Result total;
|
||||
|
||||
void operator()(ostream &stream) const;
|
||||
};
|
||||
|
||||
void
|
||||
VectorPrint::operator()(std::ostream &stream) const
|
||||
{
|
||||
size_type _size = vec.size();
|
||||
Result _total = 0.0;
|
||||
|
||||
if (flags.isSet(pdf | cdf)) {
|
||||
for (off_type i = 0; i < _size; ++i) {
|
||||
_total += vec[i];
|
||||
}
|
||||
}
|
||||
|
||||
string base = name + separatorString;
|
||||
|
||||
ScalarPrint print;
|
||||
print.name = name;
|
||||
print.desc = desc;
|
||||
print.precision = precision;
|
||||
print.descriptions = descriptions;
|
||||
print.flags = flags;
|
||||
print.pdf = _total ? 0.0 : NAN;
|
||||
print.cdf = _total ? 0.0 : NAN;
|
||||
|
||||
bool havesub = !subnames.empty();
|
||||
|
||||
if (_size == 1) {
|
||||
print.value = vec[0];
|
||||
print(stream);
|
||||
return;
|
||||
}
|
||||
|
||||
for (off_type i = 0; i < _size; ++i) {
|
||||
if (havesub && (i >= subnames.size() || subnames[i].empty()))
|
||||
continue;
|
||||
|
||||
print.name = base + (havesub ? subnames[i] : to_string(i));
|
||||
print.desc = subdescs.empty() ? desc : subdescs[i];
|
||||
|
||||
print.update(vec[i], _total);
|
||||
print(stream);
|
||||
}
|
||||
|
||||
if (flags.isSet(::Stats::total)) {
|
||||
print.pdf = NAN;
|
||||
print.cdf = NAN;
|
||||
print.name = base + "total";
|
||||
print.desc = desc;
|
||||
print.value = total;
|
||||
print(stream);
|
||||
}
|
||||
}
|
||||
|
||||
struct DistPrint
|
||||
{
|
||||
string name;
|
||||
string separatorString;
|
||||
string desc;
|
||||
Flags flags;
|
||||
bool descriptions;
|
||||
int precision;
|
||||
|
||||
const DistData &data;
|
||||
|
||||
DistPrint(const Text *text, const DistInfo &info);
|
||||
DistPrint(const Text *text, const VectorDistInfo &info, int i);
|
||||
void init(const Text *text, const Info &info);
|
||||
void operator()(ostream &stream) const;
|
||||
};
|
||||
|
||||
DistPrint::DistPrint(const Text *text, const DistInfo &info)
|
||||
: data(info.data)
|
||||
{
|
||||
init(text, info);
|
||||
}
|
||||
|
||||
DistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i)
|
||||
: data(info.data[i])
|
||||
{
|
||||
init(text, info);
|
||||
|
||||
name = info.name + "_" +
|
||||
(info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]);
|
||||
|
||||
if (!info.subdescs[i].empty())
|
||||
desc = info.subdescs[i];
|
||||
}
|
||||
|
||||
void
|
||||
DistPrint::init(const Text *text, const Info &info)
|
||||
{
|
||||
name = info.name;
|
||||
separatorString = info.separatorString;
|
||||
desc = info.desc;
|
||||
flags = info.flags;
|
||||
precision = info.precision;
|
||||
descriptions = text->descriptions;
|
||||
}
|
||||
|
||||
void
|
||||
DistPrint::operator()(ostream &stream) const
|
||||
{
|
||||
string base = name + separatorString;
|
||||
|
||||
ScalarPrint print;
|
||||
print.precision = precision;
|
||||
print.flags = flags;
|
||||
print.descriptions = descriptions;
|
||||
print.desc = desc;
|
||||
print.pdf = NAN;
|
||||
print.cdf = NAN;
|
||||
|
||||
print.name = base + "samples";
|
||||
print.value = data.samples;
|
||||
print(stream);
|
||||
|
||||
print.name = base + "mean";
|
||||
print.value = data.samples ? data.sum / data.samples : NAN;
|
||||
print(stream);
|
||||
|
||||
if (data.type == Hist) {
|
||||
print.name = base + "gmean";
|
||||
print.value = data.samples ? exp(data.logs / data.samples) : NAN;
|
||||
print(stream);
|
||||
}
|
||||
|
||||
Result stdev = NAN;
|
||||
if (data.samples)
|
||||
stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
|
||||
(data.samples * (data.samples - 1.0)));
|
||||
print.name = base + "stdev";
|
||||
print.value = stdev;
|
||||
print(stream);
|
||||
|
||||
if (data.type == Deviation)
|
||||
return;
|
||||
|
||||
size_t size = data.cvec.size();
|
||||
|
||||
Result total = 0.0;
|
||||
if (data.type == Dist && data.underflow != NAN)
|
||||
total += data.underflow;
|
||||
for (off_type i = 0; i < size; ++i)
|
||||
total += data.cvec[i];
|
||||
if (data.type == Dist && data.overflow != NAN)
|
||||
total += data.overflow;
|
||||
|
||||
if (total) {
|
||||
print.pdf = 0.0;
|
||||
print.cdf = 0.0;
|
||||
}
|
||||
|
||||
if (data.type == Dist && data.underflow != NAN) {
|
||||
print.name = base + "underflows";
|
||||
print.update(data.underflow, total);
|
||||
print(stream);
|
||||
}
|
||||
|
||||
for (off_type i = 0; i < size; ++i) {
|
||||
stringstream namestr;
|
||||
namestr << base;
|
||||
|
||||
Counter low = i * data.bucket_size + data.min;
|
||||
Counter high = ::min(low + data.bucket_size - 1.0, data.max);
|
||||
namestr << low;
|
||||
if (low < high)
|
||||
namestr << "-" << high;
|
||||
|
||||
print.name = namestr.str();
|
||||
print.update(data.cvec[i], total);
|
||||
print(stream);
|
||||
}
|
||||
|
||||
if (data.type == Dist && data.overflow != NAN) {
|
||||
print.name = base + "overflows";
|
||||
print.update(data.overflow, total);
|
||||
print(stream);
|
||||
}
|
||||
|
||||
print.pdf = NAN;
|
||||
print.cdf = NAN;
|
||||
|
||||
if (data.type == Dist && data.min_val != NAN) {
|
||||
print.name = base + "min_value";
|
||||
print.value = data.min_val;
|
||||
print(stream);
|
||||
}
|
||||
|
||||
if (data.type == Dist && data.max_val != NAN) {
|
||||
print.name = base + "max_value";
|
||||
print.value = data.max_val;
|
||||
print(stream);
|
||||
}
|
||||
|
||||
print.name = base + "total";
|
||||
print.value = total;
|
||||
print(stream);
|
||||
}
|
||||
|
||||
void
|
||||
Text::visit(const ScalarInfo &info)
|
||||
{
|
||||
if (noOutput(info))
|
||||
return;
|
||||
|
||||
ScalarPrint print;
|
||||
print.value = info.result();
|
||||
print.name = info.name;
|
||||
print.desc = info.desc;
|
||||
print.flags = info.flags;
|
||||
print.descriptions = descriptions;
|
||||
print.precision = info.precision;
|
||||
print.pdf = NAN;
|
||||
print.cdf = NAN;
|
||||
|
||||
print(*stream);
|
||||
}
|
||||
|
||||
void
|
||||
Text::visit(const VectorInfo &info)
|
||||
{
|
||||
if (noOutput(info))
|
||||
return;
|
||||
|
||||
size_type size = info.size();
|
||||
VectorPrint print;
|
||||
|
||||
print.name = info.name;
|
||||
print.separatorString = info.separatorString;
|
||||
print.desc = info.desc;
|
||||
print.flags = info.flags;
|
||||
print.descriptions = descriptions;
|
||||
print.precision = info.precision;
|
||||
print.vec = info.result();
|
||||
print.total = info.total();
|
||||
|
||||
if (!info.subnames.empty()) {
|
||||
for (off_type i = 0; i < size; ++i) {
|
||||
if (!info.subnames[i].empty()) {
|
||||
print.subnames = info.subnames;
|
||||
print.subnames.resize(size);
|
||||
for (off_type i = 0; i < size; ++i) {
|
||||
if (!info.subnames[i].empty() &&
|
||||
!info.subdescs[i].empty()) {
|
||||
print.subdescs = info.subdescs;
|
||||
print.subdescs.resize(size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print(*stream);
|
||||
}
|
||||
|
||||
void
|
||||
Text::visit(const Vector2dInfo &info)
|
||||
{
|
||||
if (noOutput(info))
|
||||
return;
|
||||
|
||||
bool havesub = false;
|
||||
VectorPrint print;
|
||||
|
||||
if (!info.y_subnames.empty()) {
|
||||
for (off_type i = 0; i < info.y; ++i) {
|
||||
if (!info.y_subnames[i].empty()) {
|
||||
print.subnames = info.y_subnames;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
print.flags = info.flags;
|
||||
print.separatorString = info.separatorString;
|
||||
print.descriptions = descriptions;
|
||||
print.precision = info.precision;
|
||||
|
||||
if (!info.subnames.empty()) {
|
||||
for (off_type i = 0; i < info.x; ++i)
|
||||
if (!info.subnames[i].empty())
|
||||
havesub = true;
|
||||
}
|
||||
|
||||
VResult tot_vec(info.y);
|
||||
Result super_total = 0.0;
|
||||
for (off_type i = 0; i < info.x; ++i) {
|
||||
if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
|
||||
continue;
|
||||
|
||||
off_type iy = i * info.y;
|
||||
VResult yvec(info.y);
|
||||
|
||||
Result total = 0.0;
|
||||
for (off_type j = 0; j < info.y; ++j) {
|
||||
yvec[j] = info.cvec[iy + j];
|
||||
tot_vec[j] += yvec[j];
|
||||
total += yvec[j];
|
||||
super_total += yvec[j];
|
||||
}
|
||||
|
||||
print.name = info.name + "_" +
|
||||
(havesub ? info.subnames[i] : to_string(i));
|
||||
print.desc = info.desc;
|
||||
print.vec = yvec;
|
||||
print.total = total;
|
||||
print(*stream);
|
||||
}
|
||||
|
||||
if (info.flags.isSet(::Stats::total) && (info.x > 1)) {
|
||||
print.name = info.name;
|
||||
print.desc = info.desc;
|
||||
print.vec = tot_vec;
|
||||
print.total = super_total;
|
||||
print(*stream);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Text::visit(const DistInfo &info)
|
||||
{
|
||||
if (noOutput(info))
|
||||
return;
|
||||
|
||||
DistPrint print(this, info);
|
||||
print(*stream);
|
||||
}
|
||||
|
||||
void
|
||||
Text::visit(const VectorDistInfo &info)
|
||||
{
|
||||
if (noOutput(info))
|
||||
return;
|
||||
|
||||
for (off_type i = 0; i < info.size(); ++i) {
|
||||
DistPrint print(this, info, i);
|
||||
print(*stream);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Text::visit(const FormulaInfo &info)
|
||||
{
|
||||
visit((const VectorInfo &)info);
|
||||
}
|
||||
|
||||
/*
|
||||
This struct implements the output methods for the sparse
|
||||
histogram stat
|
||||
*/
|
||||
struct SparseHistPrint
|
||||
{
|
||||
string name;
|
||||
string separatorString;
|
||||
string desc;
|
||||
Flags flags;
|
||||
bool descriptions;
|
||||
int precision;
|
||||
|
||||
const SparseHistData &data;
|
||||
|
||||
SparseHistPrint(const Text *text, const SparseHistInfo &info);
|
||||
void init(const Text *text, const Info &info);
|
||||
void operator()(ostream &stream) const;
|
||||
};
|
||||
|
||||
/* Call initialization function */
|
||||
SparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info)
|
||||
: data(info.data)
|
||||
{
|
||||
init(text, info);
|
||||
}
|
||||
|
||||
/* Initialization function */
|
||||
void
|
||||
SparseHistPrint::init(const Text *text, const Info &info)
|
||||
{
|
||||
name = info.name;
|
||||
separatorString = info.separatorString;
|
||||
desc = info.desc;
|
||||
flags = info.flags;
|
||||
precision = info.precision;
|
||||
descriptions = text->descriptions;
|
||||
}
|
||||
|
||||
/* Grab data from map and write to output stream */
|
||||
void
|
||||
SparseHistPrint::operator()(ostream &stream) const
|
||||
{
|
||||
string base = name + separatorString;
|
||||
|
||||
ScalarPrint print;
|
||||
print.precision = precision;
|
||||
print.flags = flags;
|
||||
print.descriptions = descriptions;
|
||||
print.desc = desc;
|
||||
print.pdf = NAN;
|
||||
print.cdf = NAN;
|
||||
|
||||
print.name = base + "samples";
|
||||
print.value = data.samples;
|
||||
print(stream);
|
||||
|
||||
MCounter::const_iterator it;
|
||||
for (it = data.cmap.begin(); it != data.cmap.end(); it++) {
|
||||
stringstream namestr;
|
||||
namestr << base;
|
||||
|
||||
namestr <<(*it).first;
|
||||
print.name = namestr.str();
|
||||
print.value = (*it).second;
|
||||
print(stream);
|
||||
}
|
||||
|
||||
print.pdf = NAN;
|
||||
print.cdf = NAN;
|
||||
|
||||
print.name = base + "total";
|
||||
print.value = total;
|
||||
print(stream);
|
||||
}
|
||||
|
||||
void
|
||||
Text::visit(const SparseHistInfo &info)
|
||||
{
|
||||
if (noOutput(info))
|
||||
return;
|
||||
|
||||
SparseHistPrint print(this, info);
|
||||
print(*stream);
|
||||
}
|
||||
|
||||
Output *
|
||||
initText(const string &filename, bool desc)
|
||||
{
|
||||
static Text text;
|
||||
static bool connected = false;
|
||||
|
||||
if (!connected) {
|
||||
ostream *os = simout.find(filename);
|
||||
if (!os)
|
||||
os = simout.create(filename);
|
||||
|
||||
text.open(*os);
|
||||
text.descriptions = desc;
|
||||
connected = true;
|
||||
}
|
||||
|
||||
return &text;
|
||||
}
|
||||
|
||||
} // namespace Stats
|
||||
82
simulators/gem5/src/base/stats/text.hh
Normal file
82
simulators/gem5/src/base/stats/text.hh
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_STATS_TEXT_HH__
|
||||
#define __BASE_STATS_TEXT_HH__
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "base/stats/output.hh"
|
||||
#include "base/output.hh"
|
||||
|
||||
namespace Stats {
|
||||
|
||||
class Text : public Output
|
||||
{
|
||||
protected:
|
||||
bool mystream;
|
||||
std::ostream *stream;
|
||||
|
||||
protected:
|
||||
bool noOutput(const Info &info);
|
||||
|
||||
public:
|
||||
bool descriptions;
|
||||
|
||||
public:
|
||||
Text();
|
||||
Text(std::ostream &stream);
|
||||
Text(const std::string &file);
|
||||
~Text();
|
||||
|
||||
void open(std::ostream &stream);
|
||||
void open(const std::string &file);
|
||||
|
||||
// Implement Visit
|
||||
virtual void visit(const ScalarInfo &info);
|
||||
virtual void visit(const VectorInfo &info);
|
||||
virtual void visit(const DistInfo &info);
|
||||
virtual void visit(const VectorDistInfo &info);
|
||||
virtual void visit(const Vector2dInfo &info);
|
||||
virtual void visit(const FormulaInfo &info);
|
||||
virtual void visit(const SparseHistInfo &info);
|
||||
|
||||
// Implement Output
|
||||
virtual bool valid() const;
|
||||
virtual void begin();
|
||||
virtual void end();
|
||||
};
|
||||
|
||||
Output *initText(const std::string &filename, bool desc);
|
||||
|
||||
} // namespace Stats
|
||||
|
||||
#endif // __BASE_STATS_TEXT_HH__
|
||||
61
simulators/gem5/src/base/stats/types.hh
Normal file
61
simulators/gem5/src/base/stats/types.hh
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_STATS_TYPES_HH__
|
||||
#define __BASE_STATS_TYPES_HH__
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
namespace Stats {
|
||||
|
||||
/** All counters are of 64-bit values. */
|
||||
typedef double Counter;
|
||||
/** vector of counters. */
|
||||
typedef std::vector<Counter> VCounter;
|
||||
/** map of counters */
|
||||
typedef std::map<Counter, int> MCounter;
|
||||
|
||||
typedef std::numeric_limits<Counter> CounterLimits;
|
||||
|
||||
/** All results are doubles. */
|
||||
typedef double Result;
|
||||
/** vector of results. */
|
||||
typedef std::vector<Result> VResult;
|
||||
|
||||
typedef unsigned int size_type;
|
||||
typedef unsigned int off_type;
|
||||
|
||||
} // namespace Stats
|
||||
|
||||
#endif // __BASE_STATS_TYPES_HH__
|
||||
98
simulators/gem5/src/base/stl_helpers.hh
Normal file
98
simulators/gem5/src/base/stl_helpers.hh
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2010 The Hewlett-Packard Development Company
|
||||
* 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_STL_HELPERS_HH__
|
||||
#define __BASE_STL_HELPERS_HH__
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
namespace m5 {
|
||||
namespace stl_helpers {
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
deletePointer(T &ptr)
|
||||
{
|
||||
delete ptr;
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class ContainerPrint
|
||||
{
|
||||
private:
|
||||
std::ostream &out;
|
||||
bool first;
|
||||
|
||||
public:
|
||||
ContainerPrint(std::ostream &out)
|
||||
: out(out), first(true)
|
||||
{}
|
||||
|
||||
void
|
||||
operator()(const T &elem)
|
||||
{
|
||||
// First one doesn't get a space before it. The rest do.
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out << " ";
|
||||
|
||||
out << elem;
|
||||
}
|
||||
};
|
||||
|
||||
// Treat all objects in an stl container as pointers to heap objects,
|
||||
// calling delete on each one and zeroing the pointers along the way
|
||||
template <template <typename T, typename A> class C, typename T, typename A>
|
||||
void
|
||||
deletePointers(C<T,A> &container)
|
||||
{
|
||||
std::for_each(container.begin(), container.end(), deletePointer<T>);
|
||||
}
|
||||
|
||||
// Write out all elements in an stl container as a space separated
|
||||
// list enclosed in square brackets
|
||||
template <template <typename T, typename A> class C, typename T, typename A>
|
||||
std::ostream &
|
||||
operator<<(std::ostream& out, const C<T,A> &vec)
|
||||
{
|
||||
out << "[ ";
|
||||
std::for_each(vec.begin(), vec.end(), ContainerPrint<T>(out));
|
||||
out << " ]";
|
||||
out << std::flush;
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace stl_helpers
|
||||
} // namespace m5
|
||||
|
||||
#endif // __BASE_STL_HELPERS_HH__
|
||||
375
simulators/gem5/src/base/str.cc
Normal file
375
simulators/gem5/src/base/str.cc
Normal file
@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/intmath.hh"
|
||||
#include "base/str.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool
|
||||
split_first(const string &s, string &lhs, string &rhs, char c)
|
||||
{
|
||||
string::size_type offset = s.find(c);
|
||||
if (offset == string::npos) {
|
||||
lhs = s;
|
||||
rhs = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
lhs = s.substr(0, offset);
|
||||
rhs = s.substr(offset + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
split_last(const string &s, string &lhs, string &rhs, char c)
|
||||
{
|
||||
string::size_type offset = s.rfind(c);
|
||||
if (offset == string::npos) {
|
||||
lhs = s;
|
||||
rhs = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
lhs = s.substr(0, offset);
|
||||
rhs = s.substr(offset + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
tokenize(vector<string>& v, const string &s, char token, bool ignore)
|
||||
{
|
||||
string::size_type first = 0;
|
||||
string::size_type last = s.find_first_of(token);
|
||||
|
||||
if (s.empty())
|
||||
return;
|
||||
|
||||
if (ignore && last == first) {
|
||||
while (last == first)
|
||||
last = s.find_first_of(token, ++first);
|
||||
|
||||
if (last == string::npos) {
|
||||
if (first != s.size())
|
||||
v.push_back(s.substr(first));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (last != string::npos) {
|
||||
v.push_back(s.substr(first, last - first));
|
||||
|
||||
if (ignore) {
|
||||
first = s.find_first_not_of(token, last + 1);
|
||||
|
||||
if (first == string::npos)
|
||||
return;
|
||||
} else
|
||||
first = last + 1;
|
||||
|
||||
last = s.find_first_of(token, first);
|
||||
}
|
||||
|
||||
v.push_back(s.substr(first));
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo This function will not handle the smallest negative decimal
|
||||
* value for a signed type
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline bool
|
||||
__to_number(string value, T &retval)
|
||||
{
|
||||
static const T maxnum = ((T)-1);
|
||||
static const bool sign = numeric_limits<T>::is_signed;
|
||||
static const int bits = numeric_limits<T>::digits;
|
||||
static const T hexmax = maxnum & (((T)1 << (bits - 4)) - 1);
|
||||
static const T octmax = maxnum & (((T)1 << (bits - 3)) - 1);
|
||||
static const T signmax = numeric_limits<T>::max();
|
||||
static const T decmax = signmax / 10;
|
||||
|
||||
#if 0
|
||||
cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n"
|
||||
<< "sign = 0x" << hex << (unsigned long long)sign << "\n"
|
||||
<< "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n"
|
||||
<< "octmax = 0x" << hex << (unsigned long long)octmax << "\n"
|
||||
<< "signmax = 0x" << hex << (unsigned long long)signmax << "\n"
|
||||
<< "decmax = 0x" << hex << (unsigned long long)decmax << "\n";
|
||||
#endif
|
||||
|
||||
eat_white(value);
|
||||
|
||||
bool negative = false;
|
||||
bool hex = false;
|
||||
bool oct = false;
|
||||
int last = value.size() - 1;
|
||||
retval = 0;
|
||||
int i = 0;
|
||||
|
||||
char c = value[i];
|
||||
if (!isDec(c)) {
|
||||
if (c == '-' && sign)
|
||||
negative = true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
retval += c - '0';
|
||||
if (last == 0) return true;
|
||||
}
|
||||
|
||||
if (c == '0')
|
||||
oct = true;
|
||||
|
||||
c = value[++i];
|
||||
if (oct) {
|
||||
if (sign && negative)
|
||||
return false;
|
||||
|
||||
if (!isOct(c)) {
|
||||
if (c == 'X' || c == 'x') {
|
||||
hex = true;
|
||||
oct = false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
retval += c - '0';
|
||||
} else if (!isDec(c))
|
||||
goto multiply;
|
||||
else {
|
||||
if (sign && negative && c == '0')
|
||||
return false;
|
||||
|
||||
retval *= 10;
|
||||
retval += c - '0';
|
||||
if (last == 1) {
|
||||
if (sign && negative) retval = -retval;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hex) {
|
||||
if (last == 1)
|
||||
return false;
|
||||
|
||||
for (i = 2; i <= last ; i++) {
|
||||
c = value[i];
|
||||
if (!isHex(c))
|
||||
return false;
|
||||
|
||||
if (retval > hexmax) return false;
|
||||
retval *= 16;
|
||||
retval += hex2Int(c);
|
||||
}
|
||||
return true;
|
||||
} else if (oct) {
|
||||
for (i = 2; i <= last ; i++) {
|
||||
c = value[i];
|
||||
if (!isOct(c))
|
||||
return false;
|
||||
|
||||
if (retval > octmax) return false;
|
||||
retval *= 8;
|
||||
retval += (c - '0');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i = 2; i < last ; i++) {
|
||||
c = value[i];
|
||||
if (!isDec(c))
|
||||
goto multiply;
|
||||
|
||||
if (retval > decmax) return false;
|
||||
bool atmax = retval == decmax;
|
||||
retval *= 10;
|
||||
retval += c - '0';
|
||||
if (atmax && retval < decmax) return false;
|
||||
if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
|
||||
return false;
|
||||
}
|
||||
|
||||
c = value[last];
|
||||
if (isDec(c)) {
|
||||
|
||||
if (retval > decmax) return false;
|
||||
bool atmax = retval == decmax;
|
||||
retval *= 10;
|
||||
retval += c - '0';
|
||||
if (atmax && retval < decmax) return false;
|
||||
if (sign && negative) {
|
||||
if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
|
||||
retval >= (T)-signmax)
|
||||
return false;
|
||||
retval = -retval;
|
||||
}
|
||||
else
|
||||
if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
multiply:
|
||||
signed long long mult = 1;
|
||||
T val;
|
||||
switch (c) {
|
||||
case 'k':
|
||||
case 'K':
|
||||
if (i != last) return false;
|
||||
mult = 1024;
|
||||
val = signmax / mult;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
if (i != last) return false;
|
||||
mult = 1024 * 1024;
|
||||
val = signmax / mult;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
if (i != last) return false;
|
||||
mult = 1024 * 1024 * 1024;
|
||||
val = signmax / mult;
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
if (i >= last) return false;
|
||||
|
||||
mult = 0;
|
||||
for (i++; i <= last; i++) {
|
||||
c = value[i];
|
||||
if (!isDec(c))
|
||||
return false;
|
||||
|
||||
mult *= 10;
|
||||
mult += c - '0';
|
||||
}
|
||||
|
||||
for (i = 0; i < mult; i++) {
|
||||
if (retval > signmax / 10)
|
||||
return false;
|
||||
retval *= 10;
|
||||
if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
|
||||
return false;
|
||||
}
|
||||
if (sign && negative) {
|
||||
if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
|
||||
retval >= (T)-signmax)
|
||||
return false;
|
||||
retval = -retval;
|
||||
}
|
||||
else
|
||||
if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sign && negative)
|
||||
return false;
|
||||
|
||||
if (mult > (unsigned long long)signmax)
|
||||
return false;
|
||||
|
||||
if (retval > val)
|
||||
return false;
|
||||
|
||||
retval *= mult;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define STN(type) \
|
||||
template<> \
|
||||
bool to_number<type>(const string &value, type &retval) \
|
||||
{ return __to_number(value, retval); }
|
||||
|
||||
STN(unsigned long long)
|
||||
STN(signed long long)
|
||||
STN(unsigned long)
|
||||
STN(signed long)
|
||||
STN(unsigned int)
|
||||
STN(signed int)
|
||||
STN(unsigned short)
|
||||
STN(signed short)
|
||||
STN(unsigned char)
|
||||
STN(signed char)
|
||||
STN(char)
|
||||
|
||||
template<>
|
||||
bool to_number<bool>(const string &value, bool &retval)
|
||||
{
|
||||
string lowered = to_lower(value);
|
||||
|
||||
if (value == "0") {
|
||||
retval = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value == "1"){
|
||||
retval = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lowered == "false") {
|
||||
retval = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lowered == "true"){
|
||||
retval = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lowered == "no") {
|
||||
retval = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lowered == "yes"){
|
||||
retval = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
143
simulators/gem5/src/base/str.hh
Normal file
143
simulators/gem5/src/base/str.hh
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __STR_HH__
|
||||
#define __STR_HH__
|
||||
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
template<class> class Hash;
|
||||
template<>
|
||||
class Hash<std::string> {
|
||||
public:
|
||||
unsigned operator()(const std::string &s) {
|
||||
std::string::const_iterator i = s.begin();
|
||||
std::string::const_iterator end = s.end();
|
||||
unsigned hash = 5381;
|
||||
|
||||
while (i < end)
|
||||
hash = ((hash << 5) + hash) + *i++;
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
inline void
|
||||
eat_lead_white(std::string &s)
|
||||
{
|
||||
std::string::size_type off = s.find_first_not_of(' ');
|
||||
if (off != std::string::npos) {
|
||||
std::string::iterator begin = s.begin();
|
||||
s.erase(begin, begin + off);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
eat_end_white(std::string &s)
|
||||
{
|
||||
std::string::size_type off = s.find_last_not_of(' ');
|
||||
if (off != std::string::npos)
|
||||
s.erase(s.begin() + off + 1, s.end());
|
||||
}
|
||||
|
||||
inline void
|
||||
eat_white(std::string &s)
|
||||
{
|
||||
eat_lead_white(s);
|
||||
eat_end_white(s);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
to_lower(const std::string &s)
|
||||
{
|
||||
std::string lower;
|
||||
int len = s.size();
|
||||
|
||||
lower.reserve(len);
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
lower.push_back(tolower(s[i]));
|
||||
|
||||
return lower;
|
||||
}
|
||||
|
||||
// Split the string s into lhs and rhs on the first occurence of the
|
||||
// character c.
|
||||
bool
|
||||
split_first(const std::string &s, std::string &lhs, std::string &rhs, char c);
|
||||
|
||||
// Split the string s into lhs and rhs on the last occurence of the
|
||||
// character c.
|
||||
bool
|
||||
split_last(const std::string &s, std::string &lhs, std::string &rhs, char c);
|
||||
|
||||
// Tokenize the string <s> splitting on the character <token>, and
|
||||
// place the result in the string vector <vector>. If <ign> is true,
|
||||
// then empty result strings (due to trailing tokens, or consecutive
|
||||
// tokens) are skipped.
|
||||
void
|
||||
tokenize(std::vector<std::string> &vector, const std::string &s,
|
||||
char token, bool ign = true);
|
||||
|
||||
template <class T> bool
|
||||
to_number(const std::string &value, T &retval);
|
||||
|
||||
template <class T>
|
||||
inline std::string
|
||||
to_string(const T &value)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << value;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
// Put quotes around string arg if it contains spaces.
|
||||
inline std::string
|
||||
quote(const std::string &s)
|
||||
{
|
||||
std::string ret;
|
||||
bool quote = s.find(' ') != std::string::npos;
|
||||
|
||||
if (quote)
|
||||
ret = '"';
|
||||
|
||||
ret += s;
|
||||
|
||||
if (quote)
|
||||
ret += '"';
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif //__STR_HH__
|
||||
167
simulators/gem5/src/base/time.cc
Normal file
167
simulators/gem5/src/base/time.cc
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "base/time.hh"
|
||||
#include "config/use_posix_clock.hh"
|
||||
#include "sim/core.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
Time::_set(bool monotonic)
|
||||
{
|
||||
#if USE_POSIX_CLOCK
|
||||
::clock_gettime(monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME, &_time);
|
||||
#else
|
||||
timeval tv;
|
||||
::gettimeofday(&tv, NULL);
|
||||
operator=(tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Time::setTick(Tick ticks)
|
||||
{
|
||||
uint64_t nsecs = ticks / SimClock::Int::ns;
|
||||
set(nsecs / NSEC_PER_SEC, nsecs % NSEC_PER_SEC);
|
||||
}
|
||||
|
||||
Tick
|
||||
Time::getTick() const
|
||||
{
|
||||
return (nsec() + sec() * NSEC_PER_SEC) * SimClock::Int::ns;
|
||||
}
|
||||
|
||||
string
|
||||
Time::date(const string &format) const
|
||||
{
|
||||
time_t sec = this->sec();
|
||||
char buf[256];
|
||||
|
||||
if (format.empty()) {
|
||||
#ifdef __SUNPRO_CC
|
||||
ctime_r(&sec, buf, sizeof(buf));
|
||||
#else
|
||||
ctime_r(&sec, buf);
|
||||
#endif
|
||||
buf[24] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct tm *tm = localtime(&sec);
|
||||
strftime(buf, sizeof(buf), format.c_str(), tm);
|
||||
return buf;
|
||||
}
|
||||
|
||||
string
|
||||
Time::time() const
|
||||
{
|
||||
double time = double(*this);
|
||||
double secs = fmod(time, 60.0);
|
||||
double all_mins = floor(time / 60.0);
|
||||
double mins = fmod(all_mins, 60.0);
|
||||
double hours = floor(all_mins / 60.0);
|
||||
|
||||
stringstream str;
|
||||
|
||||
if (hours > 0.0) {
|
||||
if (hours < 10.0)
|
||||
str << '0';
|
||||
str << hours << ':';
|
||||
}
|
||||
|
||||
if (mins > 0.0) {
|
||||
if (mins < 10.0)
|
||||
str << '0';
|
||||
str << mins << ':';
|
||||
}
|
||||
|
||||
if (secs < 10.0 && !str.str().empty())
|
||||
str << '0';
|
||||
str << secs;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
void
|
||||
Time::serialize(const std::string &base, ostream &os)
|
||||
{
|
||||
paramOut(os, base + ".sec", sec());
|
||||
paramOut(os, base + ".nsec", nsec());
|
||||
}
|
||||
|
||||
void
|
||||
Time::unserialize(const std::string &base, Checkpoint *cp,
|
||||
const string §ion)
|
||||
{
|
||||
time_t secs;
|
||||
time_t nsecs;
|
||||
paramIn(cp, section, base + ".sec", secs);
|
||||
paramIn(cp, section, base + ".nsec", nsecs);
|
||||
sec(secs);
|
||||
nsec(nsecs);
|
||||
}
|
||||
|
||||
void
|
||||
sleep(const Time &time)
|
||||
{
|
||||
timespec ts = time;
|
||||
|
||||
#if USE_POSIX_CLOCK
|
||||
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
|
||||
#else
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
time_t
|
||||
mkutctime(struct tm *time)
|
||||
{
|
||||
time_t ret;
|
||||
char *tz;
|
||||
|
||||
tz = getenv("TZ");
|
||||
setenv("TZ", "", 1);
|
||||
tzset();
|
||||
ret = mktime(time);
|
||||
if (tz)
|
||||
setenv("TZ", tz, 1);
|
||||
else
|
||||
unsetenv("TZ");
|
||||
tzset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
273
simulators/gem5/src/base/time.hh
Normal file
273
simulators/gem5/src/base/time.hh
Normal file
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Steve Reinhardt
|
||||
* Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_TIME_HH__
|
||||
#define __BASE_TIME_HH__
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <iosfwd>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "base/types.hh"
|
||||
|
||||
class Checkpoint;
|
||||
|
||||
class Time
|
||||
{
|
||||
protected:
|
||||
timespec _time;
|
||||
|
||||
/**
|
||||
* Internal time set function
|
||||
*/
|
||||
void _set(bool monotonic);
|
||||
|
||||
public:
|
||||
static const long NSEC_PER_SEC = 1000 * 1000 * 1000;
|
||||
static const long NSEC_PER_MSEC = 1000 * 1000;
|
||||
static const long NSEC_PER_USEC = 1000;
|
||||
|
||||
public:
|
||||
explicit Time() { clear(); }
|
||||
explicit Time(double sec) { operator=(sec); }
|
||||
Time(const Time &val) : _time(val._time) { }
|
||||
Time(uint64_t sec, uint64_t nsec) { set(sec, nsec); }
|
||||
Time(const timeval &tv) { operator=(tv); }
|
||||
Time(const timespec &ts) { operator=(ts); }
|
||||
|
||||
/**
|
||||
* Accessors for getting and setting the current clock
|
||||
*/
|
||||
time_t sec() const { return _time.tv_sec; }
|
||||
long msec() const { return _time.tv_nsec / NSEC_PER_MSEC; }
|
||||
long usec() const { return _time.tv_nsec / NSEC_PER_USEC; }
|
||||
long nsec() const { return _time.tv_nsec; }
|
||||
|
||||
void sec(time_t sec) { _time.tv_sec = sec; }
|
||||
void msec(long msec) { _time.tv_nsec = msec * NSEC_PER_MSEC; }
|
||||
void usec(long usec) { _time.tv_nsec = usec * NSEC_PER_USEC; }
|
||||
void nsec(long nsec) { _time.tv_nsec = nsec; }
|
||||
|
||||
/**
|
||||
* Clear the time
|
||||
*/
|
||||
void clear() { memset(&_time, 0, sizeof(_time)); }
|
||||
|
||||
/**
|
||||
* Use this to set time for the purposes of time measurement (use
|
||||
* a monotonic clock if it is available
|
||||
*/
|
||||
void setTimer() { _set(true); }
|
||||
|
||||
/**
|
||||
* Use this to set the time to the actual current time
|
||||
*/
|
||||
void setWallclock() { _set(false); }
|
||||
|
||||
/**
|
||||
* Set the current time
|
||||
*/
|
||||
void set(time_t _sec, long _nsec) { sec(_sec); nsec(_nsec); }
|
||||
|
||||
/**
|
||||
* Set the current time from a value measured in Ticks
|
||||
* @param ticks Number of ticks to convert into a time.
|
||||
*/
|
||||
void setTick(Tick ticks);
|
||||
|
||||
/**
|
||||
* Get the current time from a value measured in Ticks
|
||||
* @return Time value measured in Ticks.
|
||||
*/
|
||||
Tick getTick() const;
|
||||
|
||||
const Time &
|
||||
operator=(const Time &other)
|
||||
{
|
||||
sec(other.sec());
|
||||
nsec(other.nsec());
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Time &
|
||||
operator=(double new_time)
|
||||
{
|
||||
double seconds = floor(new_time);
|
||||
sec((time_t)seconds);
|
||||
nsec((long)((seconds - new_time) * 1e9));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Time &
|
||||
operator=(const timeval &tv)
|
||||
{
|
||||
sec(tv.tv_sec);
|
||||
nsec(tv.tv_usec * 1000);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Time &
|
||||
operator=(const timespec &ts)
|
||||
{
|
||||
sec(ts.tv_sec);
|
||||
nsec(ts.tv_nsec);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time in floating point seconds
|
||||
*/
|
||||
operator double() const
|
||||
{
|
||||
return (double)sec() + ((double)nsec()) * 1e-9;
|
||||
}
|
||||
|
||||
/**
|
||||
* operators for time conversion
|
||||
*/
|
||||
operator timespec() const { return _time; }
|
||||
operator timeval() const
|
||||
{
|
||||
timeval tv;
|
||||
tv.tv_sec = sec();
|
||||
tv.tv_usec = usec();
|
||||
return tv;
|
||||
}
|
||||
|
||||
const Time &
|
||||
operator+=(const Time &other)
|
||||
{
|
||||
|
||||
_time.tv_sec += other.sec();
|
||||
_time.tv_nsec += other.nsec();
|
||||
if (_time.tv_nsec > NSEC_PER_SEC) {
|
||||
_time.tv_sec++;
|
||||
_time.tv_nsec -= NSEC_PER_SEC;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Time &
|
||||
operator-=(const Time &other)
|
||||
{
|
||||
_time.tv_sec -= other.sec();
|
||||
_time.tv_nsec -= other.nsec();
|
||||
if (_time.tv_nsec < 0) {
|
||||
_time.tv_sec--;
|
||||
_time.tv_nsec += NSEC_PER_SEC;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string date(const std::string &format = "") const;
|
||||
std::string time() const;
|
||||
|
||||
void serialize(const std::string &base, std::ostream &os);
|
||||
void unserialize(const std::string &base, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
};
|
||||
|
||||
void sleep(const Time &time);
|
||||
|
||||
inline bool
|
||||
operator==(const Time &l, const Time &r)
|
||||
{
|
||||
return l.sec() == r.sec() && l.nsec() == r.nsec();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(const Time &l, const Time &r)
|
||||
{
|
||||
return l.sec() != r.sec() || l.nsec() != r.nsec();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(const Time &l, const Time &r)
|
||||
{
|
||||
return (l.sec() < r.sec()) ||
|
||||
(l.sec() == r.sec() && l.nsec() < r.nsec());
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<=(const Time &l, const Time &r)
|
||||
{
|
||||
return (l.sec() < r.sec()) ||
|
||||
(l.sec() == r.sec() && l.nsec() <= r.nsec());
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>(const Time &l, const Time &r)
|
||||
{
|
||||
return (l.sec() > r.sec()) ||
|
||||
(l.sec() == r.sec() && l.nsec() > r.nsec());
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>=(const Time &l, const Time &r)
|
||||
{
|
||||
return (l.sec() > r.sec()) ||
|
||||
(l.sec() == r.sec() && l.nsec() >= r.nsec());
|
||||
}
|
||||
|
||||
inline Time
|
||||
operator+(const Time &l, const Time &r)
|
||||
{
|
||||
Time time(l);
|
||||
time += r;
|
||||
return time;
|
||||
}
|
||||
|
||||
inline Time
|
||||
operator-(const Time &l, const Time &r)
|
||||
{
|
||||
Time time(l);
|
||||
time -= r;
|
||||
return time;
|
||||
}
|
||||
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &out, const Time &time)
|
||||
{
|
||||
out << time.date();
|
||||
return out;
|
||||
}
|
||||
|
||||
time_t mkutctime(struct tm *time);
|
||||
|
||||
#endif // __BASE_TIME_HH__
|
||||
152
simulators/gem5/src/base/trace.cc
Normal file
152
simulators/gem5/src/base/trace.cc
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2006 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "base/misc.hh"
|
||||
#include "base/output.hh"
|
||||
#include "base/str.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "base/varargs.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Trace {
|
||||
|
||||
const string DefaultName("global");
|
||||
bool enabled = false;
|
||||
|
||||
//
|
||||
// This variable holds the output stream for debug information. Other
|
||||
// than setting up/redirecting this stream, do *NOT* reference this
|
||||
// directly; use DebugOut() (see below) to access this stream for
|
||||
// output.
|
||||
//
|
||||
ostream *dprintf_stream = &cerr;
|
||||
ostream &
|
||||
output()
|
||||
{
|
||||
return *dprintf_stream;
|
||||
}
|
||||
|
||||
void
|
||||
setOutput(const string &filename)
|
||||
{
|
||||
dprintf_stream = simout.find(filename);
|
||||
if (!dprintf_stream)
|
||||
dprintf_stream = simout.create(filename);
|
||||
}
|
||||
|
||||
ObjectMatch ignore;
|
||||
|
||||
void
|
||||
dprintf(Tick when, const std::string &name, const char *format,
|
||||
CPRINTF_DEFINITION)
|
||||
{
|
||||
if (!name.empty() && ignore.match(name))
|
||||
return;
|
||||
|
||||
std::ostream &os = *dprintf_stream;
|
||||
|
||||
string fmt = "";
|
||||
CPrintfArgsList args(VARARGS_ALLARGS);
|
||||
|
||||
if (!name.empty()) {
|
||||
fmt = "%s: " + fmt;
|
||||
args.push_front(name);
|
||||
}
|
||||
|
||||
if (when != (Tick)-1) {
|
||||
fmt = "%7d: " + fmt;
|
||||
args.push_front(when);
|
||||
}
|
||||
|
||||
fmt += format;
|
||||
|
||||
ccprintf(os, fmt.c_str(), args);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
void
|
||||
dump(Tick when, const std::string &name, const void *d, int len)
|
||||
{
|
||||
if (!name.empty() && ignore.match(name))
|
||||
return;
|
||||
|
||||
std::ostream &os = *dprintf_stream;
|
||||
|
||||
string fmt = "";
|
||||
CPrintfArgsList args;
|
||||
|
||||
if (!name.empty()) {
|
||||
fmt = "%s: " + fmt;
|
||||
args.push_front(name);
|
||||
}
|
||||
|
||||
if (when != (Tick)-1) {
|
||||
fmt = "%7d: " + fmt;
|
||||
args.push_front(when);
|
||||
}
|
||||
|
||||
const char *data = static_cast<const char *>(d);
|
||||
int c, i, j;
|
||||
for (i = 0; i < len; i += 16) {
|
||||
ccprintf(os, fmt, args);
|
||||
ccprintf(os, "%08x ", i);
|
||||
c = len - i;
|
||||
if (c > 16) c = 16;
|
||||
|
||||
for (j = 0; j < c; j++) {
|
||||
ccprintf(os, "%02x ", data[i + j] & 0xff);
|
||||
if ((j & 0xf) == 7 && j > 0)
|
||||
ccprintf(os, " ");
|
||||
}
|
||||
|
||||
for (; j < 16; j++)
|
||||
ccprintf(os, " ");
|
||||
ccprintf(os, " ");
|
||||
|
||||
for (j = 0; j < c; j++) {
|
||||
int ch = data[i + j] & 0x7f;
|
||||
ccprintf(os, "%c", (char)(isprint(ch) ? ch : ' '));
|
||||
}
|
||||
|
||||
ccprintf(os, "\n");
|
||||
|
||||
if (c < 16)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Trace
|
||||
138
simulators/gem5/src/base/trace.hh
Normal file
138
simulators/gem5/src/base/trace.hh
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2006 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __BASE_TRACE_HH__
|
||||
#define __BASE_TRACE_HH__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/debug.hh"
|
||||
#include "base/match.hh"
|
||||
#include "base/types.hh"
|
||||
#include "sim/core.hh"
|
||||
|
||||
namespace Trace {
|
||||
|
||||
using Debug::SimpleFlag;
|
||||
using Debug::CompoundFlag;
|
||||
|
||||
std::ostream &output();
|
||||
void setOutput(const std::string &filename);
|
||||
|
||||
extern bool enabled;
|
||||
bool changeFlag(const char *str, bool value);
|
||||
void dumpStatus();
|
||||
|
||||
extern ObjectMatch ignore;
|
||||
extern const std::string DefaultName;
|
||||
|
||||
void dprintf(Tick when, const std::string &name, const char *format,
|
||||
CPRINTF_DECLARATION);
|
||||
void dump(Tick when, const std::string &name, const void *data, int len);
|
||||
|
||||
} // namespace Trace
|
||||
|
||||
// This silly little class allows us to wrap a string in a functor
|
||||
// object so that we can give a name() that DPRINTF will like
|
||||
struct StringWrap
|
||||
{
|
||||
std::string str;
|
||||
StringWrap(const std::string &s) : str(s) {}
|
||||
const std::string &operator()() const { return str; }
|
||||
};
|
||||
|
||||
inline const std::string &name() { return Trace::DefaultName; }
|
||||
|
||||
//
|
||||
// DPRINTF is a debugging trace facility that allows one to
|
||||
// selectively enable tracing statements. To use DPRINTF, there must
|
||||
// be a function or functor called name() that returns a const
|
||||
// std::string & in the current scope.
|
||||
//
|
||||
// If you desire that the automatic printing not occur, use DPRINTFR
|
||||
// (R for raw)
|
||||
//
|
||||
|
||||
#if TRACING_ON
|
||||
|
||||
#define DTRACE(x) ((Debug::x) && Trace::enabled)
|
||||
|
||||
#define DDUMP(x, data, count) do { \
|
||||
using namespace Debug; \
|
||||
if (DTRACE(x)) \
|
||||
Trace::dump(curTick(), name(), data, count); \
|
||||
} while (0)
|
||||
|
||||
#define DPRINTF(x, ...) do { \
|
||||
using namespace Debug; \
|
||||
if (DTRACE(x)) \
|
||||
Trace::dprintf(curTick(), name(), __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define DPRINTFS(x, s, ...) do { \
|
||||
using namespace Debug; \
|
||||
if (DTRACE(x)) \
|
||||
Trace::dprintf(curTick(), s->name(), __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define DPRINTFR(x, ...) do { \
|
||||
using namespace Debug; \
|
||||
if (DTRACE(x)) \
|
||||
Trace::dprintf((Tick)-1, std::string(), __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define DDUMPN(data, count) do { \
|
||||
Trace::dump(curTick(), name(), data, count); \
|
||||
} while (0)
|
||||
|
||||
#define DPRINTFN(...) do { \
|
||||
Trace::dprintf(curTick(), name(), __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define DPRINTFNR(...) do { \
|
||||
Trace::dprintf((Tick)-1, string(), __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#else // !TRACING_ON
|
||||
|
||||
#define DTRACE(x) (false)
|
||||
#define DDUMP(x, data, count) do {} while (0)
|
||||
#define DPRINTF(x, ...) do {} while (0)
|
||||
#define DPRINTFS(x, ...) do {} while (0)
|
||||
#define DPRINTFR(...) do {} while (0)
|
||||
#define DDUMPN(data, count) do {} while (0)
|
||||
#define DPRINTFN(...) do {} while (0)
|
||||
#define DPRINTFNR(...) do {} while (0)
|
||||
|
||||
#endif // TRACING_ON
|
||||
|
||||
#endif // __BASE_TRACE_HH__
|
||||
360
simulators/gem5/src/base/trie.hh
Normal file
360
simulators/gem5/src/base/trie.hh
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Google
|
||||
* 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.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __BASE_TRIE_HH__
|
||||
#define __BASE_TRIE_HH__
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
// Key has to be an integral type.
|
||||
template <class Key, class Value>
|
||||
class Trie
|
||||
{
|
||||
protected:
|
||||
struct Node
|
||||
{
|
||||
Key key;
|
||||
Key mask;
|
||||
|
||||
bool
|
||||
matches(Key test)
|
||||
{
|
||||
return (test & mask) == key;
|
||||
}
|
||||
|
||||
Value *value;
|
||||
|
||||
Node *parent;
|
||||
Node *kids[2];
|
||||
|
||||
Node(Key _key, Key _mask, Value *_val) :
|
||||
key(_key & _mask), mask(_mask), value(_val),
|
||||
parent(NULL)
|
||||
{
|
||||
kids[0] = NULL;
|
||||
kids[1] = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
if (kids[1]) {
|
||||
kids[1]->clear();
|
||||
delete kids[1];
|
||||
kids[1] = NULL;
|
||||
}
|
||||
if (kids[0]) {
|
||||
kids[0]->clear();
|
||||
delete kids[0];
|
||||
kids[0] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dump(int level)
|
||||
{
|
||||
for (int i = 1; i < level; i++) {
|
||||
cprintf("|");
|
||||
}
|
||||
if (level == 0)
|
||||
cprintf("Root ");
|
||||
else
|
||||
cprintf("+ ");
|
||||
cprintf("(%p, %p, %#X, %#X, %p)\n", parent, this, key, mask, value);
|
||||
if (kids[0])
|
||||
kids[0]->dump(level + 1);
|
||||
if (kids[1])
|
||||
kids[1]->dump(level + 1);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
Node head;
|
||||
|
||||
public:
|
||||
typedef Node *Handle;
|
||||
|
||||
Trie() : head(0, 0, NULL)
|
||||
{}
|
||||
|
||||
static const unsigned MaxBits = sizeof(Key) * 8;
|
||||
|
||||
private:
|
||||
/**
|
||||
* A utility method which checks whether the key being looked up lies
|
||||
* beyond the Node being examined. If so, it returns true and advances the
|
||||
* node being examined.
|
||||
* @param parent The node we're currently "at", which can be updated.
|
||||
* @param kid The node we may want to move to.
|
||||
* @param key The key we're looking for.
|
||||
* @param new_mask The mask to use when matching against the key.
|
||||
* @return Whether the current Node was advanced.
|
||||
*/
|
||||
bool
|
||||
goesAfter(Node **parent, Node *kid, Key key, Key new_mask)
|
||||
{
|
||||
if (kid && kid->matches(key) && (kid->mask & new_mask) == kid->mask) {
|
||||
*parent = kid;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method which extends a mask value one more bit towards the
|
||||
* lsb. This is almost just a signed right shift, except that the shifted
|
||||
* in bits are technically undefined. This is also slightly complicated by
|
||||
* the zero case.
|
||||
* @param orig The original mask to extend.
|
||||
* @return The extended mask.
|
||||
*/
|
||||
Key
|
||||
extendMask(Key orig)
|
||||
{
|
||||
// Just in case orig was 0.
|
||||
const Key msb = ULL(1) << (MaxBits - 1);
|
||||
return orig | (orig >> 1) | msb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method which looks up the Handle corresponding to a particular key. This
|
||||
* is useful if you want to delete the Handle corresponding to a key since
|
||||
* the "remove" function takes a Handle as its argument.
|
||||
* @param key The key to look up.
|
||||
* @return The first Handle matching this key, or NULL if none was found.
|
||||
*/
|
||||
Handle
|
||||
lookupHandle(Key key)
|
||||
{
|
||||
Node *node = &head;
|
||||
while (node) {
|
||||
if (node->value)
|
||||
return node;
|
||||
|
||||
if (node->kids[0] && node->kids[0]->matches(key))
|
||||
node = node->kids[0];
|
||||
else if (node->kids[1] && node->kids[1]->matches(key))
|
||||
node = node->kids[1];
|
||||
else
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Method which inserts a key/value pair into the trie.
|
||||
* @param key The key which can later be used to look up this value.
|
||||
* @param width How many bits of the key (from msb) should be used.
|
||||
* @param val A pointer to the value to store in the trie.
|
||||
* @return A Handle corresponding to this value.
|
||||
*/
|
||||
Handle
|
||||
insert(Key key, unsigned width, Value *val)
|
||||
{
|
||||
// Build a mask which masks off all the bits we don't care about.
|
||||
Key new_mask = ~(Key)0;
|
||||
if (width < MaxBits)
|
||||
new_mask <<= (MaxBits - width);
|
||||
// Use it to tidy up the key.
|
||||
key &= new_mask;
|
||||
|
||||
// Walk past all the nodes this new node will be inserted after. They
|
||||
// can be ignored for the purposes of this function.
|
||||
Node *node = &head;
|
||||
while (goesAfter(&node, node->kids[0], key, new_mask) ||
|
||||
goesAfter(&node, node->kids[1], key, new_mask))
|
||||
{}
|
||||
assert(node);
|
||||
|
||||
Key cur_mask = node->mask;
|
||||
// If we're already where the value needs to be...
|
||||
if (cur_mask == new_mask) {
|
||||
assert(!node->value);
|
||||
node->value = val;
|
||||
return node;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 2; i++) {
|
||||
Node *&kid = node->kids[i];
|
||||
Node *new_node;
|
||||
if (!kid) {
|
||||
// No kid. Add a new one.
|
||||
new_node = new Node(key, new_mask, val);
|
||||
new_node->parent = node;
|
||||
kid = new_node;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
// Walk down the leg until something doesn't match or we run out
|
||||
// of bits.
|
||||
Key last_mask;
|
||||
bool done;
|
||||
do {
|
||||
last_mask = cur_mask;
|
||||
cur_mask = extendMask(cur_mask);
|
||||
done = ((key & cur_mask) != (kid->key & cur_mask)) ||
|
||||
last_mask == new_mask;
|
||||
} while (!done);
|
||||
cur_mask = last_mask;
|
||||
|
||||
// If this isn't the right leg to go down at all, skip it.
|
||||
if (cur_mask == node->mask)
|
||||
continue;
|
||||
|
||||
// At the point we walked to above, add a new node.
|
||||
new_node = new Node(key, cur_mask, NULL);
|
||||
new_node->parent = node;
|
||||
kid->parent = new_node;
|
||||
new_node->kids[0] = kid;
|
||||
kid = new_node;
|
||||
|
||||
// If we ran out of bits, the value goes right here.
|
||||
if (cur_mask == new_mask) {
|
||||
new_node->value = val;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
// Still more bits to deal with, so add a new node for that path.
|
||||
new_node = new Node(key, new_mask, val);
|
||||
new_node->parent = kid;
|
||||
kid->kids[1] = new_node;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
panic("Reached the end of the Trie insert function!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method which looks up the Value corresponding to a particular key.
|
||||
* @param key The key to look up.
|
||||
* @return The first Value matching this key, or NULL if none was found.
|
||||
*/
|
||||
Value *
|
||||
lookup(Key key)
|
||||
{
|
||||
Node *node = lookupHandle(key);
|
||||
if (node)
|
||||
return node->value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to delete a value from the trie.
|
||||
* @param node A Handle to remove.
|
||||
* @return The Value pointer from the removed entry.
|
||||
*/
|
||||
Value *
|
||||
remove(Handle handle)
|
||||
{
|
||||
Node *node = handle;
|
||||
Value *val = node->value;
|
||||
if (node->kids[1]) {
|
||||
assert(node->value);
|
||||
node->value = NULL;
|
||||
return val;
|
||||
}
|
||||
if (!node->parent)
|
||||
panic("Trie: Can't remove root node.\n");
|
||||
|
||||
Node *parent = node->parent;
|
||||
|
||||
// If there's a kid, fix up it's parent pointer.
|
||||
if (node->kids[0])
|
||||
node->kids[0]->parent = parent;
|
||||
// Figure out which kid we are, and update our parent's pointers.
|
||||
if (parent->kids[0] == node)
|
||||
parent->kids[0] = node->kids[0];
|
||||
else if (parent->kids[1] == node)
|
||||
parent->kids[1] = node->kids[0];
|
||||
else
|
||||
panic("Trie: Inconsistent parent/kid relationship.\n");
|
||||
// Make sure if the parent only has one kid, it's kid[0].
|
||||
if (parent->kids[1] && !parent->kids[0]) {
|
||||
parent->kids[0] = parent->kids[1];
|
||||
parent->kids[1] = NULL;
|
||||
}
|
||||
|
||||
// If the parent has less than two kids and no cargo and isn't the
|
||||
// root, delete it too.
|
||||
if (!parent->kids[1] && !parent->value && parent->parent)
|
||||
remove(parent);
|
||||
delete node;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to lookup a value from the trie and then delete it.
|
||||
* @param key The key to look up and then remove.
|
||||
* @return The Value pointer from the removed entry, if any.
|
||||
*/
|
||||
Value *
|
||||
remove(Key key)
|
||||
{
|
||||
Handle handle = lookupHandle(key);
|
||||
if (!handle)
|
||||
return NULL;
|
||||
return remove(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* A method which removes all key/value pairs from the trie. This is more
|
||||
* efficient than trying to remove elements individually.
|
||||
*/
|
||||
void
|
||||
clear()
|
||||
{
|
||||
head.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* A debugging method which prints the contents of this trie.
|
||||
* @param title An identifying title to put in the dump header.
|
||||
*/
|
||||
void
|
||||
dump(const char *title)
|
||||
{
|
||||
cprintf("**************************************************\n");
|
||||
cprintf("*** Start of Trie: %s\n", title);
|
||||
cprintf("*** (parent, me, key, mask, value pointer)\n");
|
||||
cprintf("**************************************************\n");
|
||||
head.dump(0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
110
simulators/gem5/src/base/types.hh
Normal file
110
simulators/gem5/src/base/types.hh
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines global host-dependent types:
|
||||
* Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
|
||||
*/
|
||||
|
||||
#ifndef __BASE_TYPES_HH__
|
||||
#define __BASE_TYPES_HH__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/** uint64_t constant */
|
||||
#define ULL(N) ((uint64_t)N##ULL)
|
||||
/** int64_t constant */
|
||||
#define LL(N) ((int64_t)N##LL)
|
||||
|
||||
/** Statistics counter type. Not much excuse for not using a 64-bit
|
||||
* integer here, but if you're desperate and only run short
|
||||
* simulations you could make this 32 bits.
|
||||
*/
|
||||
typedef int64_t Counter;
|
||||
|
||||
/**
|
||||
* Clock cycle count type.
|
||||
* @note using an unsigned breaks the cache.
|
||||
*/
|
||||
typedef int64_t Tick;
|
||||
typedef uint64_t UTick;
|
||||
|
||||
const Tick MaxTick = LL(0x7fffffffffffffff);
|
||||
|
||||
/**
|
||||
* Address type
|
||||
* This will probably be moved somewhere else in the near future.
|
||||
* This should be at least as big as the biggest address width in use
|
||||
* in the system, which will probably be 64 bits.
|
||||
*/
|
||||
typedef uint64_t Addr;
|
||||
|
||||
typedef uint16_t MicroPC;
|
||||
|
||||
static const MicroPC MicroPCRomBit = 1 << (sizeof(MicroPC) * 8 - 1);
|
||||
|
||||
static inline MicroPC
|
||||
romMicroPC(MicroPC upc)
|
||||
{
|
||||
return upc | MicroPCRomBit;
|
||||
}
|
||||
|
||||
static inline MicroPC
|
||||
normalMicroPC(MicroPC upc)
|
||||
{
|
||||
return upc & ~MicroPCRomBit;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
isRomMicroPC(MicroPC upc)
|
||||
{
|
||||
return MicroPCRomBit & upc;
|
||||
}
|
||||
|
||||
const Addr MaxAddr = (Addr)-1;
|
||||
|
||||
/**
|
||||
* Thread index/ID type
|
||||
*/
|
||||
typedef int16_t ThreadID;
|
||||
const ThreadID InvalidThreadID = (ThreadID)-1;
|
||||
|
||||
/**
|
||||
* Port index/ID type, and a symbolic name for an invalid port id.
|
||||
*/
|
||||
typedef int16_t PortID;
|
||||
const PortID InvalidPortID = (PortID)-1;
|
||||
|
||||
class FaultBase;
|
||||
template <class T> class RefCountingPtr;
|
||||
typedef RefCountingPtr<FaultBase> Fault;
|
||||
|
||||
#endif // __BASE_TYPES_HH__
|
||||
43
simulators/gem5/src/base/userinfo.cc
Normal file
43
simulators/gem5/src/base/userinfo.cc
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string
|
||||
username()
|
||||
{
|
||||
struct passwd *pwd = getpwuid(getuid());
|
||||
|
||||
return pwd->pw_name;
|
||||
}
|
||||
38
simulators/gem5/src/base/userinfo.hh
Normal file
38
simulators/gem5/src/base/userinfo.hh
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_USERINFO_HH__
|
||||
#define __BASE_USERINFO_HH__
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string username();
|
||||
|
||||
#endif // __BASE_USERINFO_HH__
|
||||
308
simulators/gem5/src/base/varargs.hh
Normal file
308
simulators/gem5/src/base/varargs.hh
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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.
|
||||
*
|
||||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __BASE_VARARGS_HH__
|
||||
#define __BASE_VARARGS_HH__
|
||||
|
||||
#include "base/refcnt.hh"
|
||||
|
||||
#define VARARGS_DECLARATION(receiver) \
|
||||
VarArgs::Argument<receiver> a01 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a02 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a03 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a04 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a05 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a06 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a07 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a08 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a09 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a10 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a11 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a12 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a13 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a14 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a15 = VarArgs::Null(), \
|
||||
VarArgs::Argument<receiver> a16 = VarArgs::Null()
|
||||
|
||||
#define VARARGS_DEFINITION(receiver) \
|
||||
VarArgs::Argument<receiver> a01, \
|
||||
VarArgs::Argument<receiver> a02, \
|
||||
VarArgs::Argument<receiver> a03, \
|
||||
VarArgs::Argument<receiver> a04, \
|
||||
VarArgs::Argument<receiver> a05, \
|
||||
VarArgs::Argument<receiver> a06, \
|
||||
VarArgs::Argument<receiver> a07, \
|
||||
VarArgs::Argument<receiver> a08, \
|
||||
VarArgs::Argument<receiver> a09, \
|
||||
VarArgs::Argument<receiver> a10, \
|
||||
VarArgs::Argument<receiver> a11, \
|
||||
VarArgs::Argument<receiver> a12, \
|
||||
VarArgs::Argument<receiver> a13, \
|
||||
VarArgs::Argument<receiver> a14, \
|
||||
VarArgs::Argument<receiver> a15, \
|
||||
VarArgs::Argument<receiver> a16
|
||||
|
||||
#define VARARGS_ALLARGS \
|
||||
a01, a02, a03, a04, a05, a06, a07, a08, \
|
||||
a09, a10, a11, a12, a13, a14, a15, a16
|
||||
|
||||
#define VARARGS_ADDARGS(receiver) do { \
|
||||
do { \
|
||||
if (!a01) break; \
|
||||
a01.add_arg(receiver); \
|
||||
if (!a02) break; \
|
||||
a02.add_arg(receiver); \
|
||||
if (!a03) break; \
|
||||
a03.add_arg(receiver); \
|
||||
if (!a04) break; \
|
||||
a04.add_arg(receiver); \
|
||||
if (!a05) break; \
|
||||
a05.add_arg(receiver); \
|
||||
if (!a06) break; \
|
||||
a06.add_arg(receiver); \
|
||||
if (!a07) break; \
|
||||
a07.add_arg(receiver); \
|
||||
if (!a08) break; \
|
||||
a08.add_arg(receiver); \
|
||||
if (!a09) break; \
|
||||
a09.add_arg(receiver); \
|
||||
if (!a10) break; \
|
||||
a10.add_arg(receiver); \
|
||||
if (!a11) break; \
|
||||
a11.add_arg(receiver); \
|
||||
if (!a12) break; \
|
||||
a12.add_arg(receiver); \
|
||||
if (!a13) break; \
|
||||
a13.add_arg(receiver); \
|
||||
if (!a14) break; \
|
||||
a14.add_arg(receiver); \
|
||||
if (!a15) break; \
|
||||
a15.add_arg(receiver); \
|
||||
if (!a16) break; \
|
||||
a16.add_arg(receiver); \
|
||||
} while (0); \
|
||||
receiver.end_args(); \
|
||||
} while (0)
|
||||
|
||||
namespace VarArgs {
|
||||
|
||||
struct Null {};
|
||||
|
||||
template <typename T>
|
||||
struct Traits
|
||||
{
|
||||
enum { enabled = true };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Traits<Null>
|
||||
{
|
||||
enum { enabled = false };
|
||||
};
|
||||
|
||||
template <class RECV>
|
||||
struct Base : public RefCounted
|
||||
{
|
||||
virtual void add_arg(RECV &receiver) const = 0;
|
||||
};
|
||||
|
||||
template <typename T, class RECV>
|
||||
struct Any : public Base<RECV>
|
||||
{
|
||||
const T &argument;
|
||||
|
||||
Any(const T &arg) : argument(arg) {}
|
||||
|
||||
virtual void
|
||||
add_arg(RECV &receiver) const
|
||||
{
|
||||
receiver.add_arg(argument);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, class RECV>
|
||||
struct Any<T *, RECV> : public Base<RECV>
|
||||
{
|
||||
const T *argument;
|
||||
|
||||
Any(const T *arg) : argument(arg) {}
|
||||
|
||||
virtual void
|
||||
add_arg(RECV &receiver) const
|
||||
{
|
||||
receiver.add_arg(argument);
|
||||
}
|
||||
};
|
||||
|
||||
template <class RECV>
|
||||
struct Argument : public RefCountingPtr<Base<RECV> >
|
||||
{
|
||||
typedef RefCountingPtr<VarArgs::Base<RECV> > Base;
|
||||
|
||||
Argument() { }
|
||||
Argument(const Null &null) { }
|
||||
template <typename T>
|
||||
Argument(const T& arg) : Base(new Any<T, RECV>(arg)) { }
|
||||
template <typename T>
|
||||
Argument(const T* arg) : Base(new Any<T *, RECV>(arg)) { }
|
||||
|
||||
void
|
||||
add_arg(RECV &receiver) const
|
||||
{
|
||||
if (this->data)
|
||||
this->data->add_arg(receiver);
|
||||
}
|
||||
};
|
||||
|
||||
template<class RECV>
|
||||
class List
|
||||
{
|
||||
public:
|
||||
typedef VarArgs::Argument<RECV> Argument;
|
||||
typedef std::list<Argument> list;
|
||||
typedef typename list::iterator iterator;
|
||||
typedef typename list::const_iterator const_iterator;
|
||||
typedef typename list::size_type size_type;
|
||||
|
||||
protected:
|
||||
list l;
|
||||
|
||||
public:
|
||||
List() {}
|
||||
List(Argument a01, Argument a02, Argument a03, Argument a04,
|
||||
Argument a05, Argument a06, Argument a07, Argument a08,
|
||||
Argument a09, Argument a10, Argument a11, Argument a12,
|
||||
Argument a13, Argument a14, Argument a15, Argument a16)
|
||||
{
|
||||
if (!a01) return;
|
||||
l.push_back(a01);
|
||||
if (!a02) return;
|
||||
l.push_back(a02);
|
||||
if (!a03) return;
|
||||
l.push_back(a03);
|
||||
if (!a04) return;
|
||||
l.push_back(a04);
|
||||
if (!a05) return;
|
||||
l.push_back(a05);
|
||||
if (!a06) return;
|
||||
l.push_back(a06);
|
||||
if (!a07) return;
|
||||
l.push_back(a07);
|
||||
if (!a08) return;
|
||||
l.push_back(a08);
|
||||
if (!a09) return;
|
||||
l.push_back(a09);
|
||||
if (!a10) return;
|
||||
l.push_back(a10);
|
||||
if (!a11) return;
|
||||
l.push_back(a11);
|
||||
if (!a12) return;
|
||||
l.push_back(a12);
|
||||
if (!a13) return;
|
||||
l.push_back(a13);
|
||||
if (!a14) return;
|
||||
l.push_back(a14);
|
||||
if (!a15) return;
|
||||
l.push_back(a15);
|
||||
if (!a16) return;
|
||||
l.push_back(a16);
|
||||
}
|
||||
|
||||
size_type size() const { return l.size(); }
|
||||
bool empty() const { return l.empty(); }
|
||||
|
||||
iterator begin() { return l.begin(); }
|
||||
const_iterator begin() const { return l.begin(); }
|
||||
|
||||
iterator end() { return l.end(); }
|
||||
const_iterator end() const { return l.end(); }
|
||||
|
||||
void
|
||||
push_back(const Argument &arg)
|
||||
{
|
||||
if (arg)
|
||||
l.push_back(arg);
|
||||
}
|
||||
|
||||
void
|
||||
push_front(const Argument &arg)
|
||||
{
|
||||
if (arg)
|
||||
l.push_front(arg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
push_back(const T &arg)
|
||||
{
|
||||
if (Traits<T>::enabled)
|
||||
l.push_back(arg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
push_front(const T &arg)
|
||||
{
|
||||
if (Traits<T>::enabled)
|
||||
l.push_front(arg);
|
||||
}
|
||||
|
||||
Argument& front() { return l.front(); }
|
||||
const Argument& front() const { return l.front(); }
|
||||
Argument& back() { return l.back(); }
|
||||
const Argument& back() const { return l.back(); }
|
||||
|
||||
void erase(iterator position) { return l.erase(position); }
|
||||
void erase(iterator first, iterator last) { return l.erase(first, last); }
|
||||
void clear() { return l.clear(); }
|
||||
void pop_front() { return l.pop_front(); }
|
||||
void pop_back() { return l.pop_back(); }
|
||||
void reverse() { l.reverse(); }
|
||||
|
||||
/*
|
||||
* Functions specific to variable arguments
|
||||
*/
|
||||
void
|
||||
add_args(RECV &recv) const
|
||||
{
|
||||
const_iterator i = l.begin();
|
||||
const_iterator end = l.end();
|
||||
while (i != end) {
|
||||
i->add_arg(recv);
|
||||
++i;
|
||||
}
|
||||
|
||||
recv.end_args();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace VarArgs
|
||||
|
||||
#endif /* __BASE_VARARGS_HH__ */
|
||||
46
simulators/gem5/src/base/vnc/SConscript
Normal file
46
simulators/gem5/src/base/vnc/SConscript
Normal file
@ -0,0 +1,46 @@
|
||||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2010 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Authors: William Wang
|
||||
|
||||
Import('*')
|
||||
|
||||
Source('convert.cc')
|
||||
|
||||
SimObject('VncServer.py')
|
||||
Source('vncserver.cc')
|
||||
DebugFlag('VNC')
|
||||
46
simulators/gem5/src/base/vnc/VncServer.py
Normal file
46
simulators/gem5/src/base/vnc/VncServer.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright (c) 2010 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Authors: William Wang
|
||||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.params import *
|
||||
from m5.proxy import *
|
||||
|
||||
class VncServer(SimObject):
|
||||
type = 'VncServer'
|
||||
port = Param.TcpPort(5900, "listen port")
|
||||
number = Param.Int(0, "vnc client number")
|
||||
frame_capture = Param.Bool(False, "capture changed frames to files")
|
||||
156
simulators/gem5/src/base/vnc/convert.cc
Normal file
156
simulators/gem5/src/base/vnc/convert.cc
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2011 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Ali Saidi
|
||||
* William Wang
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "base/vnc/convert.hh"
|
||||
#include "base/misc.hh"
|
||||
|
||||
/** @file
|
||||
* This file provides conversion functions for a variety of video modes
|
||||
*/
|
||||
|
||||
VideoConvert::VideoConvert(Mode input_mode, Mode output_mode, int _width,
|
||||
int _height)
|
||||
: inputMode(input_mode), outputMode(output_mode), width(_width),
|
||||
height(_height)
|
||||
{
|
||||
if (inputMode != bgr565 && inputMode != rgb565 && inputMode != bgr8888)
|
||||
fatal("Only support converting from bgr565, rdb565, and bgr8888\n");
|
||||
|
||||
if (outputMode != rgb8888)
|
||||
fatal("Only support converting to rgb8888\n");
|
||||
|
||||
assert(0 < height && height < 4000);
|
||||
assert(0 < width && width < 4000);
|
||||
}
|
||||
|
||||
VideoConvert::~VideoConvert()
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
VideoConvert::convert(const uint8_t *fb) const
|
||||
{
|
||||
switch (inputMode) {
|
||||
case bgr565:
|
||||
return m565rgb8888(fb, true);
|
||||
case rgb565:
|
||||
return m565rgb8888(fb, false);
|
||||
case bgr8888:
|
||||
return bgr8888rgb8888(fb);
|
||||
default:
|
||||
panic("Unimplemented Mode\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
VideoConvert::m565rgb8888(const uint8_t *fb, bool bgr) const
|
||||
{
|
||||
uint8_t *out = new uint8_t[area() * sizeof(uint32_t)];
|
||||
uint32_t *out32 = (uint32_t*)out;
|
||||
|
||||
uint16_t *in16 = (uint16_t*)fb;
|
||||
|
||||
for (int x = 0; x < area(); x++) {
|
||||
Bgr565 inpx;
|
||||
Rgb8888 outpx = 0;
|
||||
|
||||
inpx = in16[x];
|
||||
|
||||
if (bgr) {
|
||||
outpx.red = inpx.blue << 3;
|
||||
outpx.green = inpx.green << 2;
|
||||
outpx.blue = inpx.red << 3;
|
||||
} else {
|
||||
outpx.blue = inpx.blue << 3;
|
||||
outpx.green = inpx.green << 2;
|
||||
outpx.red = inpx.red << 3;
|
||||
}
|
||||
|
||||
out32[x] = outpx;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
uint8_t*
|
||||
VideoConvert::bgr8888rgb8888(const uint8_t *fb) const
|
||||
{
|
||||
uint8_t *out = new uint8_t[area() * sizeof(uint32_t)];
|
||||
uint32_t *out32 = (uint32_t*)out;
|
||||
|
||||
uint32_t *in32 = (uint32_t*)fb;
|
||||
|
||||
for (int x = 0; x < area(); x++) {
|
||||
Rgb8888 outpx = 0;
|
||||
Bgr8888 inpx;
|
||||
|
||||
|
||||
inpx = in32[x];
|
||||
|
||||
outpx.red = inpx.blue;
|
||||
outpx.green = inpx.green;
|
||||
outpx.blue = inpx.red;
|
||||
|
||||
out32[x] = outpx;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
/*
|
||||
uint64_t
|
||||
VideoConvert::getHash(const uint8_t *fb) const
|
||||
{
|
||||
const uint8_t *fb_e = fb + area();
|
||||
|
||||
uint64_t hash = 1;
|
||||
while (fb < fb_e - 8) {
|
||||
hash += *((const uint64_t*)fb);
|
||||
fb += 8;
|
||||
}
|
||||
|
||||
while (fb < fb_e) {
|
||||
hash += *(fb++);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user