Merge linux tree with head
arch/alpha/alpha_memory.cc: dev/alpha_console.cc: dev/alpha_console.hh: Merge --HG-- extra : convert_revision : 3233648f204338ab3f102ff117754dce955dcc37
This commit is contained in:
commit
eac2d6a668
17 changed files with 471 additions and 263 deletions
|
@ -97,7 +97,8 @@ AlphaTlb::checkCacheability(MemReqPtr &req)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("IPR memory space not implemented! PA=%x\n", req->paddr);
|
panic("IPR memory space not implemented! PA=%x\n",
|
||||||
|
req->paddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1225,7 +1225,7 @@ declare {{
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr branchTarget(Addr branchPC)
|
Addr branchTarget(Addr branchPC) const
|
||||||
{
|
{
|
||||||
return branchPC + 4 + disp;
|
return branchPC + 4 + disp;
|
||||||
}
|
}
|
||||||
|
@ -1287,7 +1287,7 @@ declare {{
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr branchTarget(ExecContext *xc)
|
Addr branchTarget(ExecContext *xc) const
|
||||||
{
|
{
|
||||||
Addr NPC = xc->readPC() + 4;
|
Addr NPC = xc->readPC() + 4;
|
||||||
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
|
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
|
||||||
|
@ -2330,10 +2330,6 @@ decode OPCODE default Unknown::unknown() {
|
||||||
// miscellaneous mem-format ops
|
// miscellaneous mem-format ops
|
||||||
0x18: decode MEMFUNC {
|
0x18: decode MEMFUNC {
|
||||||
format WarnUnimpl {
|
format WarnUnimpl {
|
||||||
0x0000: trapb();
|
|
||||||
0x0400: excb();
|
|
||||||
0x4000: mb();
|
|
||||||
0x4400: wmb();
|
|
||||||
0x8000: fetch();
|
0x8000: fetch();
|
||||||
0xa000: fetch_m();
|
0xa000: fetch_m();
|
||||||
0xe800: ecb();
|
0xe800: ecb();
|
||||||
|
@ -2347,6 +2343,27 @@ decode OPCODE default Unknown::unknown() {
|
||||||
|
|
||||||
format BasicOperate {
|
format BasicOperate {
|
||||||
0xc000: rpcc({{ Ra = curTick; }});
|
0xc000: rpcc({{ Ra = curTick; }});
|
||||||
|
|
||||||
|
// All of the barrier instructions below do nothing in
|
||||||
|
// their execute() methods (hence the empty code blocks).
|
||||||
|
// All of their functionality is hard-coded in the
|
||||||
|
// pipeline based on the flags IsSerializing,
|
||||||
|
// IsMemBarrier, and IsWriteBarrier. In the current
|
||||||
|
// detailed CPU model, the execute() function only gets
|
||||||
|
// called at fetch, so there's no way to generate pipeline
|
||||||
|
// behavior at any other stage. Once we go to an
|
||||||
|
// exec-in-exec CPU model we should be able to get rid of
|
||||||
|
// these flags and implement this behavior via the
|
||||||
|
// execute() methods.
|
||||||
|
|
||||||
|
// trapb is just a barrier on integer traps, where excb is
|
||||||
|
// a barrier on integer and FP traps. "EXCB is thus a
|
||||||
|
// superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat
|
||||||
|
// them the same though.
|
||||||
|
0x0000: trapb({{ }}, IsSerializing, No_OpClass);
|
||||||
|
0x0400: excb({{ }}, IsSerializing, No_OpClass);
|
||||||
|
0x4000: mb({{ }}, IsMemBarrier, RdPort);
|
||||||
|
0x4400: wmb({{ }}, IsWriteBarrier, WrPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FULL_SYSTEM
|
#ifdef FULL_SYSTEM
|
||||||
|
@ -2356,13 +2373,13 @@ decode OPCODE default Unknown::unknown() {
|
||||||
if (!xc->misspeculating()) {
|
if (!xc->misspeculating()) {
|
||||||
xc->regs.intrflag = 0;
|
xc->regs.intrflag = 0;
|
||||||
}
|
}
|
||||||
}}, No_OpClass);
|
}});
|
||||||
0xf000: rs({{
|
0xf000: rs({{
|
||||||
Ra = xc->regs.intrflag;
|
Ra = xc->regs.intrflag;
|
||||||
if (!xc->misspeculating()) {
|
if (!xc->misspeculating()) {
|
||||||
xc->regs.intrflag = 1;
|
xc->regs.intrflag = 1;
|
||||||
}
|
}
|
||||||
}}, No_OpClass);
|
}});
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
format FailUnimpl {
|
format FailUnimpl {
|
||||||
|
@ -2476,7 +2493,7 @@ decode OPCODE default Unknown::unknown() {
|
||||||
if (!xc->misspeculating())
|
if (!xc->misspeculating())
|
||||||
AlphaPseudo::m5exit(xc);
|
AlphaPseudo::m5exit(xc);
|
||||||
}}, No_OpClass);
|
}}, No_OpClass);
|
||||||
0x30: initparam({{ Ra = xc->cpu->system->init_param; }});
|
0x30: initparam({{ Ra = cpu->system->init_param; }});
|
||||||
0x40: resetstats({{
|
0x40: resetstats({{
|
||||||
if (!xc->misspeculating())
|
if (!xc->misspeculating())
|
||||||
AlphaPseudo::resetstats(xc);
|
AlphaPseudo::resetstats(xc);
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
* This file defines a doNothing compression algorithm.
|
* This file defines a doNothing compression algorithm.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h> // for uint8_t
|
||||||
|
#include "base/misc.hh" // for fatal()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A dummy compression class to use when no data compression is desired.
|
* A dummy compression class to use when no data compression is desired.
|
||||||
*/
|
*/
|
||||||
|
|
83
base/range.cc
Normal file
83
base/range.cc
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003 The Regents of The University of Michigan
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "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 &start, T &end)
|
||||||
|
{
|
||||||
|
std::vector<std::string> values;
|
||||||
|
tokenize(values, str, ':');
|
||||||
|
|
||||||
|
T thestart, theend;
|
||||||
|
|
||||||
|
if (values.size() != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string s = values[0];
|
||||||
|
std::string e = values[1];
|
||||||
|
|
||||||
|
if (!to_number(s, thestart))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool increment = (e[0] == '+');
|
||||||
|
if (increment)
|
||||||
|
e = e.substr(1);
|
||||||
|
|
||||||
|
if (!to_number(e, theend))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (increment)
|
||||||
|
theend += thestart;
|
||||||
|
|
||||||
|
start = thestart;
|
||||||
|
end = theend;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RANGE_PARSE(type) \
|
||||||
|
template<> bool \
|
||||||
|
__parse_range(const std::string &s, type &start, type &end) \
|
||||||
|
{ return __x_parse_range(s, start, end); }
|
||||||
|
|
||||||
|
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);
|
459
base/range.hh
459
base/range.hh
|
@ -29,232 +29,351 @@
|
||||||
#ifndef __RANGE_HH__
|
#ifndef __RANGE_HH__
|
||||||
#define __RANGE_HH__
|
#define __RANGE_HH__
|
||||||
|
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "base/intmath.hh"
|
template <class T>
|
||||||
#include "base/str.hh"
|
bool __parse_range(const std::string &s, T &start, T &end);
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
class Range
|
struct Range
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool valid;
|
/**
|
||||||
|
* @param s range string
|
||||||
|
* Ranges are in the following format:
|
||||||
|
* <range> := {<start_val>}:{<end>}
|
||||||
|
* <end> := <end_val> | +<delta>
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse(const std::string &s)
|
||||||
|
{
|
||||||
|
if (!__parse_range(s, start, end))
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
T start;
|
T start;
|
||||||
T end;
|
T end;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Range() {}
|
Range()
|
||||||
|
|
||||||
Range(const Range &r) { operator=(r); }
|
|
||||||
|
|
||||||
Range(const T &s, const T &e)
|
|
||||||
: start(s), end(e)
|
|
||||||
{
|
{
|
||||||
valid = (start <= end);
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
Range(const std::string &s) { valid = parse(s); }
|
Range(T first, T second)
|
||||||
|
: start(first), end(second)
|
||||||
|
{}
|
||||||
|
|
||||||
~Range() {}
|
template <class U>
|
||||||
|
Range(const Range<U> &r)
|
||||||
|
: start(r.start), end(r.end)
|
||||||
|
{}
|
||||||
|
|
||||||
int compare(const T &p);
|
template <class U>
|
||||||
bool parse(const std::string &s);
|
Range(const std::pair<U, U> &r)
|
||||||
const Range &operator=(const Range &r);
|
: start(r.first), end(r.second)
|
||||||
|
{}
|
||||||
|
|
||||||
bool isValid() const { return valid; }
|
Range(const std::string &s)
|
||||||
};
|
{
|
||||||
|
parse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class U>
|
||||||
template<class T>
|
const Range<T> &operator=(const Range<U> &r)
|
||||||
inline int
|
{
|
||||||
Range<T>::compare(const T &p)
|
|
||||||
{
|
|
||||||
assert(isValid());
|
|
||||||
|
|
||||||
if (p < start)
|
|
||||||
return -1;
|
|
||||||
else if (p > end)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse a range string
|
|
||||||
//
|
|
||||||
// Ranges are in the following format:
|
|
||||||
// <range> := {<start_val>}:{<end>}
|
|
||||||
// <end> := <end_val> | +<delta>
|
|
||||||
template<class T>
|
|
||||||
inline bool
|
|
||||||
Range<T>::parse(const std::string &str)
|
|
||||||
{
|
|
||||||
std::vector<std::string> values;
|
|
||||||
tokenize(values, str, ':');
|
|
||||||
|
|
||||||
T thestart, theend;
|
|
||||||
|
|
||||||
if (values.size() != 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string s = values[0];
|
|
||||||
std::string e = values[1];
|
|
||||||
|
|
||||||
if (!to_number(s, thestart))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool increment = (e[0] == '+');
|
|
||||||
if (increment)
|
|
||||||
e = e.substr(1);
|
|
||||||
|
|
||||||
if (!to_number(e, theend))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (increment)
|
|
||||||
theend += thestart;
|
|
||||||
|
|
||||||
start = thestart;
|
|
||||||
end = theend;
|
|
||||||
|
|
||||||
if (start > end)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline const Range<T> &
|
|
||||||
Range<T>::operator=(const Range<T> &r)
|
|
||||||
{
|
|
||||||
if (this != &r) {
|
|
||||||
start = r.start;
|
start = r.start;
|
||||||
end = r.end;
|
end = r.end;
|
||||||
|
|
||||||
valid = r.valid;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
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)
|
||||||
|
{
|
||||||
|
parse(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate() { start = 0; end = 0; }
|
||||||
|
T size() const { return end - start; }
|
||||||
|
bool valid() const { return start < end; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Range<T>
|
||||||
|
make_range(T start, T end)
|
||||||
|
{
|
||||||
|
return Range<T>(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
inline std::ostream &
|
inline std::ostream &
|
||||||
operator<<(std::ostream &o, const Range<T> &r)
|
operator<<(std::ostream &o, const Range<T> &r)
|
||||||
{
|
{
|
||||||
// don't currently support output of invalid ranges
|
// don't currently support output of invalid ranges
|
||||||
assert(r.isValid());
|
assert(r.valid());
|
||||||
o << r.start << ":" << r.end;
|
o << r.start << ":" << r.end;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Compare two ranges
|
// Range to Range Comparisons
|
||||||
//
|
//
|
||||||
template<class T>
|
|
||||||
|
/**
|
||||||
|
* @param range1 is a range.
|
||||||
|
* @param range2 is a range.
|
||||||
|
* @return if range1 and range2 are identical.
|
||||||
|
*/
|
||||||
|
template <class T, class U>
|
||||||
inline bool
|
inline bool
|
||||||
operator==(const Range<T> &l, const Range<T> &r)
|
operator==(const Range<T> &range1, const Range<U> &range2)
|
||||||
{
|
{
|
||||||
// ranges must both be valid to be equal
|
assert(range1.valid() && range2.valid());
|
||||||
return (l.isValid() && r.isValid() &&
|
return range1.start == range2.start && range1.end == range2.end;
|
||||||
(l.start == r.start) && (l.end == r.end));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
/**
|
||||||
|
* @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
|
inline bool
|
||||||
operator!=(const Range<T> &l, const Range<T> &r)
|
operator!=(const Range<T> &range1, const Range<U> &range2)
|
||||||
{
|
{
|
||||||
// for symmetry with ==, an invalid range is not equal to any other
|
assert(range1.valid() && range2.valid());
|
||||||
return (!l.isValid() || !r.isValid() ||
|
return range1.start != range2.start || range1.end != range2.end;
|
||||||
(l.start != r.start) || (l.end != r.end));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
/**
|
||||||
//
|
* @param range1 is a range.
|
||||||
// Compare position to a range
|
* @param range2 is a range.
|
||||||
//
|
* @return if range1 is less than range2 and does not overlap range1.
|
||||||
// - 'pos == range' indicates that position pos is within the given range.
|
*/
|
||||||
// This test always returns false if the range is invalid.
|
template <class T, class U>
|
||||||
//
|
inline bool
|
||||||
// - 'pos < range' and 'pos > range' indicate that the position is
|
operator<(const Range<T> &range1, const Range<U> &range2)
|
||||||
// before the start of or after the end of the range, respectively.
|
{
|
||||||
// The range must be valid for these comparisons to be made.
|
assert(range1.valid() && range2.valid());
|
||||||
//
|
return range1.end <= range2.start;
|
||||||
// All other comparisons do the obvious thing based on these definitions.
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
assert(range1.valid() && range2.valid());
|
||||||
|
return range1.start <= range2.start && range1.end <= range2.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
assert(range1.valid() && range2.valid());
|
||||||
|
return range1.start >= range2.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
assert(range1.valid() && range2.valid());
|
||||||
|
return range1.start >= range2.start && range1.end >= range2.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
return pos >= range.start;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Basic comparisons
|
// Range to Position Comparisons (for symmetry)
|
||||||
//
|
//
|
||||||
template<class T>
|
|
||||||
inline bool
|
|
||||||
operator==(const T &pos, const Range<T> &range)
|
|
||||||
{ return range.isValid() && pos >= range.start && pos <= range.end; }
|
|
||||||
|
|
||||||
template<class T>
|
/**
|
||||||
|
* @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
|
inline bool
|
||||||
operator<(const T &pos, const Range<T> &range)
|
operator==(const Range<T> &range, const U &pos)
|
||||||
{ assert(range.isValid()); return pos < range.start; }
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
return pos >= range.start && pos < range.end;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
/**
|
||||||
|
* @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
|
inline bool
|
||||||
operator>(const T &pos, const Range<T> &range)
|
operator!=(const Range<T> &range, const U &pos)
|
||||||
{ assert(range.isValid()); return pos > range.end; }
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
return pos < range.start || pos >= range.end;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
/**
|
||||||
// Derived comparisons
|
* @param range range compared against.
|
||||||
//
|
* @param pos position compared to the range.
|
||||||
template<class T>
|
* @return indicates that position pos is above the range.
|
||||||
|
*/
|
||||||
|
template <class T, class U>
|
||||||
inline bool
|
inline bool
|
||||||
operator<=(const T &pos, const Range<T> &range)
|
operator<(const Range<T> &range, const U &pos)
|
||||||
{ assert(range.isValid()); return pos <= range.end; }
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
return range.end <= pos;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
/**
|
||||||
|
* @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
|
inline bool
|
||||||
operator>=(const T &pos, const Range<T> &range)
|
operator<=(const Range<T> &range, const U &pos)
|
||||||
{ assert(range.isValid()); return pos >= range.start; }
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
return range.start <= pos;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
/**
|
||||||
|
* @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
|
inline bool
|
||||||
operator!=(const T &pos, const Range<T> &range)
|
operator>(const Range<T> &range, const U &pos)
|
||||||
{ return !(pos == range); }
|
{
|
||||||
|
assert(range.valid());
|
||||||
|
return range.start > pos;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
/**
|
||||||
// Define symmetric comparisons based on above
|
* @param range range compared against.
|
||||||
//
|
* @param pos position compared to the range.
|
||||||
template<class T>
|
* 'range >= pos' indicates that position pos is below or in the range.
|
||||||
|
*/
|
||||||
|
template <class T, class U>
|
||||||
inline bool
|
inline bool
|
||||||
operator>(const Range<T> &range, const T &pos)
|
operator>=(const Range<T> &range, const U &pos)
|
||||||
{ return pos < range; }
|
{
|
||||||
|
assert(range.valid());
|
||||||
template<class T>
|
return range.end > pos;
|
||||||
inline bool
|
}
|
||||||
operator<(const Range<T> &range, const T &pos)
|
|
||||||
{ return pos > range; }
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline bool
|
|
||||||
operator<=(const Range<T> &range, const T &pos)
|
|
||||||
{ return pos >= range; }
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline bool
|
|
||||||
operator>=(const Range<T> &range, const T &pos)
|
|
||||||
{ return pos <= range; }
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline bool
|
|
||||||
operator==(const Range<T> &range, const T &pos)
|
|
||||||
{ return (pos == range); }
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline bool
|
|
||||||
operator!=(const Range<T> &range, const T &pos)
|
|
||||||
{ return (pos != range); }
|
|
||||||
|
|
||||||
#endif // __RANGE_HH__
|
#endif // __RANGE_HH__
|
||||||
|
|
|
@ -338,7 +338,7 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (va < ALPHA_K1SEG_BASE) {
|
if (va < ALPHA_K1SEG_BASE) {
|
||||||
if (va < (ALPHA_K0SEG_BASE + pmem->getSize())) {
|
if (va < (ALPHA_K0SEG_BASE + pmem->size())) {
|
||||||
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
|
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
|
||||||
"%#x < K0SEG + size\n", va);
|
"%#x < K0SEG + size\n", va);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -78,6 +78,12 @@ class StaticInstBase : public RefCounted
|
||||||
/// - If IsControl is set, then exactly one of IsDirectControl or
|
/// - If IsControl is set, then exactly one of IsDirectControl or
|
||||||
/// IsIndirect Control will be set, and exactly one of
|
/// IsIndirect Control will be set, and exactly one of
|
||||||
/// IsCondControl or IsUncondControl will be set.
|
/// IsCondControl or IsUncondControl will be set.
|
||||||
|
/// - IsSerializing, IsMemBarrier, and IsWriteBarrier are
|
||||||
|
/// implemented as flags since in the current model there's no
|
||||||
|
/// other way for instructions to inject behavior into the
|
||||||
|
/// pipeline outside of fetch. Once we go to an exec-in-exec CPU
|
||||||
|
/// model we should be able to get rid of these flags and
|
||||||
|
/// implement this behavior via the execute() methods.
|
||||||
///
|
///
|
||||||
enum Flags {
|
enum Flags {
|
||||||
IsNop, ///< Is a no-op (no effect at all).
|
IsNop, ///< Is a no-op (no effect at all).
|
||||||
|
@ -101,6 +107,11 @@ class StaticInstBase : public RefCounted
|
||||||
|
|
||||||
IsThreadSync, ///< Thread synchronization operation.
|
IsThreadSync, ///< Thread synchronization operation.
|
||||||
|
|
||||||
|
IsSerializing, ///< Serializes pipeline: won't until all
|
||||||
|
/// older instructions have committed.
|
||||||
|
IsMemBarrier, ///< Is a memory barrier
|
||||||
|
IsWriteBarrier, ///< Is a write barrier
|
||||||
|
|
||||||
NumFlags
|
NumFlags
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -178,6 +189,9 @@ class StaticInstBase : public RefCounted
|
||||||
bool isUncondCtrl() const { return flags[IsUncondControl]; }
|
bool isUncondCtrl() const { return flags[IsUncondControl]; }
|
||||||
|
|
||||||
bool isThreadSync() const { return flags[IsThreadSync]; }
|
bool isThreadSync() const { return flags[IsThreadSync]; }
|
||||||
|
bool isSerializing() const { return flags[IsSerializing]; }
|
||||||
|
bool isMemBarrier() const { return flags[IsMemBarrier]; }
|
||||||
|
bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// Operation class. Used to select appropriate function unit in issue.
|
/// Operation class. Used to select appropriate function unit in issue.
|
||||||
|
@ -216,11 +230,11 @@ class StaticInst : public StaticInstBase
|
||||||
|
|
||||||
/// Return logical index (architectural reg num) of i'th destination reg.
|
/// Return logical index (architectural reg num) of i'th destination reg.
|
||||||
/// Only the entries from 0 through numDestRegs()-1 are valid.
|
/// Only the entries from 0 through numDestRegs()-1 are valid.
|
||||||
RegIndex destRegIdx(int i) { return _destRegIdx[i]; }
|
RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
|
||||||
|
|
||||||
/// Return logical index (architectural reg num) of i'th source reg.
|
/// Return logical index (architectural reg num) of i'th source reg.
|
||||||
/// Only the entries from 0 through numSrcRegs()-1 are valid.
|
/// Only the entries from 0 through numSrcRegs()-1 are valid.
|
||||||
RegIndex srcRegIdx(int i) { return _srcRegIdx[i]; }
|
RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; }
|
||||||
|
|
||||||
/// Pointer to a statically allocated "null" instruction object.
|
/// Pointer to a statically allocated "null" instruction object.
|
||||||
/// Used to give eaCompInst() and memAccInst() something to return
|
/// Used to give eaCompInst() and memAccInst() something to return
|
||||||
|
@ -305,7 +319,7 @@ class StaticInst : public StaticInstBase
|
||||||
* Invalid if not a PC-relative branch (i.e. isDirectCtrl()
|
* Invalid if not a PC-relative branch (i.e. isDirectCtrl()
|
||||||
* should be true).
|
* should be true).
|
||||||
*/
|
*/
|
||||||
virtual Addr branchTarget(Addr branchPC)
|
virtual Addr branchTarget(Addr branchPC) const
|
||||||
{
|
{
|
||||||
panic("StaticInst::branchTarget() called on instruction "
|
panic("StaticInst::branchTarget() called on instruction "
|
||||||
"that is not a PC-relative branch.");
|
"that is not a PC-relative branch.");
|
||||||
|
@ -318,7 +332,7 @@ class StaticInst : public StaticInstBase
|
||||||
* execute the branch in question. Invalid if not an indirect
|
* execute the branch in question. Invalid if not an indirect
|
||||||
* branch (i.e. isIndirectCtrl() should be true).
|
* branch (i.e. isIndirectCtrl() should be true).
|
||||||
*/
|
*/
|
||||||
virtual Addr branchTarget(ExecContext *xc)
|
virtual Addr branchTarget(ExecContext *xc) const
|
||||||
{
|
{
|
||||||
panic("StaticInst::branchTarget() called on instruction "
|
panic("StaticInst::branchTarget() called on instruction "
|
||||||
"that is not an indirect branch.");
|
"that is not an indirect branch.");
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#define ALPHA_ACCESS_VERSION (1301) /* CH++*/
|
#define ALPHA_ACCESS_VERSION (1301) /* CH++*/
|
||||||
|
|
||||||
#ifndef CONSOLE
|
#ifndef CONSOLE
|
||||||
#include <ostream>
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,6 +56,8 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
|
||||||
Addr addr, Addr mask, MemoryController *mmu)
|
Addr addr, Addr mask, MemoryController *mmu)
|
||||||
: MmapDevice(name, addr, mask, mmu), disk(d), console(cons)
|
: MmapDevice(name, addr, mask, mmu), disk(d), console(cons)
|
||||||
{
|
{
|
||||||
|
mmu->add_child(this, Range<Addr>(addr, addr + size));
|
||||||
|
|
||||||
consoleData = new uint8_t[size];
|
consoleData = new uint8_t[size];
|
||||||
memset(consoleData, 0, size);
|
memset(consoleData, 0, size);
|
||||||
|
|
||||||
|
@ -66,7 +68,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
|
||||||
|
|
||||||
alphaAccess->version = ALPHA_ACCESS_VERSION;
|
alphaAccess->version = ALPHA_ACCESS_VERSION;
|
||||||
alphaAccess->numCPUs = num_cpus;
|
alphaAccess->numCPUs = num_cpus;
|
||||||
alphaAccess->mem_size = system->physmem->getSize();
|
alphaAccess->mem_size = system->physmem->size();
|
||||||
alphaAccess->cpuClock = cpu->getFreq() / 1000000;
|
alphaAccess->cpuClock = cpu->getFreq() / 1000000;
|
||||||
alphaAccess->intrClockFrequency = clock->frequency();
|
alphaAccess->intrClockFrequency = clock->frequency();
|
||||||
|
|
||||||
|
@ -79,7 +81,8 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
||||||
memset(data, 0, req->size);
|
memset(data, 0, req->size);
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
|
||||||
Addr daddr = req->paddr & addr_mask;
|
Addr daddr = req->paddr - addr;
|
||||||
|
|
||||||
switch (daddr) {
|
switch (daddr) {
|
||||||
case offsetof(AlphaAccess, inputChar):
|
case offsetof(AlphaAccess, inputChar):
|
||||||
val = console->console_in();
|
val = console->console_in();
|
||||||
|
@ -126,7 +129,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
|
||||||
return Machine_Check_Fault;
|
return Machine_Check_Fault;
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr daddr = req->paddr & addr_mask;
|
Addr daddr = req->paddr - addr;
|
||||||
ExecContext *other_xc;
|
ExecContext *other_xc;
|
||||||
|
|
||||||
switch (daddr) {
|
switch (daddr) {
|
||||||
|
@ -244,11 +247,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
|
||||||
SimObjectParam<SimConsole *> sim_console;
|
SimObjectParam<SimConsole *> sim_console;
|
||||||
SimObjectParam<SimpleDisk *> disk;
|
SimObjectParam<SimpleDisk *> disk;
|
||||||
Param<int> size;
|
|
||||||
Param<int> num_cpus;
|
Param<int> num_cpus;
|
||||||
SimObjectParam<MemoryController *> mmu;
|
SimObjectParam<MemoryController *> mmu;
|
||||||
Param<Addr> addr;
|
Param<Addr> addr;
|
||||||
Param<Addr> mask;
|
|
||||||
SimObjectParam<System *> system;
|
SimObjectParam<System *> system;
|
||||||
SimObjectParam<BaseCPU *> cpu;
|
SimObjectParam<BaseCPU *> cpu;
|
||||||
SimObjectParam<TsunamiIO *> clock;
|
SimObjectParam<TsunamiIO *> clock;
|
||||||
|
@ -259,11 +260,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
|
||||||
INIT_PARAM(sim_console, "The Simulator Console"),
|
INIT_PARAM(sim_console, "The Simulator Console"),
|
||||||
INIT_PARAM(disk, "Simple Disk"),
|
INIT_PARAM(disk, "Simple Disk"),
|
||||||
INIT_PARAM_DFLT(size, "AlphaConsole size", sizeof(AlphaAccess)),
|
|
||||||
INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
|
INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(mmu, "Memory Controller"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(addr, "Device Address"),
|
||||||
INIT_PARAM(mask, "Address Mask"),
|
|
||||||
INIT_PARAM(system, "system object"),
|
INIT_PARAM(system, "system object"),
|
||||||
INIT_PARAM(cpu, "Processor"),
|
INIT_PARAM(cpu, "Processor"),
|
||||||
INIT_PARAM(clock, "Turbolaser Clock")
|
INIT_PARAM(clock, "Turbolaser Clock")
|
||||||
|
@ -272,10 +271,8 @@ END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(AlphaConsole)
|
CREATE_SIM_OBJECT(AlphaConsole)
|
||||||
{
|
{
|
||||||
return new AlphaConsole(getInstanceName(), sim_console,
|
return new AlphaConsole(getInstanceName(), sim_console, disk,
|
||||||
disk, size, system,
|
system, cpu, clock, num_cpus, mmu, addr);
|
||||||
cpu, clock, num_cpus,
|
|
||||||
addr, mask, mmu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
|
REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
|
||||||
|
|
|
@ -33,9 +33,10 @@
|
||||||
#ifndef __ALPHA_CONSOLE_HH__
|
#ifndef __ALPHA_CONSOLE_HH__
|
||||||
#define __ALPHA_CONSOLE_HH__
|
#define __ALPHA_CONSOLE_HH__
|
||||||
|
|
||||||
#include "sim/host.hh"
|
#include "base/range.hh"
|
||||||
#include "dev/alpha_access.h"
|
#include "dev/alpha_access.h"
|
||||||
#include "mem/functional_mem/mmap_device.hh"
|
#include "mem/functional_mem/functional_memory.hh"
|
||||||
|
#include "sim/host.hh"
|
||||||
#include "dev/tsunami_io.hh"
|
#include "dev/tsunami_io.hh"
|
||||||
|
|
||||||
class BaseCPU;
|
class BaseCPU;
|
||||||
|
@ -69,7 +70,7 @@ class SimpleDisk;
|
||||||
* primarily used doing boot before the kernel has loaded its device
|
* primarily used doing boot before the kernel has loaded its device
|
||||||
* drivers.
|
* drivers.
|
||||||
*/
|
*/
|
||||||
class AlphaConsole : public MmapDevice
|
class AlphaConsole : public FunctionalMemory
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
|
@ -83,6 +84,9 @@ class AlphaConsole : public MmapDevice
|
||||||
/** the system console (the terminal) is accessable from the console */
|
/** the system console (the terminal) is accessable from the console */
|
||||||
SimConsole *console;
|
SimConsole *console;
|
||||||
|
|
||||||
|
Addr addr;
|
||||||
|
static const Addr size = 0x80; // equal to sizeof(alpha_access);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Standard Constructor */
|
/** Standard Constructor */
|
||||||
AlphaConsole(const std::string &name, SimConsole *cons,
|
AlphaConsole(const std::string &name, SimConsole *cons,
|
||||||
|
@ -91,7 +95,6 @@ class AlphaConsole : public MmapDevice
|
||||||
TsunamiIO *clock, int num_cpus,
|
TsunamiIO *clock, int num_cpus,
|
||||||
Addr addr, Addr mask, MemoryController *mmu);
|
Addr addr, Addr mask, MemoryController *mmu);
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
* memory mapped reads and writes
|
* memory mapped reads and writes
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -89,7 +89,7 @@ class EtherLink : public SimObject
|
||||||
Link(const std::string &name, double rate, EtherDump *dump);
|
Link(const std::string &name, double rate, EtherDump *dump);
|
||||||
~Link() {}
|
~Link() {}
|
||||||
|
|
||||||
virtual std::string name() const { return objName; }
|
virtual const std::string name() const { return objName; }
|
||||||
|
|
||||||
bool busy() const { return (bool)packet; }
|
bool busy() const { return (bool)packet; }
|
||||||
bool transmit(PacketPtr &packet);
|
bool transmit(PacketPtr &packet);
|
||||||
|
|
|
@ -153,7 +153,7 @@ class Event : public Serializable, public FastAlloc
|
||||||
|
|
||||||
~Event() {}
|
~Event() {}
|
||||||
|
|
||||||
virtual std::string name() const {
|
virtual const std::string name() const {
|
||||||
return csprintf("Event_%x", (uintptr_t)this);
|
return csprintf("Event_%x", (uintptr_t)this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ class EventQueue : public Serializable
|
||||||
: objName(n), head(NULL)
|
: objName(n), head(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual std::string name() const { return objName; }
|
virtual const std::string name() const { return objName; }
|
||||||
|
|
||||||
// schedule the given event on this queue
|
// schedule the given event on this queue
|
||||||
void schedule(Event *ev);
|
void schedule(Event *ev);
|
||||||
|
|
|
@ -186,7 +186,7 @@ INSTANTIATE_PARAM_TEMPLATES(string)
|
||||||
class Globals : public Serializable
|
class Globals : public Serializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
string name() const;
|
const string name() const;
|
||||||
void serialize(ostream &os);
|
void serialize(ostream &os);
|
||||||
void unserialize(Checkpoint *cp);
|
void unserialize(Checkpoint *cp);
|
||||||
};
|
};
|
||||||
|
@ -194,7 +194,7 @@ class Globals : public Serializable
|
||||||
/// The one and only instance of the Globals class.
|
/// The one and only instance of the Globals class.
|
||||||
Globals globals;
|
Globals globals;
|
||||||
|
|
||||||
string
|
const string
|
||||||
Globals::name() const
|
Globals::name() const
|
||||||
{
|
{
|
||||||
return "Globals";
|
return "Globals";
|
||||||
|
|
|
@ -111,7 +111,7 @@ class Serializable
|
||||||
virtual ~Serializable() {}
|
virtual ~Serializable() {}
|
||||||
|
|
||||||
// manditory virtual function, so objects must provide names
|
// manditory virtual function, so objects must provide names
|
||||||
virtual std::string name() const = 0;
|
virtual const std::string name() const = 0;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os) {}
|
virtual void serialize(std::ostream &os) {}
|
||||||
virtual void unserialize(Checkpoint *cp, const std::string §ion) {}
|
virtual void unserialize(Checkpoint *cp, const std::string §ion) {}
|
||||||
|
|
|
@ -63,7 +63,7 @@ class SimObject : public Serializable
|
||||||
|
|
||||||
virtual ~SimObject() {}
|
virtual ~SimObject() {}
|
||||||
|
|
||||||
virtual std::string name() const { return objName; }
|
virtual const std::string name() const { return objName; }
|
||||||
|
|
||||||
// initialization pass of all objects. Gets invoked by SimInit()
|
// initialization pass of all objects. Gets invoked by SimInit()
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
|
@ -49,7 +49,7 @@ nmtest: nmtest.o object_file.o symtab.o misc.o str.o
|
||||||
offtest: offtest.o
|
offtest: offtest.o
|
||||||
$(CXX) $(LFLAGS) -o $@ $^
|
$(CXX) $(LFLAGS) -o $@ $^
|
||||||
|
|
||||||
rangetest: rangetest.o str.o
|
rangetest: rangetest.o range.o str.o
|
||||||
$(CXX) $(LFLAGS) -o $@ $^
|
$(CXX) $(LFLAGS) -o $@ $^
|
||||||
|
|
||||||
stattest: cprintf.o hostinfo.o misc.o python.o statistics.o stattest.o \
|
stattest: cprintf.o hostinfo.o misc.o python.o statistics.o stattest.o \
|
||||||
|
|
|
@ -31,11 +31,12 @@
|
||||||
|
|
||||||
#include "base/range.hh"
|
#include "base/range.hh"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
Range<int> r1(9, 28);
|
Range<int> r1(make_pair(9, 28));
|
||||||
Range<unsigned> r2("0x1000:+0x100");
|
Range<unsigned> r2("0x1000:+0x100");
|
||||||
|
|
||||||
cout << r1 << "\n"
|
cout << r1 << "\n"
|
||||||
|
@ -44,61 +45,30 @@ main()
|
||||||
#define RANGETEST(X, C, Y) \
|
#define RANGETEST(X, C, Y) \
|
||||||
cout << X << " "#C" " << Y << " => " << ((X C Y) ? "true" : "false") << "\n"
|
cout << X << " "#C" " << Y << " => " << ((X C Y) ? "true" : "false") << "\n"
|
||||||
|
|
||||||
int i1 = 10;
|
#define TESTEM(X, Y) do { \
|
||||||
int i2 = 0x1001;
|
RANGETEST(X, < , Y); \
|
||||||
RANGETEST(i1, < , r1);
|
RANGETEST(X, <=, Y); \
|
||||||
RANGETEST(i1, <=, r1);
|
RANGETEST(X, > , Y); \
|
||||||
RANGETEST(i1, > , r1);
|
RANGETEST(X, >=, Y); \
|
||||||
RANGETEST(i1, >=, r1);
|
RANGETEST(X, ==, Y); \
|
||||||
RANGETEST(i1, ==, r1);
|
RANGETEST(X, !=, Y); \
|
||||||
RANGETEST(i1, !=, r1);
|
RANGETEST(Y, < , X); \
|
||||||
RANGETEST(r1, < , i1);
|
RANGETEST(Y, <=, X); \
|
||||||
RANGETEST(r1, <=, i1);
|
RANGETEST(Y, > , X); \
|
||||||
RANGETEST(r1, > , i1);
|
RANGETEST(Y, >=, X); \
|
||||||
RANGETEST(r1, >=, i1);
|
RANGETEST(Y, ==, X); \
|
||||||
RANGETEST(r1, ==, i1);
|
RANGETEST(Y, !=, X); \
|
||||||
RANGETEST(r1, !=, i1);
|
} while (0)
|
||||||
|
|
||||||
RANGETEST(i2, < , r1);
|
TESTEM(8, r1);
|
||||||
RANGETEST(i2, <=, r1);
|
TESTEM(9, r1);
|
||||||
RANGETEST(i2, > , r1);
|
TESTEM(27, r1);
|
||||||
RANGETEST(i2, >=, r1);
|
TESTEM(28, r1);
|
||||||
RANGETEST(i2, ==, r1);
|
|
||||||
RANGETEST(i2, !=, r1);
|
|
||||||
RANGETEST(r1, < , i2);
|
|
||||||
RANGETEST(r1, <=, i2);
|
|
||||||
RANGETEST(r1, > , i2);
|
|
||||||
RANGETEST(r1, >=, i2);
|
|
||||||
RANGETEST(r1, ==, i2);
|
|
||||||
RANGETEST(r1, !=, i2);
|
|
||||||
|
|
||||||
unsigned u1 = 10;
|
TESTEM(0x0fff, r2);
|
||||||
unsigned u2 = 0x1001;
|
TESTEM(0x1000, r2);
|
||||||
RANGETEST(u1, < , r2);
|
TESTEM(0x10ff, r2);
|
||||||
RANGETEST(u1, <=, r2);
|
TESTEM(0x1100, r2);
|
||||||
RANGETEST(u1, > , r2);
|
|
||||||
RANGETEST(u1, >=, r2);
|
|
||||||
RANGETEST(u1, ==, r2);
|
|
||||||
RANGETEST(u1, !=, r2);
|
|
||||||
RANGETEST(r2, < , u1);
|
|
||||||
RANGETEST(r2, <=, u1);
|
|
||||||
RANGETEST(r2, > , u1);
|
|
||||||
RANGETEST(r2, >=, u1);
|
|
||||||
RANGETEST(r2, ==, u1);
|
|
||||||
RANGETEST(r2, !=, u1);
|
|
||||||
|
|
||||||
RANGETEST(u2, < , r2);
|
|
||||||
RANGETEST(u2, <=, r2);
|
|
||||||
RANGETEST(u2, > , r2);
|
|
||||||
RANGETEST(u2, >=, r2);
|
|
||||||
RANGETEST(u2, ==, r2);
|
|
||||||
RANGETEST(u2, !=, r2);
|
|
||||||
RANGETEST(r2, < , u2);
|
|
||||||
RANGETEST(r2, <=, u2);
|
|
||||||
RANGETEST(r2, > , u2);
|
|
||||||
RANGETEST(r2, >=, u2);
|
|
||||||
RANGETEST(r2, ==, u2);
|
|
||||||
RANGETEST(r2, !=, u2);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue