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;
|
||||
|
||||
default:
|
||||
panic("IPR memory space not implemented! PA=%x\n", req->paddr);
|
||||
panic("IPR memory space not implemented! PA=%x\n",
|
||||
req->paddr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1225,7 +1225,7 @@ declare {{
|
|||
{
|
||||
}
|
||||
|
||||
Addr branchTarget(Addr branchPC)
|
||||
Addr branchTarget(Addr branchPC) const
|
||||
{
|
||||
return branchPC + 4 + disp;
|
||||
}
|
||||
|
@ -1287,7 +1287,7 @@ declare {{
|
|||
{
|
||||
}
|
||||
|
||||
Addr branchTarget(ExecContext *xc)
|
||||
Addr branchTarget(ExecContext *xc) const
|
||||
{
|
||||
Addr NPC = xc->readPC() + 4;
|
||||
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
|
||||
|
@ -2330,10 +2330,6 @@ decode OPCODE default Unknown::unknown() {
|
|||
// miscellaneous mem-format ops
|
||||
0x18: decode MEMFUNC {
|
||||
format WarnUnimpl {
|
||||
0x0000: trapb();
|
||||
0x0400: excb();
|
||||
0x4000: mb();
|
||||
0x4400: wmb();
|
||||
0x8000: fetch();
|
||||
0xa000: fetch_m();
|
||||
0xe800: ecb();
|
||||
|
@ -2347,6 +2343,27 @@ decode OPCODE default Unknown::unknown() {
|
|||
|
||||
format BasicOperate {
|
||||
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
|
||||
|
@ -2356,13 +2373,13 @@ decode OPCODE default Unknown::unknown() {
|
|||
if (!xc->misspeculating()) {
|
||||
xc->regs.intrflag = 0;
|
||||
}
|
||||
}}, No_OpClass);
|
||||
}});
|
||||
0xf000: rs({{
|
||||
Ra = xc->regs.intrflag;
|
||||
if (!xc->misspeculating()) {
|
||||
xc->regs.intrflag = 1;
|
||||
}
|
||||
}}, No_OpClass);
|
||||
}});
|
||||
}
|
||||
#else
|
||||
format FailUnimpl {
|
||||
|
@ -2476,7 +2493,7 @@ decode OPCODE default Unknown::unknown() {
|
|||
if (!xc->misspeculating())
|
||||
AlphaPseudo::m5exit(xc);
|
||||
}}, No_OpClass);
|
||||
0x30: initparam({{ Ra = xc->cpu->system->init_param; }});
|
||||
0x30: initparam({{ Ra = cpu->system->init_param; }});
|
||||
0x40: resetstats({{
|
||||
if (!xc->misspeculating())
|
||||
AlphaPseudo::resetstats(xc);
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
* 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.
|
||||
*/
|
||||
|
|
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);
|
451
base/range.hh
451
base/range.hh
|
@ -29,232 +29,351 @@
|
|||
#ifndef __RANGE_HH__
|
||||
#define __RANGE_HH__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "base/intmath.hh"
|
||||
#include "base/str.hh"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
template <class T>
|
||||
class Range
|
||||
bool __parse_range(const std::string &s, T &start, T &end);
|
||||
|
||||
template <class T>
|
||||
struct Range
|
||||
{
|
||||
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:
|
||||
T start;
|
||||
T end;
|
||||
|
||||
public:
|
||||
Range() {}
|
||||
|
||||
Range(const Range &r) { operator=(r); }
|
||||
|
||||
Range(const T &s, const T &e)
|
||||
: start(s), end(e)
|
||||
Range()
|
||||
{
|
||||
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);
|
||||
bool parse(const std::string &s);
|
||||
const Range &operator=(const Range &r);
|
||||
template <class U>
|
||||
Range(const std::pair<U, U> &r)
|
||||
: start(r.first), end(r.second)
|
||||
{}
|
||||
|
||||
bool isValid() const { return valid; }
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
inline int
|
||||
Range<T>::compare(const T &p)
|
||||
Range(const std::string &s)
|
||||
{
|
||||
assert(isValid());
|
||||
|
||||
if (p < start)
|
||||
return -1;
|
||||
else if (p > end)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
parse(s);
|
||||
}
|
||||
|
||||
// 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)
|
||||
template <class U>
|
||||
const Range<T> &operator=(const Range<U> &r)
|
||||
{
|
||||
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;
|
||||
end = r.end;
|
||||
|
||||
valid = r.valid;
|
||||
}
|
||||
else {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
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>
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream &o, const Range<T> &r)
|
||||
{
|
||||
// don't currently support output of invalid ranges
|
||||
assert(r.isValid());
|
||||
assert(r.valid());
|
||||
o << r.start << ":" << r.end;
|
||||
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
|
||||
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
|
||||
return (l.isValid() && r.isValid() &&
|
||||
(l.start == r.start) && (l.end == r.end));
|
||||
assert(range1.valid() && range2.valid());
|
||||
return range1.start == range2.start && range1.end == range2.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
|
||||
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
|
||||
return (!l.isValid() || !r.isValid() ||
|
||||
(l.start != r.start) || (l.end != r.end));
|
||||
assert(range1.valid() && range2.valid());
|
||||
return range1.start != range2.start || range1.end != range2.end;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
//
|
||||
// Compare position to a range
|
||||
//
|
||||
// - 'pos == range' indicates that position pos is within the given range.
|
||||
// This test always returns false if the range is invalid.
|
||||
//
|
||||
// - 'pos < range' and 'pos > range' indicate that the position is
|
||||
// before the start of or after the end of the range, respectively.
|
||||
// The range must be valid for these comparisons to be made.
|
||||
//
|
||||
// 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 and does not overlap range1.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
assert(range1.valid() && range2.valid());
|
||||
return range1.end <= range2.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range1 is a range.
|
||||
* @param range2 is a range.
|
||||
* @return if range1 is less than range2. range1 may overlap range2,
|
||||
* but not extend beyond the end of range2.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<=(const Range<T> &range1, const Range<U> &range2)
|
||||
{
|
||||
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
|
||||
operator<(const T &pos, const Range<T> &range)
|
||||
{ assert(range.isValid()); return pos < range.start; }
|
||||
operator==(const Range<T> &range, const U &pos)
|
||||
{
|
||||
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
|
||||
operator>(const T &pos, const Range<T> &range)
|
||||
{ assert(range.isValid()); return pos > range.end; }
|
||||
operator!=(const Range<T> &range, const U &pos)
|
||||
{
|
||||
assert(range.valid());
|
||||
return pos < range.start || pos >= range.end;
|
||||
}
|
||||
|
||||
//
|
||||
// Derived comparisons
|
||||
//
|
||||
template<class T>
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* @return indicates that position pos is above the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator<=(const T &pos, const Range<T> &range)
|
||||
{ assert(range.isValid()); return pos <= range.end; }
|
||||
operator<(const Range<T> &range, const U &pos)
|
||||
{
|
||||
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
|
||||
operator>=(const T &pos, const Range<T> &range)
|
||||
{ assert(range.isValid()); return pos >= range.start; }
|
||||
operator<=(const Range<T> &range, const U &pos)
|
||||
{
|
||||
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
|
||||
operator!=(const T &pos, const Range<T> &range)
|
||||
{ return !(pos == range); }
|
||||
operator>(const Range<T> &range, const U &pos)
|
||||
{
|
||||
assert(range.valid());
|
||||
return range.start > pos;
|
||||
}
|
||||
|
||||
//
|
||||
// Define symmetric comparisons based on above
|
||||
//
|
||||
template<class T>
|
||||
/**
|
||||
* @param range range compared against.
|
||||
* @param pos position compared to the range.
|
||||
* 'range >= pos' indicates that position pos is below or in the range.
|
||||
*/
|
||||
template <class T, class U>
|
||||
inline bool
|
||||
operator>(const Range<T> &range, const 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); }
|
||||
|
||||
template<class T>
|
||||
inline bool
|
||||
operator!=(const Range<T> &range, const T &pos)
|
||||
{ return (pos != range); }
|
||||
operator>=(const Range<T> &range, const U &pos)
|
||||
{
|
||||
assert(range.valid());
|
||||
return range.end > pos;
|
||||
}
|
||||
|
||||
#endif // __RANGE_HH__
|
||||
|
|
|
@ -338,7 +338,7 @@ RemoteGDB::acc(Addr va, size_t len)
|
|||
}
|
||||
|
||||
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 <= "
|
||||
"%#x < K0SEG + size\n", va);
|
||||
return true;
|
||||
|
|
|
@ -78,6 +78,12 @@ class StaticInstBase : public RefCounted
|
|||
/// - If IsControl is set, then exactly one of IsDirectControl or
|
||||
/// IsIndirect Control will be set, and exactly one of
|
||||
/// IsCondControl or IsUncondControl will be set.
|
||||
/// - 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 {
|
||||
IsNop, ///< Is a no-op (no effect at all).
|
||||
|
@ -101,6 +107,11 @@ class StaticInstBase : public RefCounted
|
|||
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -178,6 +189,9 @@ class StaticInstBase : public RefCounted
|
|||
bool isUncondCtrl() const { return flags[IsUncondControl]; }
|
||||
|
||||
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.
|
||||
|
@ -216,11 +230,11 @@ class StaticInst : public StaticInstBase
|
|||
|
||||
/// Return logical index (architectural reg num) of i'th destination reg.
|
||||
/// Only the entries from 0 through numDestRegs()-1 are valid.
|
||||
RegIndex destRegIdx(int i) { return _destRegIdx[i]; }
|
||||
RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
|
||||
|
||||
/// Return logical index (architectural reg num) of i'th source reg.
|
||||
/// Only the entries from 0 through numSrcRegs()-1 are valid.
|
||||
RegIndex srcRegIdx(int i) { return _srcRegIdx[i]; }
|
||||
RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; }
|
||||
|
||||
/// Pointer to a statically allocated "null" instruction object.
|
||||
/// 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()
|
||||
* should be true).
|
||||
*/
|
||||
virtual Addr branchTarget(Addr branchPC)
|
||||
virtual Addr branchTarget(Addr branchPC) const
|
||||
{
|
||||
panic("StaticInst::branchTarget() called on instruction "
|
||||
"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
|
||||
* branch (i.e. isIndirectCtrl() should be true).
|
||||
*/
|
||||
virtual Addr branchTarget(ExecContext *xc)
|
||||
virtual Addr branchTarget(ExecContext *xc) const
|
||||
{
|
||||
panic("StaticInst::branchTarget() called on instruction "
|
||||
"that is not an indirect branch.");
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#define ALPHA_ACCESS_VERSION (1301) /* CH++*/
|
||||
|
||||
#ifndef CONSOLE
|
||||
#include <ostream>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
class Checkpoint;
|
||||
#endif
|
||||
|
|
|
@ -56,6 +56,8 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
|
|||
Addr addr, Addr mask, MemoryController *mmu)
|
||||
: MmapDevice(name, addr, mask, mmu), disk(d), console(cons)
|
||||
{
|
||||
mmu->add_child(this, Range<Addr>(addr, addr + size));
|
||||
|
||||
consoleData = new uint8_t[size];
|
||||
memset(consoleData, 0, size);
|
||||
|
||||
|
@ -66,7 +68,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
|
|||
|
||||
alphaAccess->version = ALPHA_ACCESS_VERSION;
|
||||
alphaAccess->numCPUs = num_cpus;
|
||||
alphaAccess->mem_size = system->physmem->getSize();
|
||||
alphaAccess->mem_size = system->physmem->size();
|
||||
alphaAccess->cpuClock = cpu->getFreq() / 1000000;
|
||||
alphaAccess->intrClockFrequency = clock->frequency();
|
||||
|
||||
|
@ -79,7 +81,8 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
|
|||
memset(data, 0, req->size);
|
||||
uint64_t val;
|
||||
|
||||
Addr daddr = req->paddr & addr_mask;
|
||||
Addr daddr = req->paddr - addr;
|
||||
|
||||
switch (daddr) {
|
||||
case offsetof(AlphaAccess, inputChar):
|
||||
val = console->console_in();
|
||||
|
@ -126,7 +129,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
|
|||
return Machine_Check_Fault;
|
||||
}
|
||||
|
||||
Addr daddr = req->paddr & addr_mask;
|
||||
Addr daddr = req->paddr - addr;
|
||||
ExecContext *other_xc;
|
||||
|
||||
switch (daddr) {
|
||||
|
@ -244,11 +247,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
|||
|
||||
SimObjectParam<SimConsole *> sim_console;
|
||||
SimObjectParam<SimpleDisk *> disk;
|
||||
Param<int> size;
|
||||
Param<int> num_cpus;
|
||||
SimObjectParam<MemoryController *> mmu;
|
||||
Param<Addr> addr;
|
||||
Param<Addr> mask;
|
||||
SimObjectParam<System *> system;
|
||||
SimObjectParam<BaseCPU *> cpu;
|
||||
SimObjectParam<TsunamiIO *> clock;
|
||||
|
@ -259,11 +260,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
|||
|
||||
INIT_PARAM(sim_console, "The Simulator Console"),
|
||||
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(mmu, "Memory Controller"),
|
||||
INIT_PARAM(addr, "Device Address"),
|
||||
INIT_PARAM(mask, "Address Mask"),
|
||||
INIT_PARAM(system, "system object"),
|
||||
INIT_PARAM(cpu, "Processor"),
|
||||
INIT_PARAM(clock, "Turbolaser Clock")
|
||||
|
@ -272,10 +271,8 @@ END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
|||
|
||||
CREATE_SIM_OBJECT(AlphaConsole)
|
||||
{
|
||||
return new AlphaConsole(getInstanceName(), sim_console,
|
||||
disk, size, system,
|
||||
cpu, clock, num_cpus,
|
||||
addr, mask, mmu);
|
||||
return new AlphaConsole(getInstanceName(), sim_console, disk,
|
||||
system, cpu, clock, num_cpus, mmu, addr);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)
|
||||
|
|
|
@ -33,9 +33,10 @@
|
|||
#ifndef __ALPHA_CONSOLE_HH__
|
||||
#define __ALPHA_CONSOLE_HH__
|
||||
|
||||
#include "sim/host.hh"
|
||||
#include "base/range.hh"
|
||||
#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"
|
||||
|
||||
class BaseCPU;
|
||||
|
@ -69,7 +70,7 @@ class SimpleDisk;
|
|||
* primarily used doing boot before the kernel has loaded its device
|
||||
* drivers.
|
||||
*/
|
||||
class AlphaConsole : public MmapDevice
|
||||
class AlphaConsole : public FunctionalMemory
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
|
@ -83,6 +84,9 @@ class AlphaConsole : public MmapDevice
|
|||
/** the system console (the terminal) is accessable from the console */
|
||||
SimConsole *console;
|
||||
|
||||
Addr addr;
|
||||
static const Addr size = 0x80; // equal to sizeof(alpha_access);
|
||||
|
||||
public:
|
||||
/** Standard Constructor */
|
||||
AlphaConsole(const std::string &name, SimConsole *cons,
|
||||
|
@ -91,7 +95,6 @@ class AlphaConsole : public MmapDevice
|
|||
TsunamiIO *clock, int num_cpus,
|
||||
Addr addr, Addr mask, MemoryController *mmu);
|
||||
|
||||
public:
|
||||
/**
|
||||
* memory mapped reads and writes
|
||||
*/
|
||||
|
|
|
@ -89,7 +89,7 @@ class EtherLink : public SimObject
|
|||
Link(const std::string &name, double rate, EtherDump *dump);
|
||||
~Link() {}
|
||||
|
||||
virtual std::string name() const { return objName; }
|
||||
virtual const std::string name() const { return objName; }
|
||||
|
||||
bool busy() const { return (bool)packet; }
|
||||
bool transmit(PacketPtr &packet);
|
||||
|
|
|
@ -153,7 +153,7 @@ class Event : public Serializable, public FastAlloc
|
|||
|
||||
~Event() {}
|
||||
|
||||
virtual std::string name() const {
|
||||
virtual const std::string name() const {
|
||||
return csprintf("Event_%x", (uintptr_t)this);
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ class EventQueue : public Serializable
|
|||
: 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
|
||||
void schedule(Event *ev);
|
||||
|
|
|
@ -186,7 +186,7 @@ INSTANTIATE_PARAM_TEMPLATES(string)
|
|||
class Globals : public Serializable
|
||||
{
|
||||
public:
|
||||
string name() const;
|
||||
const string name() const;
|
||||
void serialize(ostream &os);
|
||||
void unserialize(Checkpoint *cp);
|
||||
};
|
||||
|
@ -194,7 +194,7 @@ class Globals : public Serializable
|
|||
/// The one and only instance of the Globals class.
|
||||
Globals globals;
|
||||
|
||||
string
|
||||
const string
|
||||
Globals::name() const
|
||||
{
|
||||
return "Globals";
|
||||
|
|
|
@ -111,7 +111,7 @@ class Serializable
|
|||
virtual ~Serializable() {}
|
||||
|
||||
// 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 unserialize(Checkpoint *cp, const std::string §ion) {}
|
||||
|
|
|
@ -63,7 +63,7 @@ class SimObject : public Serializable
|
|||
|
||||
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()
|
||||
virtual void init();
|
||||
|
|
|
@ -49,7 +49,7 @@ nmtest: nmtest.o object_file.o symtab.o misc.o str.o
|
|||
offtest: offtest.o
|
||||
$(CXX) $(LFLAGS) -o $@ $^
|
||||
|
||||
rangetest: rangetest.o str.o
|
||||
rangetest: rangetest.o range.o str.o
|
||||
$(CXX) $(LFLAGS) -o $@ $^
|
||||
|
||||
stattest: cprintf.o hostinfo.o misc.o python.o statistics.o stattest.o \
|
||||
|
|
|
@ -31,11 +31,12 @@
|
|||
|
||||
#include "base/range.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
Range<int> r1(9, 28);
|
||||
Range<int> r1(make_pair(9, 28));
|
||||
Range<unsigned> r2("0x1000:+0x100");
|
||||
|
||||
cout << r1 << "\n"
|
||||
|
@ -44,61 +45,30 @@ main()
|
|||
#define RANGETEST(X, C, Y) \
|
||||
cout << X << " "#C" " << Y << " => " << ((X C Y) ? "true" : "false") << "\n"
|
||||
|
||||
int i1 = 10;
|
||||
int i2 = 0x1001;
|
||||
RANGETEST(i1, < , r1);
|
||||
RANGETEST(i1, <=, r1);
|
||||
RANGETEST(i1, > , r1);
|
||||
RANGETEST(i1, >=, r1);
|
||||
RANGETEST(i1, ==, r1);
|
||||
RANGETEST(i1, !=, r1);
|
||||
RANGETEST(r1, < , i1);
|
||||
RANGETEST(r1, <=, i1);
|
||||
RANGETEST(r1, > , i1);
|
||||
RANGETEST(r1, >=, i1);
|
||||
RANGETEST(r1, ==, i1);
|
||||
RANGETEST(r1, !=, i1);
|
||||
#define TESTEM(X, Y) do { \
|
||||
RANGETEST(X, < , Y); \
|
||||
RANGETEST(X, <=, Y); \
|
||||
RANGETEST(X, > , Y); \
|
||||
RANGETEST(X, >=, Y); \
|
||||
RANGETEST(X, ==, Y); \
|
||||
RANGETEST(X, !=, Y); \
|
||||
RANGETEST(Y, < , X); \
|
||||
RANGETEST(Y, <=, X); \
|
||||
RANGETEST(Y, > , X); \
|
||||
RANGETEST(Y, >=, X); \
|
||||
RANGETEST(Y, ==, X); \
|
||||
RANGETEST(Y, !=, X); \
|
||||
} while (0)
|
||||
|
||||
RANGETEST(i2, < , r1);
|
||||
RANGETEST(i2, <=, r1);
|
||||
RANGETEST(i2, > , r1);
|
||||
RANGETEST(i2, >=, 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);
|
||||
TESTEM(8, r1);
|
||||
TESTEM(9, r1);
|
||||
TESTEM(27, r1);
|
||||
TESTEM(28, r1);
|
||||
|
||||
unsigned u1 = 10;
|
||||
unsigned u2 = 0x1001;
|
||||
RANGETEST(u1, < , r2);
|
||||
RANGETEST(u1, <=, 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);
|
||||
TESTEM(0x0fff, r2);
|
||||
TESTEM(0x1000, r2);
|
||||
TESTEM(0x10ff, r2);
|
||||
TESTEM(0x1100, r2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue