Delete unused files from src/base directory.
This commit is contained in:
parent
c69d48f007
commit
2f4c71968a
15 changed files with 0 additions and 2460 deletions
|
@ -38,14 +38,11 @@ Source('bigint.cc')
|
||||||
Source('callback.cc')
|
Source('callback.cc')
|
||||||
Source('circlebuf.cc')
|
Source('circlebuf.cc')
|
||||||
Source('cprintf.cc')
|
Source('cprintf.cc')
|
||||||
Source('crc.cc')
|
|
||||||
Source('debug.cc')
|
Source('debug.cc')
|
||||||
Source('fast_alloc.cc')
|
Source('fast_alloc.cc')
|
||||||
if env['USE_FENV']:
|
if env['USE_FENV']:
|
||||||
Source('fenv.c')
|
Source('fenv.c')
|
||||||
Source('fifo_buffer.cc')
|
|
||||||
Source('hostinfo.cc')
|
Source('hostinfo.cc')
|
||||||
Source('hybrid_pred.cc')
|
|
||||||
Source('inet.cc')
|
Source('inet.cc')
|
||||||
Source('inifile.cc')
|
Source('inifile.cc')
|
||||||
Source('intmath.cc')
|
Source('intmath.cc')
|
||||||
|
@ -58,7 +55,6 @@ Source('random_mt.cc')
|
||||||
Source('range.cc')
|
Source('range.cc')
|
||||||
if env['TARGET_ISA'] != 'no':
|
if env['TARGET_ISA'] != 'no':
|
||||||
Source('remote_gdb.cc')
|
Source('remote_gdb.cc')
|
||||||
Source('sat_counter.cc')
|
|
||||||
Source('socket.cc')
|
Source('socket.cc')
|
||||||
Source('statistics.cc')
|
Source('statistics.cc')
|
||||||
Source('str.cc')
|
Source('str.cc')
|
||||||
|
@ -66,8 +62,6 @@ Source('time.cc')
|
||||||
Source('trace.cc')
|
Source('trace.cc')
|
||||||
Source('userinfo.cc')
|
Source('userinfo.cc')
|
||||||
|
|
||||||
Source('compression/lzss_compression.cc')
|
|
||||||
|
|
||||||
Source('loader/aout_object.cc')
|
Source('loader/aout_object.cc')
|
||||||
Source('loader/ecoff_object.cc')
|
Source('loader/ecoff_object.cc')
|
||||||
Source('loader/elf_object.cc')
|
Source('loader/elf_object.cc')
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
* 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: Erik Hallnor
|
|
||||||
* Nathan Binkert
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __BASE_COMPRESSION_BASE_HH__
|
|
||||||
#define __BASE_COMPRESSION_BASE_HH__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* This file defines a base (abstract virtual) compression algorithm object.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "base/types.hh"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract virtual compression algorithm object.
|
|
||||||
*/
|
|
||||||
class CompressionAlgorithm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~CompressionAlgorithm() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uncompress the data, causes a fatal since no data should be compressed.
|
|
||||||
* @param dest The output buffer.
|
|
||||||
* @param src The compressed data.
|
|
||||||
* @param size The number of bytes in src.
|
|
||||||
*
|
|
||||||
* @retval The size of the uncompressed data.
|
|
||||||
*/
|
|
||||||
virtual int uncompress(uint8_t * dest, uint8_t *src, int size) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compress the data, just returns the source data.
|
|
||||||
* @param dest The output buffer.
|
|
||||||
* @param src The data to be compressed.
|
|
||||||
* @param size The number of bytes in src.
|
|
||||||
*
|
|
||||||
* @retval The size of the compressed data.
|
|
||||||
*/
|
|
||||||
virtual int compress(uint8_t *dest, uint8_t *src, int size) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //__BASE_COMPRESSION_BASE_HH__
|
|
|
@ -1,173 +0,0 @@
|
||||||
/*
|
|
||||||
* 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: Erik Hallnor
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* LZSSCompression definitions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include "base/compression/lzss_compression.hh"
|
|
||||||
|
|
||||||
#include "base/misc.hh" //for fatal
|
|
||||||
|
|
||||||
void
|
|
||||||
LZSSCompression::findSubString(uint8_t *src, int back, int size, uint16_t &L,
|
|
||||||
uint16_t &P)
|
|
||||||
{
|
|
||||||
int front = 0;
|
|
||||||
int max_length = size - back;
|
|
||||||
L = 0;
|
|
||||||
P = back - 1;
|
|
||||||
while (front < back) {
|
|
||||||
while (src[front] != src[back] && front < back) ++front;
|
|
||||||
if (front >= back) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int i = 1;
|
|
||||||
while (src[front+i] == src[back+i] && i < max_length) ++i;
|
|
||||||
if (i >= L) {
|
|
||||||
L = i;
|
|
||||||
P = front;
|
|
||||||
}
|
|
||||||
if (src[front+i] != src[back+i-1]) {
|
|
||||||
// can't find a longer substring until past this point.
|
|
||||||
front += i;
|
|
||||||
} else {
|
|
||||||
++front;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
LZSSCompression::emitByte(uint8_t *dest, uint8_t byte)
|
|
||||||
{
|
|
||||||
if ((byte >> 5 & 0x7) == 0 || (byte >> 5 & 0x7) == 7) {
|
|
||||||
// If the top 3 bits are the same, emit 00<6bits>
|
|
||||||
dest[0] = byte & 0x3f;
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
// emit 01XXXXXX <8 bits>
|
|
||||||
dest[0] = 0x40;
|
|
||||||
dest[1] = byte;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LZSSCompression::emitString(uint8_t *dest, uint16_t P, uint16_t L)
|
|
||||||
{
|
|
||||||
// Emit 1<7P> <5P><3L> <8L>
|
|
||||||
dest[0] = 1<<7 | (P >> 5 & 0x7f);
|
|
||||||
dest[1] = ((P & 0x1f) << 3) | (L>>8 & 0x3);
|
|
||||||
dest[2] = L & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
LZSSCompression::compress(uint8_t *dest, uint8_t *src, int size)
|
|
||||||
{
|
|
||||||
if (size > 4096) {
|
|
||||||
fatal("Compression can only handle block sizes of 4096 bytes or less");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode the first byte.
|
|
||||||
int dest_index = emitByte(dest, src[0]);
|
|
||||||
int i = 1;
|
|
||||||
// A 11 bit field
|
|
||||||
uint16_t L;
|
|
||||||
// A 12 bit field
|
|
||||||
uint16_t P = 0;
|
|
||||||
|
|
||||||
while (i < size && dest_index < size) {
|
|
||||||
L = 0;
|
|
||||||
|
|
||||||
if (dest_index+3 >= size) {
|
|
||||||
dest_index = size;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == size - 1) {
|
|
||||||
// Output the character
|
|
||||||
dest_index += emitByte(&dest[dest_index], src[i]);
|
|
||||||
++i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
findSubString(src, i, size, L, P);
|
|
||||||
if (L > 1) {
|
|
||||||
// Output the string reference
|
|
||||||
emitString(&dest[dest_index], P, L);
|
|
||||||
dest_index += 3;
|
|
||||||
i = i+L;
|
|
||||||
} else {
|
|
||||||
// Output the character
|
|
||||||
dest_index += emitByte(&dest[dest_index], src[i]);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest_index >= size) {
|
|
||||||
// Have expansion instead of compression, just copy.
|
|
||||||
std::memcpy(dest,src,size);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
return dest_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
LZSSCompression::uncompress(uint8_t *dest, uint8_t *src, int size)
|
|
||||||
{
|
|
||||||
int index = 0;
|
|
||||||
int i = 0;
|
|
||||||
while (i < size) {
|
|
||||||
if (src[i] & 1<<7 ) {
|
|
||||||
// We have a string
|
|
||||||
// Extract P
|
|
||||||
int start = (src[i] & 0x3f)<<5 | ((src[i+1] >> 3) & 0x1f);
|
|
||||||
// Extract L
|
|
||||||
int len = (src[i+1] & 0x07)<<8 | src[i+2];
|
|
||||||
i += 3;
|
|
||||||
for (int j = start; j < start+len; ++j) {
|
|
||||||
dest[index++] = dest[j];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// We have a character
|
|
||||||
if (src[i] & 1<<6) {
|
|
||||||
// Value is in the next byte
|
|
||||||
dest[index++] = src[i+1];
|
|
||||||
i += 2;
|
|
||||||
} else {
|
|
||||||
// just extend the lower 6 bits
|
|
||||||
dest[index++] = (src[i] & 0x3f) | ((src[i] & 1<<5) ? 0xC0 : 0);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
* 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: Erik Hallnor
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LZSS_COMPRESSION_HH__
|
|
||||||
#define __LZSS_COMPRESSION_HH__
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* LZSSCompression declarations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "base/compression/base.hh"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple LZSS compression scheme.
|
|
||||||
*/
|
|
||||||
class LZSSCompression : public CompressionAlgorithm
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Finds the longest substring for the given offset.
|
|
||||||
* @param src The source block that we search for substrings.
|
|
||||||
* @param back The larger offset.
|
|
||||||
* @param size The size of the source block.
|
|
||||||
* @param L The length of the largest substring.
|
|
||||||
* @param P The starting offset of the largest substring.
|
|
||||||
*/
|
|
||||||
void findSubString(uint8_t *src, int back, int size, uint16_t &L,
|
|
||||||
uint16_t &P);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emit an encoded byte to the compressed data array. If the 2 high
|
|
||||||
* order bits can be signed extended, use 1 byte encoding, if not use 2
|
|
||||||
* bytes.
|
|
||||||
* @param dest The compressed data.
|
|
||||||
* @param byte The byte to emit.
|
|
||||||
* @return The number of bytes used to encode.
|
|
||||||
*/
|
|
||||||
int emitByte(uint8_t *dest, uint8_t byte);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emit a string reference to the compressed data array. A string reference
|
|
||||||
* always uses 3 bytes. 1 flag bit, 12 bits for the starting position, and
|
|
||||||
* 11 bits for the length of the string. This allows compression of 4096
|
|
||||||
* byte blocks with string lengths of up to 2048 bytes.
|
|
||||||
* @param dest The compressed data.
|
|
||||||
* @param P The starting position in the uncompressed data.
|
|
||||||
* @param L The length in bytes of the string.
|
|
||||||
*/
|
|
||||||
void emitString(uint8_t *dest, uint16_t P, uint16_t L);
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Compresses the source block and stores it in the destination block. If
|
|
||||||
* the compressed block grows to larger than the source block, it aborts
|
|
||||||
* and just performs a copy.
|
|
||||||
* @param dest The destination block.
|
|
||||||
* @param src The block to be compressed.
|
|
||||||
* @param size The size of the source block.
|
|
||||||
* @return The size of the compressed block.
|
|
||||||
*
|
|
||||||
* @pre Destination has enough storage to hold the compressed block.
|
|
||||||
*/
|
|
||||||
int compress(uint8_t *dest, uint8_t *src, int size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unompresses the source block and stores it in the destination block.
|
|
||||||
* @param dest The destination block.
|
|
||||||
* @param src The block to be uncompressed.
|
|
||||||
* @param size The size of the source block.
|
|
||||||
* @return The size of the uncompressed block.
|
|
||||||
*
|
|
||||||
* @pre Destination has enough storage to hold the uncompressed block.
|
|
||||||
*/
|
|
||||||
int uncompress(uint8_t *dest, uint8_t *src, int size);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //__LZSS_COMPRESSION_HH__
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* 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: Erik Hallnor
|
|
||||||
* Nathan Binkert
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __BASE_COMPRESSION_NULL_COMPRESSION_HH__
|
|
||||||
#define __BASE_COMPRESSION_NULL_COMPRESSION_HH__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* This file defines a doNothing compression algorithm.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "base/misc.hh" // for fatal()
|
|
||||||
#include "base/compression/base.hh"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A dummy compression class to use when no data compression is desired.
|
|
||||||
*/
|
|
||||||
class NullCompression : public CompressionAlgorithm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int uncompress(uint8_t * dest, uint8_t *src, int size)
|
|
||||||
{
|
|
||||||
fatal("Can't uncompress data");
|
|
||||||
M5_DUMMY_RETURN
|
|
||||||
}
|
|
||||||
|
|
||||||
int compress(uint8_t *dest, uint8_t *src, int size)
|
|
||||||
{
|
|
||||||
fatal("Can't compress data");
|
|
||||||
M5_DUMMY_RETURN
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //__BASE_COMPRESSION_NULL_COMPRESSION_HH__
|
|
105
src/base/crc.cc
105
src/base/crc.cc
|
@ -1,105 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1988, 1992, 1993
|
|
||||||
* The Regents of the University of California. 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 the University of
|
|
||||||
* California, Berkeley and its contributors.
|
|
||||||
* 4. Neither the name of the University 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 REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "base/crc.hh"
|
|
||||||
#include "base/types.hh"
|
|
||||||
|
|
||||||
#define ETHER_CRC_POLY_LE 0xedb88320
|
|
||||||
#define ETHER_CRC_POLY_BE 0x04c11db6
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* This is for reference. We have a table-driven version
|
|
||||||
* of the little-endian crc32 generator, which is faster
|
|
||||||
* than the double-loop.
|
|
||||||
*/
|
|
||||||
uint32_t
|
|
||||||
crc32le(const uint8_t *buf, size_t len)
|
|
||||||
{
|
|
||||||
uint32_t crc = 0xffffffffU; /* initial value */
|
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
uint32_t c = buf[i];
|
|
||||||
for (size_t j = 0; j < 8; j++) {
|
|
||||||
uint32_t carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
|
|
||||||
crc >>= 1;
|
|
||||||
c >>= 1;
|
|
||||||
if (carry)
|
|
||||||
crc = (crc ^ ETHER_CRC_POLY_LE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
uint32_t
|
|
||||||
crc32le(const uint8_t *buf, size_t len)
|
|
||||||
{
|
|
||||||
static const uint32_t crctab[] = {
|
|
||||||
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
|
||||||
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
|
||||||
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
|
||||||
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
|
|
||||||
};
|
|
||||||
uint32_t crc = 0xffffffffU; /* initial value */
|
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
crc ^= buf[i];
|
|
||||||
crc = (crc >> 4) ^ crctab[crc & 0xf];
|
|
||||||
crc = (crc >> 4) ^ crctab[crc & 0xf];
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
crc32be(const uint8_t *buf, size_t len)
|
|
||||||
{
|
|
||||||
uint32_t crc = 0xffffffffU; /* initial value */
|
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
uint32_t c = buf[i];
|
|
||||||
for (size_t j = 0; j < 8; j++) {
|
|
||||||
uint32_t carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
|
|
||||||
crc <<= 1;
|
|
||||||
c >>= 1;
|
|
||||||
if (carry)
|
|
||||||
crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (crc);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* 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_CRC_HH__
|
|
||||||
#define __BASE_CRC_HH__
|
|
||||||
|
|
||||||
#include "base/types.hh"
|
|
||||||
|
|
||||||
uint32_t crc32be(const uint8_t *buf, size_t len);
|
|
||||||
uint32_t crc32le(const uint8_t *buf, size_t len);
|
|
||||||
|
|
||||||
#endif // __BASE_CRC_HH__
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* Nathan Binkert
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "base/fifo_buffer.hh"
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void
|
|
||||||
FifoBuffer<T>::dump()
|
|
||||||
{
|
|
||||||
if (buffer->count() > 0)
|
|
||||||
for (iterator i=buffer->tail(); i.notnull(); i=i.prev())
|
|
||||||
i->dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* Nathan Binkert
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FIFO_BUFFER_HH__
|
|
||||||
#define __FIFO_BUFFER_HH__
|
|
||||||
|
|
||||||
#include "base/res_list.hh"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// The FifoBuffer requires only that the objects to be used have a default
|
|
||||||
// constructor and a dump() method
|
|
||||||
//
|
|
||||||
template<class T>
|
|
||||||
class FifoBuffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename res_list<T>::iterator iterator;
|
|
||||||
|
|
||||||
private:
|
|
||||||
res_list<T> *buffer;
|
|
||||||
|
|
||||||
unsigned size;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FifoBuffer(unsigned sz)
|
|
||||||
{
|
|
||||||
buffer = new res_list<T>(sz, true, 0);
|
|
||||||
size = sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(T &item)
|
|
||||||
{
|
|
||||||
assert(buffer->num_free() > 0);
|
|
||||||
buffer->add_head(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator head() { return buffer->head(); }
|
|
||||||
iterator tail() { return buffer->tail(); }
|
|
||||||
|
|
||||||
unsigned count() {return buffer->count();}
|
|
||||||
unsigned free_slots() {return buffer->num_free();}
|
|
||||||
|
|
||||||
T *peek() { return (count() > 0) ? tail().data_ptr() : 0; }
|
|
||||||
|
|
||||||
T remove()
|
|
||||||
{
|
|
||||||
assert(buffer->count() > 0);
|
|
||||||
T rval = *buffer->tail();
|
|
||||||
buffer->remove_tail();
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump();
|
|
||||||
|
|
||||||
~FifoBuffer() { delete buffer; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,276 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* Lisa Hsu
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "base/hybrid_pred.hh"
|
|
||||||
#include "base/statistics.hh"
|
|
||||||
#include "sim/stats.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
HybridPredictor::HybridPredictor(const char *_p_name, const char *_z_name,
|
|
||||||
const char *_o_name,
|
|
||||||
unsigned _index_bits, unsigned _counter_bits,
|
|
||||||
unsigned _zero_change, unsigned _one_change,
|
|
||||||
unsigned _thresh,
|
|
||||||
unsigned _global_bits,
|
|
||||||
unsigned _global_thresh,
|
|
||||||
bool _reg_individual_stats)
|
|
||||||
{
|
|
||||||
stringstream local_name, global_name;
|
|
||||||
|
|
||||||
pred_name = _p_name;
|
|
||||||
one_name = _o_name;
|
|
||||||
zero_name = _z_name;
|
|
||||||
reg_individual_stats = _reg_individual_stats;
|
|
||||||
|
|
||||||
local_name << pred_name.c_str() << ":L";
|
|
||||||
local = new SaturatingCounterPred(local_name.str(), zero_name, one_name,
|
|
||||||
_index_bits, _counter_bits,
|
|
||||||
_zero_change, _one_change, _thresh);
|
|
||||||
|
|
||||||
global_name << pred_name.c_str() << ":G";
|
|
||||||
global = new SaturatingCounterPred(global_name.str(), zero_name, one_name,
|
|
||||||
0, _global_bits, 1, 1, _global_thresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HybridPredictor::regStats()
|
|
||||||
{
|
|
||||||
using namespace Stats;
|
|
||||||
|
|
||||||
string p_name;
|
|
||||||
stringstream description;
|
|
||||||
|
|
||||||
if (reg_individual_stats)
|
|
||||||
p_name = pred_name + ":A";
|
|
||||||
else
|
|
||||||
p_name = pred_name;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Number of predictions
|
|
||||||
//
|
|
||||||
stringstream num_zero_preds;
|
|
||||||
num_zero_preds << p_name << ":" << zero_name << ":preds";
|
|
||||||
description << "number of predictions of " << zero_name;
|
|
||||||
pred_zero
|
|
||||||
.name(num_zero_preds.str())
|
|
||||||
.desc(description.str());
|
|
||||||
description.str("");
|
|
||||||
|
|
||||||
stringstream num_one_preds;
|
|
||||||
num_one_preds << p_name << ":" << one_name << ":preds";
|
|
||||||
description << "number of predictions of " << one_name;
|
|
||||||
pred_one
|
|
||||||
.name(num_one_preds.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Count the number of correct predictions
|
|
||||||
//
|
|
||||||
stringstream num_zero_correct;
|
|
||||||
num_zero_correct << p_name << ":" << zero_name << ":corr_preds";
|
|
||||||
description << "number of correct " << zero_name << " preds" ;
|
|
||||||
correct_pred_zero
|
|
||||||
.name(num_zero_correct.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
|
|
||||||
stringstream num_one_correct;
|
|
||||||
num_one_correct << p_name << ":" << one_name << ":corr_preds";
|
|
||||||
description << "number of correct " << one_name << " preds" ;
|
|
||||||
correct_pred_one
|
|
||||||
.name(num_one_correct.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Number of predictor updates
|
|
||||||
//
|
|
||||||
stringstream num_zero_updates;
|
|
||||||
num_zero_updates << p_name << ":" << zero_name << ":updates" ;
|
|
||||||
description << "number of actual " << zero_name << "s" ;
|
|
||||||
record_zero
|
|
||||||
.name(num_zero_updates.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
|
|
||||||
stringstream num_one_updates;
|
|
||||||
num_one_updates << p_name << ":" << one_name << ":updates" ;
|
|
||||||
description << "number of actual " << one_name << "s" ;
|
|
||||||
record_one
|
|
||||||
.name(num_one_updates.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Local & Global predictor stats
|
|
||||||
//
|
|
||||||
if (reg_individual_stats) {
|
|
||||||
local->regStats();
|
|
||||||
global->regStats();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HybridPredictor::regFormulas()
|
|
||||||
{
|
|
||||||
using namespace Stats;
|
|
||||||
|
|
||||||
string p_name;
|
|
||||||
stringstream description;
|
|
||||||
stringstream name;
|
|
||||||
|
|
||||||
if (reg_individual_stats)
|
|
||||||
p_name = pred_name + ":A";
|
|
||||||
else
|
|
||||||
p_name = pred_name;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Number of predictions
|
|
||||||
//
|
|
||||||
name << p_name << ":predictions" ;
|
|
||||||
total_preds
|
|
||||||
.name(name.str())
|
|
||||||
.desc("total number of predictions made")
|
|
||||||
;
|
|
||||||
total_preds = pred_one + pred_zero;
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fraction of all predictions that are one or zero
|
|
||||||
//
|
|
||||||
name << p_name << ":" << zero_name << ":pred_frac";
|
|
||||||
description << "fraction of all preds that were " << zero_name ;
|
|
||||||
frac_preds_zero
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
frac_preds_zero = 100 * record_zero / total_preds;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << p_name << ":" << one_name << ":pred_frac";
|
|
||||||
description << "fraction of all preds that were " << one_name ;
|
|
||||||
frac_preds_one
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
frac_preds_one = 100 * record_one / total_preds;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Count the number of correct predictions
|
|
||||||
//
|
|
||||||
name << p_name << ":correct_preds" ;
|
|
||||||
total_correct
|
|
||||||
.name(name.str())
|
|
||||||
.desc("total number of correct predictions made")
|
|
||||||
;
|
|
||||||
total_correct = correct_pred_one + correct_pred_zero;
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prediction accuracy rates
|
|
||||||
//
|
|
||||||
name << p_name << ":pred_rate";
|
|
||||||
total_accuracy
|
|
||||||
.name(name.str())
|
|
||||||
.desc("fraction of all preds that were correct")
|
|
||||||
;
|
|
||||||
total_accuracy = 100 * total_correct / total_preds;
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << p_name << ":" << zero_name << ":pred_rate" ;
|
|
||||||
description << "fraction of "<< zero_name <<" preds that were correct";
|
|
||||||
zero_accuracy
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
zero_accuracy = 100 * correct_pred_zero / pred_zero;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << p_name << ":" << one_name << ":pred_rate" ;
|
|
||||||
description << "fraction of "<< one_name <<" preds that were correct";
|
|
||||||
one_accuracy
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
one_accuracy = 100 * correct_pred_one / pred_one;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Coverage
|
|
||||||
//
|
|
||||||
name << p_name << ":" << zero_name << ":coverage";
|
|
||||||
description << "fraction of " << zero_name
|
|
||||||
<< "s that were predicted correctly";
|
|
||||||
zero_coverage
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
zero_coverage = 100 * correct_pred_zero / record_zero;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << p_name << ":" << one_name << ":coverage";
|
|
||||||
description << "fraction of " << one_name
|
|
||||||
<< "s that were predicted correctly";
|
|
||||||
one_coverage
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
one_coverage = 100 * correct_pred_one / record_one;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Local & Global predictor stats
|
|
||||||
//
|
|
||||||
if (reg_individual_stats) {
|
|
||||||
local->regFormulas();
|
|
||||||
global->regFormulas();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,204 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 Raasch
|
|
||||||
* Steve Reinhardt
|
|
||||||
*/
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// This predictor takes the AND of a "local" and a "global" predictor
|
|
||||||
// in order to determine its prediction.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __HYBRID_PRED_HH__
|
|
||||||
#define __HYBRID_PRED_HH__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "base/sat_counter.hh"
|
|
||||||
#include "base/statistics.hh"
|
|
||||||
|
|
||||||
class HybridPredictor : public GenericPredictor
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string pred_name;
|
|
||||||
std::string one_name;
|
|
||||||
std::string zero_name;
|
|
||||||
bool reg_individual_stats;
|
|
||||||
|
|
||||||
SaturatingCounterPred *local;
|
|
||||||
SaturatingCounterPred *global;
|
|
||||||
|
|
||||||
unsigned long max_index;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Stats
|
|
||||||
//
|
|
||||||
Stats::Scalar pred_one; //num_one_preds
|
|
||||||
Stats::Scalar pred_zero; //num_zero_preds
|
|
||||||
Stats::Scalar correct_pred_one; //num_one_correct
|
|
||||||
Stats::Scalar correct_pred_zero; //num_zero_correct
|
|
||||||
Stats::Scalar record_one; //num_one_updates
|
|
||||||
Stats::Scalar record_zero; //num_zero_updates
|
|
||||||
|
|
||||||
Stats::Formula total_preds;
|
|
||||||
Stats::Formula frac_preds_zero;
|
|
||||||
Stats::Formula frac_preds_one;
|
|
||||||
Stats::Formula total_correct;
|
|
||||||
Stats::Formula total_accuracy;
|
|
||||||
Stats::Formula zero_accuracy;
|
|
||||||
Stats::Formula one_accuracy;
|
|
||||||
Stats::Formula zero_coverage;
|
|
||||||
Stats::Formula one_coverage;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HybridPredictor(const char *_p_name, const char *_z_name,
|
|
||||||
const char *_o_name,
|
|
||||||
unsigned _index_bits, unsigned _counter_bits,
|
|
||||||
unsigned _zero_change, unsigned _one_change,
|
|
||||||
unsigned _thresh,
|
|
||||||
unsigned _global_bits, unsigned _global_thresh,
|
|
||||||
bool _reg_individual_stats = false);
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
global->clear();
|
|
||||||
local->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned peek(unsigned long _index) {
|
|
||||||
unsigned l = local->peek(_index);
|
|
||||||
unsigned g = global->peek(_index);
|
|
||||||
|
|
||||||
if (l && g)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned value(unsigned long _index) {
|
|
||||||
unsigned l = local->peek(_index);
|
|
||||||
unsigned g = global->peek(_index);
|
|
||||||
|
|
||||||
l = l & 0xFFFF;
|
|
||||||
g = g & 0xFFFF;
|
|
||||||
|
|
||||||
return (l << 16) | g;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned predict(unsigned long _index) {
|
|
||||||
unsigned l = local->predict(_index);
|
|
||||||
unsigned g = global->predict(_index);
|
|
||||||
|
|
||||||
if (l && g) {
|
|
||||||
++pred_one;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
++pred_zero;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// This version need only be used if local/global statistics
|
|
||||||
// will be maintained
|
|
||||||
//
|
|
||||||
unsigned predict(unsigned long _index, unsigned &_pdata) {
|
|
||||||
unsigned l = local->predict(_index);
|
|
||||||
unsigned g = global->predict(_index);
|
|
||||||
|
|
||||||
//
|
|
||||||
// bit 0 => local predictor result
|
|
||||||
// bit 1 => global predictor result
|
|
||||||
//
|
|
||||||
_pdata = 0;
|
|
||||||
if (l)
|
|
||||||
_pdata |= 1;
|
|
||||||
if (g)
|
|
||||||
_pdata |= 2;
|
|
||||||
if (l && g) {
|
|
||||||
++pred_one;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
++pred_zero;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void record(unsigned long _index, unsigned _val, unsigned _predicted) {
|
|
||||||
|
|
||||||
if (_val) {
|
|
||||||
local->record(_index, _val, 0);
|
|
||||||
global->record(_index, _val, 0);
|
|
||||||
++record_one;
|
|
||||||
|
|
||||||
if (_val == _predicted) {
|
|
||||||
++correct_pred_one;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
local->record(_index, _val, 0);
|
|
||||||
global->record(_index, _val, 0);
|
|
||||||
++record_zero;
|
|
||||||
|
|
||||||
if (_val == _predicted)
|
|
||||||
++correct_pred_zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void record(unsigned long _index, unsigned _val, unsigned _predicted,
|
|
||||||
unsigned _pdata)
|
|
||||||
{
|
|
||||||
|
|
||||||
local->record(_index, _val, (_pdata & 1));
|
|
||||||
global->record(_index, _val, ((_pdata & 2) ? 1 : 0));
|
|
||||||
|
|
||||||
|
|
||||||
if (_val) {
|
|
||||||
++record_one;
|
|
||||||
|
|
||||||
if (_val == _predicted)
|
|
||||||
++correct_pred_one;
|
|
||||||
} else {
|
|
||||||
++record_zero;
|
|
||||||
|
|
||||||
if (_val == _predicted)
|
|
||||||
++correct_pred_zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void regStats();
|
|
||||||
void regFormulas();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _HYBRID_PRED_HH__
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 Raasch
|
|
||||||
* Nathan Binkert
|
|
||||||
*/
|
|
||||||
|
|
||||||
//
|
|
||||||
// Abstract base class for a generic predictor
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __PREDICTOR_HH__
|
|
||||||
#define __PREDICTOR_HH__
|
|
||||||
|
|
||||||
class GenericPredictor {
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void clear() = 0;
|
|
||||||
|
|
||||||
virtual unsigned predict(unsigned long _index) = 0;
|
|
||||||
virtual unsigned predict(unsigned long _index, unsigned &pdata) = 0;
|
|
||||||
|
|
||||||
virtual unsigned peek(unsigned long _index) = 0;
|
|
||||||
|
|
||||||
virtual void record(unsigned long _index, unsigned _actual_value,
|
|
||||||
unsigned _pred_value) = 0;
|
|
||||||
virtual void record(unsigned long _index, unsigned _actual_value,
|
|
||||||
unsigned _pred_value, unsigned _pdata) = 0;
|
|
||||||
|
|
||||||
virtual unsigned value(unsigned long _index) = 0;
|
|
||||||
|
|
||||||
virtual void regStats() = 0;
|
|
||||||
virtual void regFormulas() = 0;
|
|
||||||
|
|
||||||
virtual ~GenericPredictor() {};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __PREDICTOR_HH__
|
|
|
@ -1,759 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 Raasch
|
|
||||||
* Nathan Binkert
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __RES_LIST_HH__
|
|
||||||
#define __RES_LIST_HH__
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "base/cprintf.hh"
|
|
||||||
|
|
||||||
#define DEBUG_REMOVE 0
|
|
||||||
|
|
||||||
#define DEBUG_MEMORY 0
|
|
||||||
//#define DEBUG_MEMORY DEBUG
|
|
||||||
|
|
||||||
class res_list_base
|
|
||||||
{
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
protected:
|
|
||||||
static long long allocated_elements;
|
|
||||||
static long long allocated_lists;
|
|
||||||
|
|
||||||
public:
|
|
||||||
long long get_elements(void) {
|
|
||||||
return allocated_elements;
|
|
||||||
}
|
|
||||||
long long get_lists(void) {
|
|
||||||
return allocated_lists;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
extern void what_the(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
class res_list : public res_list_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class iterator;
|
|
||||||
|
|
||||||
class res_element
|
|
||||||
{
|
|
||||||
res_element *next;
|
|
||||||
res_element *prev;
|
|
||||||
T *data;
|
|
||||||
bool allocate_data;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// always adds to the END of the list
|
|
||||||
res_element(res_element *_prev, bool allocate);
|
|
||||||
~res_element();
|
|
||||||
void dump(void);
|
|
||||||
|
|
||||||
friend class res_list<T>;
|
|
||||||
friend class res_list<T>::iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
res_element *p;
|
|
||||||
|
|
||||||
friend class res_list<T>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
iterator(res_element *q) : p(q) {}
|
|
||||||
iterator(void) { p=0; };
|
|
||||||
|
|
||||||
void dump(void);
|
|
||||||
T* data_ptr(void);
|
|
||||||
res_element *res_el_ptr(void) { return p;}
|
|
||||||
void point_to(T &d) { p->data = &d; }
|
|
||||||
|
|
||||||
iterator next(void) { return iterator(p->next); }
|
|
||||||
iterator prev(void) { return iterator(p->prev); }
|
|
||||||
bool operator== (iterator x) { return (x.p == this->p); }
|
|
||||||
bool operator != (iterator x) { return (x.p != this->p); }
|
|
||||||
T &operator * (void) { return *(p->data); }
|
|
||||||
T* operator -> (void) { return p->data; }
|
|
||||||
bool isnull(void) { return (p==0); }
|
|
||||||
bool notnull(void) { return (p!=0); }
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
iterator unused_elements;
|
|
||||||
iterator head_ptr;
|
|
||||||
iterator tail_ptr;
|
|
||||||
|
|
||||||
unsigned base_elements;
|
|
||||||
unsigned extra_elements;
|
|
||||||
unsigned active_elements;
|
|
||||||
bool allocate_storage;
|
|
||||||
unsigned build_size;
|
|
||||||
|
|
||||||
int remove_count;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate new elements, and assign them to the unused_elements
|
|
||||||
// list.
|
|
||||||
//
|
|
||||||
unsigned allocate_elements(unsigned num, bool allocate_storage);
|
|
||||||
|
|
||||||
public:
|
|
||||||
//
|
|
||||||
// List Constructor
|
|
||||||
//
|
|
||||||
res_list(unsigned size, bool alloc_storage = false,
|
|
||||||
unsigned build_sz = 5);
|
|
||||||
|
|
||||||
//
|
|
||||||
// List Destructor
|
|
||||||
//
|
|
||||||
~res_list();
|
|
||||||
|
|
||||||
iterator head(void) {return head_ptr;};
|
|
||||||
iterator tail(void) {return tail_ptr;};
|
|
||||||
|
|
||||||
unsigned num_free(void) { return size() - count(); }
|
|
||||||
unsigned size(void) { return base_elements + extra_elements; }
|
|
||||||
unsigned count(void) { return active_elements; }
|
|
||||||
bool empty(void) { return count() == 0; }
|
|
||||||
bool full(void);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Insert with data copy
|
|
||||||
//
|
|
||||||
iterator insert_after(iterator prev, T *d);
|
|
||||||
iterator insert_after(iterator prev, T &d);
|
|
||||||
iterator insert_before(iterator prev, T *d);
|
|
||||||
iterator insert_before(iterator prev, T &d);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Insert new list element (no data copy)
|
|
||||||
//
|
|
||||||
iterator insert_after(iterator prev);
|
|
||||||
iterator insert_before(iterator prev);
|
|
||||||
|
|
||||||
iterator add_tail(T *d) { return insert_after(tail_ptr, d); }
|
|
||||||
iterator add_tail(T &d) { return insert_after(tail_ptr, d); }
|
|
||||||
iterator add_tail(void) { return insert_after(tail_ptr); }
|
|
||||||
iterator add_head(T *d) { return insert_before(head_ptr, d); }
|
|
||||||
iterator add_head(T &d) { return insert_before(head_ptr, d); }
|
|
||||||
iterator add_head(void) { return insert_before(head_ptr); }
|
|
||||||
|
|
||||||
iterator remove(iterator q);
|
|
||||||
iterator remove_head(void) {return remove(head_ptr);}
|
|
||||||
iterator remove_tail(void) {return remove(tail_ptr);}
|
|
||||||
|
|
||||||
bool in_list(iterator j);
|
|
||||||
void free_extras(void);
|
|
||||||
void clear(void);
|
|
||||||
void dump(void);
|
|
||||||
void raw_dump(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
res_list<T>::res_element::res_element(res_element *_prev, bool allocate)
|
|
||||||
{
|
|
||||||
allocate_data = allocate;
|
|
||||||
prev = _prev;
|
|
||||||
next = 0;
|
|
||||||
|
|
||||||
if (prev)
|
|
||||||
prev->next = this;
|
|
||||||
|
|
||||||
if (allocate)
|
|
||||||
data = new T;
|
|
||||||
else
|
|
||||||
data = 0;
|
|
||||||
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
++allocated_elements;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
res_list<T>::res_element::~res_element(void)
|
|
||||||
{
|
|
||||||
if (prev)
|
|
||||||
prev->next = next;
|
|
||||||
|
|
||||||
if (next)
|
|
||||||
next->prev = prev;
|
|
||||||
|
|
||||||
if (allocate_data)
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
--allocated_elements;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void
|
|
||||||
res_list<T>::res_element::dump(void)
|
|
||||||
{
|
|
||||||
cprintf(" prev = %#x\n", prev);
|
|
||||||
cprintf(" next = %#x\n", next);
|
|
||||||
cprintf(" data = %#x\n", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void
|
|
||||||
res_list<T>::iterator::dump(void)
|
|
||||||
{
|
|
||||||
if (p && p->data)
|
|
||||||
p->data->dump();
|
|
||||||
else {
|
|
||||||
if (!p)
|
|
||||||
cprintf(" Null Pointer\n");
|
|
||||||
else
|
|
||||||
cprintf(" Null 'data' Pointer\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T *
|
|
||||||
res_list<T>::iterator::data_ptr(void)
|
|
||||||
{
|
|
||||||
if (p)
|
|
||||||
return p->data;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate new elements, and assign them to the unused_elements
|
|
||||||
// list.
|
|
||||||
//
|
|
||||||
template <class T>
|
|
||||||
inline unsigned
|
|
||||||
res_list<T>::allocate_elements(unsigned num, bool allocate_storage)
|
|
||||||
{
|
|
||||||
res_element *pnew, *plast = 0, *pfirst=0;
|
|
||||||
|
|
||||||
for (int i=0; i<num; ++i) {
|
|
||||||
pnew = new res_element(plast, allocate_storage);
|
|
||||||
if (i==0)
|
|
||||||
pfirst = pnew;
|
|
||||||
plast = pnew;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unused_elements.notnull()) {
|
|
||||||
// Add these new elements to the front of the list
|
|
||||||
plast->next = unused_elements.res_el_ptr();
|
|
||||||
unused_elements.res_el_ptr()->prev = plast;
|
|
||||||
}
|
|
||||||
|
|
||||||
unused_elements = iterator(pfirst);
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
res_list<T>::res_list(unsigned size, bool alloc_storage, unsigned build_sz)
|
|
||||||
{
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
++allocated_lists;
|
|
||||||
#endif
|
|
||||||
extra_elements = 0;
|
|
||||||
active_elements = 0;
|
|
||||||
build_size = build_sz;
|
|
||||||
allocate_storage = alloc_storage;
|
|
||||||
remove_count = 0;
|
|
||||||
|
|
||||||
// Create the new elements
|
|
||||||
base_elements = allocate_elements(size, alloc_storage);
|
|
||||||
|
|
||||||
// The list of active elements
|
|
||||||
head_ptr = iterator(0);
|
|
||||||
tail_ptr = iterator(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// List Destructor
|
|
||||||
//
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
res_list<T>::~res_list(void)
|
|
||||||
{
|
|
||||||
iterator n;
|
|
||||||
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
--allocated_lists;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put everything into the unused list
|
|
||||||
clear();
|
|
||||||
|
|
||||||
// rudely delete all the res_elements
|
|
||||||
for (iterator p = unused_elements;
|
|
||||||
p.notnull();
|
|
||||||
p = n) {
|
|
||||||
|
|
||||||
n = p.next();
|
|
||||||
|
|
||||||
// delete the res_element
|
|
||||||
// (it will take care of deleting the data)
|
|
||||||
delete p.res_el_ptr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline bool
|
|
||||||
res_list<T>::full(void)
|
|
||||||
{
|
|
||||||
if (build_size)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return unused_elements.isnull();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Insert with data copy
|
|
||||||
//
|
|
||||||
template <class T>
|
|
||||||
inline typename res_list<T>::iterator
|
|
||||||
res_list<T>::insert_after(iterator prev, T *d)
|
|
||||||
{
|
|
||||||
iterator p;
|
|
||||||
|
|
||||||
if (!allocate_storage)
|
|
||||||
this->panic("Can't copy data... not allocating storage");
|
|
||||||
|
|
||||||
p = insert_after(prev);
|
|
||||||
if (p.notnull())
|
|
||||||
*p = *d;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline typename res_list<T>::iterator
|
|
||||||
res_list<T>::insert_after(iterator prev, T &d)
|
|
||||||
{
|
|
||||||
iterator p;
|
|
||||||
|
|
||||||
p = insert_after(prev);
|
|
||||||
if (p.notnull()) {
|
|
||||||
|
|
||||||
if (allocate_storage) {
|
|
||||||
// if we allocate storage, then copy the contents of the
|
|
||||||
// specified object to our object
|
|
||||||
*p = d;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// if we don't allocate storage, then we just want to
|
|
||||||
// point to the specified object
|
|
||||||
p.point_to(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline typename res_list<T>::iterator
|
|
||||||
res_list<T>::insert_after(iterator prev)
|
|
||||||
{
|
|
||||||
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
if (active_elements > 2*base_elements) {
|
|
||||||
what_the();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If we have no unused elements, make some more
|
|
||||||
if (unused_elements.isnull()) {
|
|
||||||
|
|
||||||
if (build_size == 0) {
|
|
||||||
return 0; // No space left, and can't allocate more....
|
|
||||||
}
|
|
||||||
|
|
||||||
extra_elements += allocate_elements(build_size, allocate_storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// grab the first unused element
|
|
||||||
res_element *p = unused_elements.res_el_ptr();
|
|
||||||
|
|
||||||
unused_elements = unused_elements.next();
|
|
||||||
|
|
||||||
++active_elements;
|
|
||||||
|
|
||||||
// Insert the new element
|
|
||||||
if (head_ptr.isnull()) {
|
|
||||||
//
|
|
||||||
// Special case #1: Empty List
|
|
||||||
//
|
|
||||||
head_ptr = p;
|
|
||||||
tail_ptr = p;
|
|
||||||
p->prev = 0;
|
|
||||||
p->next = 0;
|
|
||||||
}
|
|
||||||
else if (prev.isnull()) {
|
|
||||||
//
|
|
||||||
// Special case #2: Insert at head
|
|
||||||
//
|
|
||||||
|
|
||||||
// our next ptr points to old head element
|
|
||||||
p->next = head_ptr.res_el_ptr();
|
|
||||||
|
|
||||||
// our element becomes the new head element
|
|
||||||
head_ptr = p;
|
|
||||||
|
|
||||||
// no previous element for the head
|
|
||||||
p->prev = 0;
|
|
||||||
|
|
||||||
// old head element points back to this element
|
|
||||||
p->next->prev = p;
|
|
||||||
}
|
|
||||||
else if (prev.next().isnull()) {
|
|
||||||
//
|
|
||||||
// Special case #3 Insert at tail
|
|
||||||
//
|
|
||||||
|
|
||||||
// our prev pointer points to old tail element
|
|
||||||
p->prev = tail_ptr.res_el_ptr();
|
|
||||||
|
|
||||||
// our element becomes the new tail
|
|
||||||
tail_ptr = p;
|
|
||||||
|
|
||||||
// no next element for the tail
|
|
||||||
p->next = 0;
|
|
||||||
|
|
||||||
// old tail element point to this element
|
|
||||||
p->prev->next = p;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//
|
|
||||||
// Normal insertion (after prev)
|
|
||||||
//
|
|
||||||
p->prev = prev.res_el_ptr();
|
|
||||||
p->next = prev.next().res_el_ptr();
|
|
||||||
|
|
||||||
prev.res_el_ptr()->next = p;
|
|
||||||
p->next->prev = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return iterator(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline typename res_list<T>::iterator
|
|
||||||
res_list<T>::insert_before(iterator next, T &d)
|
|
||||||
{
|
|
||||||
iterator p;
|
|
||||||
|
|
||||||
p = insert_before(next);
|
|
||||||
if (p.notnull()) {
|
|
||||||
|
|
||||||
if (allocate_storage) {
|
|
||||||
// if we allocate storage, then copy the contents of the
|
|
||||||
// specified object to our object
|
|
||||||
*p = d;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// if we don't allocate storage, then we just want to
|
|
||||||
// point to the specified object
|
|
||||||
p.point_to(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline typename res_list<T>::iterator
|
|
||||||
res_list<T>::insert_before(iterator next)
|
|
||||||
{
|
|
||||||
|
|
||||||
#if DEBUG_MEMORY
|
|
||||||
if (active_elements > 2*base_elements) {
|
|
||||||
what_the();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If we have no unused elements, make some more
|
|
||||||
if (unused_elements.isnull()) {
|
|
||||||
|
|
||||||
if (build_size == 0) {
|
|
||||||
return 0; // No space left, and can't allocate more....
|
|
||||||
}
|
|
||||||
|
|
||||||
extra_elements += allocate_elements(build_size, allocate_storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// grab the first unused element
|
|
||||||
res_element *p = unused_elements.res_el_ptr();
|
|
||||||
|
|
||||||
unused_elements = unused_elements.next();
|
|
||||||
|
|
||||||
++active_elements;
|
|
||||||
|
|
||||||
// Insert the new element
|
|
||||||
if (head_ptr.isnull()) {
|
|
||||||
//
|
|
||||||
// Special case #1: Empty List
|
|
||||||
//
|
|
||||||
head_ptr = p;
|
|
||||||
tail_ptr = p;
|
|
||||||
p->prev = 0;
|
|
||||||
p->next = 0;
|
|
||||||
}
|
|
||||||
else if (next.isnull()) {
|
|
||||||
//
|
|
||||||
// Special case #2 Insert at tail
|
|
||||||
//
|
|
||||||
|
|
||||||
// our prev pointer points to old tail element
|
|
||||||
p->prev = tail_ptr.res_el_ptr();
|
|
||||||
|
|
||||||
// our element becomes the new tail
|
|
||||||
tail_ptr = p;
|
|
||||||
|
|
||||||
// no next element for the tail
|
|
||||||
p->next = 0;
|
|
||||||
|
|
||||||
// old tail element point to this element
|
|
||||||
p->prev->next = p;
|
|
||||||
}
|
|
||||||
else if (next.prev().isnull()) {
|
|
||||||
//
|
|
||||||
// Special case #3: Insert at head
|
|
||||||
//
|
|
||||||
|
|
||||||
// our next ptr points to old head element
|
|
||||||
p->next = head_ptr.res_el_ptr();
|
|
||||||
|
|
||||||
// our element becomes the new head element
|
|
||||||
head_ptr = p;
|
|
||||||
|
|
||||||
// no previous element for the head
|
|
||||||
p->prev = 0;
|
|
||||||
|
|
||||||
// old head element points back to this element
|
|
||||||
p->next->prev = p;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//
|
|
||||||
// Normal insertion (before next)
|
|
||||||
//
|
|
||||||
p->next = next.res_el_ptr();
|
|
||||||
p->prev = next.prev().res_el_ptr();
|
|
||||||
|
|
||||||
next.res_el_ptr()->prev = p;
|
|
||||||
p->prev->next = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return iterator(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline typename res_list<T>::iterator
|
|
||||||
res_list<T>::remove(iterator q)
|
|
||||||
{
|
|
||||||
res_element *p = q.res_el_ptr();
|
|
||||||
iterator n = 0;
|
|
||||||
|
|
||||||
// Handle the special cases
|
|
||||||
if (active_elements == 1) { // This is the only element
|
|
||||||
head_ptr = 0;
|
|
||||||
tail_ptr = 0;
|
|
||||||
}
|
|
||||||
else if (q == head_ptr) { // This is the head element
|
|
||||||
head_ptr = q.next();
|
|
||||||
head_ptr.res_el_ptr()->prev = 0;
|
|
||||||
|
|
||||||
n = head_ptr;
|
|
||||||
}
|
|
||||||
else if (q == tail_ptr) { // This is the tail element
|
|
||||||
tail_ptr = q.prev();
|
|
||||||
tail_ptr.res_el_ptr()->next = 0;
|
|
||||||
}
|
|
||||||
else { // This is between two elements
|
|
||||||
p->prev->next = p->next;
|
|
||||||
p->next->prev = p->prev;
|
|
||||||
|
|
||||||
// Get the "next" element for return
|
|
||||||
n = p->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
--active_elements;
|
|
||||||
|
|
||||||
// Put this element back onto the unused list
|
|
||||||
p->next = unused_elements.res_el_ptr();
|
|
||||||
p->prev = 0;
|
|
||||||
if (p->next) { // NULL if unused list is empty
|
|
||||||
p->next->prev = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allocate_storage) {
|
|
||||||
p->data = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unused_elements = q;
|
|
||||||
|
|
||||||
// A little "garbage collection"
|
|
||||||
if (++remove_count > 10) {
|
|
||||||
// free_extras();
|
|
||||||
remove_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG_REMOVE
|
|
||||||
unsigned unused_count = 0;
|
|
||||||
for (iterator i=unused_elements;
|
|
||||||
i.notnull();
|
|
||||||
i = i.next()) {
|
|
||||||
|
|
||||||
++unused_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert((active_elements+unused_count) == (base_elements+extra_elements));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return iterator(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline bool
|
|
||||||
res_list<T>::in_list(iterator j)
|
|
||||||
{
|
|
||||||
iterator i;
|
|
||||||
|
|
||||||
for (i=head(); i.notnull(); i=i.next()) {
|
|
||||||
if (j.res_el_ptr() == i.res_el_ptr()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void
|
|
||||||
res_list<T>::free_extras(void)
|
|
||||||
{
|
|
||||||
unsigned num_unused = base_elements + extra_elements - active_elements;
|
|
||||||
unsigned to_free = extra_elements;
|
|
||||||
res_element *p;
|
|
||||||
|
|
||||||
|
|
||||||
if (extra_elements != 0) {
|
|
||||||
//
|
|
||||||
// Free min(extra_elements, # unused elements)
|
|
||||||
//
|
|
||||||
if (extra_elements > num_unused) {
|
|
||||||
to_free = num_unused;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = unused_elements.res_el_ptr();
|
|
||||||
for (int i=0; i<to_free; ++i) {
|
|
||||||
res_element *q = p->next;
|
|
||||||
|
|
||||||
delete p;
|
|
||||||
|
|
||||||
p = q;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the unused element pointer to point to the first
|
|
||||||
// element that wasn't deleted.
|
|
||||||
unused_elements = iterator(p);
|
|
||||||
|
|
||||||
// Update the number of extra elements
|
|
||||||
extra_elements -= to_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void
|
|
||||||
res_list<T>::clear(void)
|
|
||||||
{
|
|
||||||
iterator i,n;
|
|
||||||
|
|
||||||
for (i=head_ptr; i.notnull(); i=n) {
|
|
||||||
n = i.next();
|
|
||||||
remove(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_extras();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void
|
|
||||||
res_list<T>::dump(void)
|
|
||||||
{
|
|
||||||
for (iterator i=head(); !i.isnull(); i=i.next())
|
|
||||||
i->dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void
|
|
||||||
res_list<T>::raw_dump(void)
|
|
||||||
{
|
|
||||||
int j = 0;
|
|
||||||
res_element *p;
|
|
||||||
for (iterator i=head(); !i.isnull(); i=i.next()) {
|
|
||||||
cprintf("Element %d:\n", j);
|
|
||||||
|
|
||||||
if (i.notnull()) {
|
|
||||||
p = i.res_el_ptr();
|
|
||||||
cprintf(" points to res_element @ %#x\n", p);
|
|
||||||
p->dump();
|
|
||||||
cprintf(" Data Element:\n");
|
|
||||||
i->dump();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cprintf(" NULL iterator!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __RES_LIST_HH__
|
|
|
@ -1,271 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* Lisa Hsu
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "base/sat_counter.hh"
|
|
||||||
#include "base/statistics.hh"
|
|
||||||
#include "sim/stats.hh"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
|
|
||||||
SaturatingCounterPred::SaturatingCounterPred(string p_name,
|
|
||||||
string z_name,
|
|
||||||
string o_name,
|
|
||||||
unsigned _index_bits,
|
|
||||||
unsigned _counter_bits,
|
|
||||||
unsigned _zero_change,
|
|
||||||
unsigned _one_change,
|
|
||||||
unsigned _thresh,
|
|
||||||
unsigned _init_value)
|
|
||||||
{
|
|
||||||
pred_name = p_name;
|
|
||||||
zero_name = z_name;
|
|
||||||
one_name = o_name;
|
|
||||||
|
|
||||||
index_bits = _index_bits;
|
|
||||||
counter_bits = _counter_bits;
|
|
||||||
zero_change = _zero_change;
|
|
||||||
one_change = _one_change;
|
|
||||||
thresh = _thresh;
|
|
||||||
init_value = _init_value;
|
|
||||||
|
|
||||||
max_index = (1 << index_bits) - 1;
|
|
||||||
max_value = (1 << counter_bits) - 1;
|
|
||||||
|
|
||||||
table = new unsigned[max_index + 1];
|
|
||||||
|
|
||||||
// Initialize with the right parameters & clear the counter
|
|
||||||
for (unsigned long i = 0; i <= max_index; ++i)
|
|
||||||
table[i] = init_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaturatingCounterPred::regStats()
|
|
||||||
{
|
|
||||||
using namespace Stats;
|
|
||||||
stringstream name, description;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Number of predictions
|
|
||||||
//
|
|
||||||
name << pred_name << ":" << zero_name << ":preds";
|
|
||||||
description << "number of predictions of " << zero_name;
|
|
||||||
predicted_zero
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << pred_name << ":" << one_name << ":preds";
|
|
||||||
description << "number of predictions of " << one_name;
|
|
||||||
predicted_one
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Count the number of correct predictions
|
|
||||||
//
|
|
||||||
name << pred_name << ":" << zero_name << ":corr_preds";
|
|
||||||
description << "number of correct " << zero_name << " preds";
|
|
||||||
correct_pred_zero
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << pred_name << ":" << one_name << ":corr_preds";
|
|
||||||
description << "number of correct " << one_name << " preds";
|
|
||||||
correct_pred_one
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Number of predictor updates
|
|
||||||
//
|
|
||||||
name << pred_name << ":" << zero_name << ":updates";
|
|
||||||
description << "number of actual " << zero_name << "s";
|
|
||||||
record_zero
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << pred_name << ":" << one_name << ":updates";
|
|
||||||
description << "number of actual " << one_name << "s";
|
|
||||||
record_one
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaturatingCounterPred::regFormulas()
|
|
||||||
{
|
|
||||||
using namespace Stats;
|
|
||||||
stringstream name, description;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Number of predictions
|
|
||||||
//
|
|
||||||
name << pred_name << ":predictions";
|
|
||||||
preds_total
|
|
||||||
.name(name.str())
|
|
||||||
.desc("total number of predictions made")
|
|
||||||
;
|
|
||||||
preds_total = predicted_zero + predicted_one;
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fraction of all predictions that are one or zero
|
|
||||||
//
|
|
||||||
name << pred_name << ":" << zero_name << ":pred_frac";
|
|
||||||
description << "fraction of all preds that were " << zero_name;
|
|
||||||
pred_frac_zero
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
pred_frac_zero = 100 * predicted_zero / preds_total;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << pred_name << ":" << one_name << ":pred_frac";
|
|
||||||
description << "fraction of all preds that were " << one_name;
|
|
||||||
pred_frac_one
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
pred_frac_one = 100 * predicted_one / preds_total;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Count the number of correct predictions
|
|
||||||
//
|
|
||||||
name << pred_name << ":correct_preds";
|
|
||||||
correct_total
|
|
||||||
.name(name.str())
|
|
||||||
.desc("total correct predictions made")
|
|
||||||
;
|
|
||||||
correct_total = correct_pred_one + correct_pred_zero;
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Number of predictor updates
|
|
||||||
//
|
|
||||||
name << pred_name << ":updates";
|
|
||||||
updates_total
|
|
||||||
.name(name.str())
|
|
||||||
.desc("total number of updates")
|
|
||||||
;
|
|
||||||
updates_total = record_zero + record_one;
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prediction accuracy rates
|
|
||||||
//
|
|
||||||
name << pred_name << ":pred_rate";
|
|
||||||
pred_rate
|
|
||||||
.name(name.str())
|
|
||||||
.desc("correct fraction of all preds")
|
|
||||||
;
|
|
||||||
pred_rate = correct_total / updates_total;
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << pred_name << ":" << zero_name << ":pred_rate";
|
|
||||||
description << "fraction of " << zero_name << " preds that were correct";
|
|
||||||
frac_correct_zero
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
frac_correct_zero = 100 * correct_pred_zero /
|
|
||||||
(correct_pred_zero + record_one - correct_pred_one);
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << pred_name << ":" << one_name << ":pred_rate";
|
|
||||||
description << "fraction of " << one_name << " preds that were correct";
|
|
||||||
frac_correct_one
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
frac_correct_one = 100 * correct_pred_one /
|
|
||||||
(correct_pred_one + record_zero - correct_pred_zero);
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Coverage
|
|
||||||
//
|
|
||||||
name << pred_name << ":" << zero_name << ":coverage";
|
|
||||||
description << "fraction of " << zero_name
|
|
||||||
<< "s that were predicted correctly";
|
|
||||||
coverage_zero
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
coverage_zero = 100 * correct_pred_zero / record_zero;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
|
|
||||||
name << pred_name << ":" << one_name << ":coverage";
|
|
||||||
description << "fraction of " << one_name
|
|
||||||
<< "s that were predicted correctly";
|
|
||||||
coverage_one
|
|
||||||
.name(name.str())
|
|
||||||
.desc(description.str())
|
|
||||||
;
|
|
||||||
coverage_one = 100 * correct_pred_one / record_one;
|
|
||||||
description.str("");
|
|
||||||
name.str("");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,195 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 Raasch
|
|
||||||
* Steve Reinhardt
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SAT_COUNTER_HH__
|
|
||||||
#define __SAT_COUNTER_HH__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "base/predictor.hh"
|
|
||||||
|
|
||||||
#include "base/statistics.hh"
|
|
||||||
#include "sim/stats.hh"
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// A simple saturating counter predictor
|
|
||||||
//
|
|
||||||
//
|
|
||||||
class SaturatingCounterPred : public GenericPredictor
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string pred_name;
|
|
||||||
std::string zero_name;
|
|
||||||
std::string one_name;
|
|
||||||
|
|
||||||
unsigned index_bits;
|
|
||||||
unsigned counter_bits;
|
|
||||||
unsigned zero_change;
|
|
||||||
unsigned one_change;
|
|
||||||
unsigned thresh;
|
|
||||||
unsigned init_value;
|
|
||||||
|
|
||||||
unsigned max_value; // maximum counter value
|
|
||||||
|
|
||||||
unsigned long max_index; // also the index mask value
|
|
||||||
unsigned *table;
|
|
||||||
|
|
||||||
// Statistics
|
|
||||||
Stats::Scalar predicted_one; // Total predictions of one, preds_one
|
|
||||||
Stats::Scalar predicted_zero; // Total predictions of zero, preds_zero
|
|
||||||
Stats::Scalar correct_pred_one; // Total correct predictions of one, correct_one
|
|
||||||
Stats::Scalar correct_pred_zero; // Total correct predictions of zero, correct_zero
|
|
||||||
|
|
||||||
Stats::Scalar record_zero; //updates_zero
|
|
||||||
Stats::Scalar record_one; //updates_one
|
|
||||||
|
|
||||||
Stats::Formula preds_total;
|
|
||||||
Stats::Formula pred_frac_zero;
|
|
||||||
Stats::Formula pred_frac_one;
|
|
||||||
Stats::Formula correct_total;
|
|
||||||
Stats::Formula updates_total;
|
|
||||||
Stats::Formula pred_rate;
|
|
||||||
Stats::Formula frac_correct_zero;
|
|
||||||
Stats::Formula frac_correct_one;
|
|
||||||
Stats::Formula coverage_zero;
|
|
||||||
Stats::Formula coverage_one;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool pred_one(unsigned &counter) { return counter > thresh; }
|
|
||||||
bool pred_zero(unsigned &counter) { return counter <= thresh; }
|
|
||||||
|
|
||||||
void update_one(unsigned &counter) {
|
|
||||||
|
|
||||||
if (one_change)
|
|
||||||
counter += one_change;
|
|
||||||
else
|
|
||||||
counter = 0;
|
|
||||||
|
|
||||||
// check for wrap
|
|
||||||
if (counter > max_value)
|
|
||||||
counter = max_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_zero(unsigned &counter) {
|
|
||||||
if (zero_change) {
|
|
||||||
// check for wrap
|
|
||||||
if (counter < zero_change)
|
|
||||||
counter = 0;
|
|
||||||
else
|
|
||||||
counter -= zero_change;
|
|
||||||
} else
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
SaturatingCounterPred(std::string p_name,
|
|
||||||
std::string z_name, std::string o_name,
|
|
||||||
unsigned _index_bits, unsigned _counter_bits = 2,
|
|
||||||
unsigned _zero_change = 1, unsigned _one_change = 1,
|
|
||||||
unsigned _thresh = 1, unsigned _init_value = 0);
|
|
||||||
|
|
||||||
void
|
|
||||||
clear()
|
|
||||||
{
|
|
||||||
for (unsigned long i = 0; i <= max_index; ++i)
|
|
||||||
table[i] = init_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record the ACTUAL result... and indicate whether the prediction
|
|
||||||
// corresponding to this event was correct
|
|
||||||
void record(unsigned long _index, unsigned _val, unsigned _predicted,
|
|
||||||
unsigned _pdata)
|
|
||||||
{
|
|
||||||
record(_index, _val, _predicted);
|
|
||||||
}
|
|
||||||
|
|
||||||
void record(unsigned long _index, unsigned _val, unsigned _predicted) {
|
|
||||||
unsigned long index = _index & max_index;
|
|
||||||
|
|
||||||
if (_val) {
|
|
||||||
update_one(table[index]);
|
|
||||||
++record_one;
|
|
||||||
|
|
||||||
if (_predicted)
|
|
||||||
++correct_pred_one;
|
|
||||||
} else {
|
|
||||||
update_zero(table[index]);
|
|
||||||
++record_zero;
|
|
||||||
|
|
||||||
if (!_predicted)
|
|
||||||
++correct_pred_zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned value(unsigned long _index) {
|
|
||||||
unsigned long index = _index & max_index;
|
|
||||||
|
|
||||||
return table[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned predict(unsigned long _index, unsigned &pdata) {
|
|
||||||
return predict(_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned predict(unsigned long _index) {
|
|
||||||
unsigned long index = _index & max_index;
|
|
||||||
|
|
||||||
if (pred_one(table[index])) {
|
|
||||||
++predicted_one;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
++predicted_zero;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No internal state is changed here
|
|
||||||
unsigned peek(unsigned long _index) {
|
|
||||||
unsigned long index = _index & max_index;
|
|
||||||
|
|
||||||
if (pred_one(table[index]))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//=======================================================
|
|
||||||
void regStats();
|
|
||||||
void regFormulas();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __SAT_COUNTER_HH__
|
|
Loading…
Reference in a new issue