summaryrefslogtreecommitdiff
path: root/src/mem/ruby/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/common')
-rw-r--r--src/mem/ruby/common/Address.cc68
-rw-r--r--src/mem/ruby/common/Address.hh255
-rw-r--r--src/mem/ruby/common/BigSet.cc249
-rw-r--r--src/mem/ruby/common/BigSet.hh125
-rw-r--r--src/mem/ruby/common/Consumer.hh89
-rw-r--r--src/mem/ruby/common/DataBlock.cc91
-rw-r--r--src/mem/ruby/common/DataBlock.hh82
-rw-r--r--src/mem/ruby/common/Debug.cc369
-rw-r--r--src/mem/ruby/common/Debug.def17
-rw-r--r--src/mem/ruby/common/Debug.hh291
-rw-r--r--src/mem/ruby/common/Driver.cc39
-rw-r--r--src/mem/ruby/common/Driver.hh98
-rw-r--r--src/mem/ruby/common/Global.cc35
-rw-r--r--src/mem/ruby/common/Global.hh110
-rw-r--r--src/mem/ruby/common/Histogram.cc185
-rw-r--r--src/mem/ruby/common/Histogram.hh104
-rw-r--r--src/mem/ruby/common/Message.cc34
-rw-r--r--src/mem/ruby/common/NetDest.cc259
-rw-r--r--src/mem/ruby/common/NetDest.hh145
-rw-r--r--src/mem/ruby/common/OptBigSet.cc576
-rw-r--r--src/mem/ruby/common/OptBigSet.hh202
-rw-r--r--src/mem/ruby/common/Set.cc231
-rw-r--r--src/mem/ruby/common/Set.hh149
-rw-r--r--src/mem/ruby/common/SubBlock.cc81
-rw-r--r--src/mem/ruby/common/SubBlock.hh105
25 files changed, 3989 insertions, 0 deletions
diff --git a/src/mem/ruby/common/Address.cc b/src/mem/ruby/common/Address.cc
new file mode 100644
index 000000000..5d38faae0
--- /dev/null
+++ b/src/mem/ruby/common/Address.cc
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "Address.hh"
+
+void Address::output(ostream& out) const
+{
+ // Note: this outputs addresses in the form "ffff", not "0xffff".
+ // This code should always be able to write out addresses in a
+ // format that can be read in by the below input() method. Please
+ // don't change this without talking to Milo first.
+ out << hex << m_address << dec;
+}
+
+void Address::input(istream& in)
+{
+ // Note: this only works with addresses in the form "ffff", not
+ // "0xffff". This code should always be able to read in addresses
+ // written out by the above output() method. Please don't change
+ // this without talking to Milo first.
+ in >> hex >> m_address >> dec;
+}
+
+Address::Address(const Address& obj)
+{
+ m_address = obj.m_address;
+}
+
+Address& Address::operator=(const Address& obj)
+{
+ if (this == &obj) {
+ // assert(false);
+ } else {
+ m_address = obj.m_address;
+ }
+ return *this;
+}
+
diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh
new file mode 100644
index 000000000..3c3c5ad30
--- /dev/null
+++ b/src/mem/ruby/common/Address.hh
@@ -0,0 +1,255 @@
+
+/*
+ * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin
+ * Multifacet Project. ALL RIGHTS RESERVED.
+ *
+ * ##HEADER##
+ *
+ * This software is furnished under a license and may be used and
+ * copied only in accordance with the terms of such license and the
+ * inclusion of the above copyright notice. This software or any
+ * other copies thereof or any derivative works may not be provided or
+ * otherwise made available to any other persons. Title to and
+ * ownership of the software is retained by Mark Hill and David Wood.
+ * Any use of this software must include the above copyright notice.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO
+ * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE.
+ * */
+
+/*
+ * $Id$
+ */
+
+#ifndef ADDRESS_H
+#define ADDRESS_H
+
+#include <iomanip>
+#include "Global.hh"
+#include "RubyConfig.hh"
+#include "NodeID.hh"
+#include "MachineID.hh"
+
+const int ADDRESS_WIDTH = 64; // address width in bytes
+
+class Address;
+typedef Address PhysAddress;
+typedef Address VirtAddress;
+
+class Address {
+public:
+ // Constructors
+ Address() { m_address = 0; }
+ explicit Address(physical_address_t address) { m_address = address; }
+
+ Address(const Address& obj);
+ Address& operator=(const Address& obj);
+
+ // Destructor
+ // ~Address();
+
+ // Public Methods
+
+ void setAddress(physical_address_t address) { m_address = address; }
+ physical_address_t getAddress() const {return m_address;}
+ // selects bits inclusive
+ physical_address_t bitSelect(int small, int big) const;
+ physical_address_t maskLowOrderBits(int number) const;
+ physical_address_t maskHighOrderBits(int number) const;
+ physical_address_t shiftLowOrderBits(int number) const;
+ physical_address_t getLineAddress() const
+ { return bitSelect(RubyConfig::dataBlockBits(), ADDRESS_WIDTH); }
+ physical_address_t getOffset() const
+ { return bitSelect(0, RubyConfig::dataBlockBits()-1); }
+
+ void makeLineAddress() { m_address = maskLowOrderBits(RubyConfig::dataBlockBits()); }
+ // returns the next stride address based on line address
+ void makeNextStrideAddress( int stride) {
+ m_address = maskLowOrderBits(RubyConfig::dataBlockBits())
+ + RubyConfig::dataBlockBytes()*stride;
+ }
+ void makePageAddress() { m_address = maskLowOrderBits(RubyConfig::pageSizeBits()); }
+ int getBankSetNum() const;
+ int getBankSetDist() const;
+
+ Index memoryModuleIndex() const;
+
+ void print(ostream& out) const;
+ void output(ostream& out) const;
+ void input(istream& in);
+
+ void setOffset( int offset ){
+ // first, zero out the offset bits
+ makeLineAddress();
+ m_address |= (physical_address_t) offset;
+ }
+
+private:
+ // Private Methods
+
+ // Private copy constructor and assignment operator
+ // Address(const Address& obj);
+ // Address& operator=(const Address& obj);
+
+ // Data Members (m_ prefix)
+ physical_address_t m_address;
+};
+
+inline
+Address line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; }
+
+inline
+Address next_stride_address(const Address& addr, int stride) {
+ Address temp = addr;
+ temp.makeNextStrideAddress(stride);
+ temp.setAddress(temp.maskHighOrderBits(ADDRESS_WIDTH-RubyConfig::memorySizeBits())); // surpress wrap-around problem
+ return temp;
+}
+
+inline
+Address page_address(const Address& addr) { Address temp(addr); temp.makePageAddress(); return temp; }
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Address& obj);
+// comparison operator declaration
+bool operator==(const Address& obj1, const Address& obj2);
+bool operator!=(const Address& obj1, const Address& obj2);
+bool operator<(const Address& obj1, const Address& obj2);
+/* Address& operator=(const physical_address_t address); */
+
+inline
+bool operator<(const Address& obj1, const Address& obj2)
+{
+ return obj1.getAddress() < obj2.getAddress();
+}
+
+// ******************* Definitions *******************
+
+// Output operator definition
+inline
+ostream& operator<<(ostream& out, const Address& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+inline
+bool operator==(const Address& obj1, const Address& obj2)
+{
+ return (obj1.getAddress() == obj2.getAddress());
+}
+
+inline
+bool operator!=(const Address& obj1, const Address& obj2)
+{
+ return (obj1.getAddress() != obj2.getAddress());
+}
+
+inline
+physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive
+{
+ physical_address_t mask;
+ assert(big >= small);
+
+ if (big >= ADDRESS_WIDTH - 1) {
+ return (m_address >> small);
+ } else {
+ mask = ~((physical_address_t)~0 << (big + 1));
+ // FIXME - this is slow to manipulate a 64-bit number using 32-bits
+ physical_address_t partial = (m_address & mask);
+ return (partial >> small);
+ }
+}
+
+inline
+physical_address_t Address::maskLowOrderBits(int number) const
+{
+ physical_address_t mask;
+
+ if (number >= ADDRESS_WIDTH - 1) {
+ mask = ~0;
+ } else {
+ mask = (physical_address_t)~0 << number;
+ }
+ return (m_address & mask);
+}
+
+inline
+physical_address_t Address::maskHighOrderBits(int number) const
+{
+ physical_address_t mask;
+
+ if (number >= ADDRESS_WIDTH - 1) {
+ mask = ~0;
+ } else {
+ mask = (physical_address_t)~0 >> number;
+ }
+ return (m_address & mask);
+}
+
+inline
+physical_address_t Address::shiftLowOrderBits(int number) const
+{
+ return (m_address >> number);
+}
+
+inline
+integer_t Address::memoryModuleIndex() const
+{
+ integer_t index = bitSelect(RubyConfig::dataBlockBits()+RubyConfig::memoryBits(), ADDRESS_WIDTH);
+ assert (index >= 0);
+ if (index >= RubyConfig::memoryModuleBlocks()) {
+ cerr << " memoryBits: " << RubyConfig::memoryBits() << " memorySizeBits: " << RubyConfig::memorySizeBits()
+ << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush
+ << "error: limit exceeded. " <<
+ " dataBlockBits: " << RubyConfig::dataBlockBits() <<
+ " memoryModuleBlocks: " << RubyConfig::memoryModuleBlocks() <<
+ " index: " << index << endl;
+ }
+ assert (index < RubyConfig::memoryModuleBlocks());
+ return index;
+
+ // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS);
+ // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1);
+
+ //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS));
+
+ /*
+ Round-robin mapping of addresses, at page size granularity
+
+ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS
+ | | | |
+ \ / \ / \ / \ / 0
+ -----------------------------------------------------------------------
+ | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| |
+ | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| |
+ -----------------------------------------------------------------------
+ indexHighPortion indexLowPortion
+ <------->
+ NUMBER_OF_MEMORY_MODULE_BITS
+ */
+}
+
+inline
+void Address::print(ostream& out) const
+{
+ out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush;
+}
+
+class Address;
+namespace __gnu_cxx {
+ template <> struct hash<Address>
+ {
+ size_t operator()(const Address &s) const { return (size_t) s.getAddress(); }
+ };
+}
+namespace std {
+ template <> struct equal_to<Address>
+ {
+ bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; }
+ };
+}
+
+#endif //ADDRESS_H
+
diff --git a/src/mem/ruby/common/BigSet.cc b/src/mem/ruby/common/BigSet.cc
new file mode 100644
index 000000000..e16284f15
--- /dev/null
+++ b/src/mem/ruby/common/BigSet.cc
@@ -0,0 +1,249 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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 "Set.hh"
+#include "RubyConfig.hh"
+
+Set::Set()
+{
+ setSize(RubyConfig::numberOfProcessors());
+}
+
+Set::Set(int size)
+{
+ setSize(size);
+}
+
+void Set::add(NodeID index)
+{
+ m_bits[index] = Present;
+}
+
+void Set::addSet(const Set& set)
+{
+ assert(m_bits.size() == set.getSize());
+ for (int i=0; i<m_bits.size(); i++) {
+ if(set.isElement(i)){
+ add(i);
+ }
+ }
+}
+
+void Set::addRandom()
+{
+ int rand = random();
+ for (int i=0; i<m_bits.size(); i++) {
+ if(rand & 0x1 == 0) { // Look at the low order bit
+ add(i);
+ }
+ rand = (rand >> 1); // Shift the random number to look at the next bit
+ }
+}
+
+void Set::remove(NodeID index)
+{
+ m_bits[index] = NotPresent;
+}
+
+void Set::removeSet(const Set& set)
+{
+ assert(m_bits.size() == set.getSize());
+ for (int i=0; i<m_bits.size(); i++) {
+ if(set.isElement(i)){
+ remove(i);
+ }
+ }
+}
+
+void Set::clear()
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ m_bits[i] = NotPresent;
+ }
+}
+
+void Set::broadcast()
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ m_bits[i] = Present;
+ }
+}
+
+int Set::count() const
+{
+ int counter = 0;
+ for (int i=0; i<m_bits.size(); i++) {
+ if (m_bits[i] == Present) {
+ counter++;
+ }
+ }
+ return counter;
+}
+
+bool Set::isEqual(const Set& set) const
+{
+ assert(m_bits.size() == set.getSize());
+ for (int i=0; i<m_bits.size(); i++) {
+ if (m_bits[i] != set.isElement(i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+NodeID Set::smallestElement() const
+{
+ assert(count() > 0);
+ for (int i=0; i<m_bits.size(); i++) {
+ if (isElement(i)) {
+ return i;
+ }
+ }
+ ERROR_MSG("No smallest element of an empty set.");
+}
+
+// Returns true iff all bits are set
+bool Set::isBroadcast() const
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ if (m_bits[i] == NotPresent) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Returns true iff no bits are set
+bool Set::isEmpty() const
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ if (m_bits[i] == Present) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// returns the logical OR of "this" set and orSet
+Set Set::OR(const Set& orSet) const
+{
+ Set result;
+ assert(m_bits.size() == orSet.getSize());
+ result.setSize(m_bits.size());
+ for (int i=0; i<m_bits.size(); i++) {
+ if(m_bits[i] == Present || orSet.isElement(i)){
+ result.add(i);
+ }else{
+ result.remove(i);
+ }
+ }
+
+ return result;
+
+}
+
+// returns the logical AND of "this" set and andSet
+Set Set::AND(const Set& andSet) const
+{
+ Set result;
+ assert(m_bits.size() == andSet.getSize());
+ result.setSize(m_bits.size());
+ for (int i=0; i<m_bits.size(); i++) {
+ if(m_bits[i] == Present && andSet.isElement(i)){
+ result.add(i);
+ }else{
+ result.remove(i);
+ }
+ }
+ return result;
+}
+
+// Returns true if the intersection of the two sets is non-empty
+bool Set::intersectionIsNotEmpty(const Set& other_set) const
+{
+ assert(m_bits.size() == other_set.getSize());
+ for(int index=0; index < m_bits.size(); index++){
+ if(other_set.isElement(index) && isElement(index)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Returns true if the intersection of the two sets is non-empty
+bool Set::intersectionIsEmpty(const Set& other_set) const
+{
+ assert(m_bits.size() == other_set.getSize());
+ for(int index=0; index < m_bits.size(); index++){
+ if(other_set.isElement(index) && isElement(index)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Set::isSuperset(const Set& test) const
+{
+ assert(m_bits.size() == test.getSize());
+ for(int index=0; index < m_bits.size(); index++){
+ if(test.isElement(index) && !isElement(index)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Set::isElement(NodeID element) const
+{
+ return (m_bits[element] == Present);
+}
+
+NodeID Set::elementAt(int index) const
+{
+ if (m_bits[index] == Present) {
+ return m_bits[index] == Present;
+ } else {
+ return 0;
+ }
+}
+
+void Set::setSize(int size)
+{
+ m_bits.setSize(size);
+ clear();
+}
+
+void Set::print(ostream& out) const
+{
+ out << "[Set ";
+ for (int i=0; i<m_bits.size(); i++) {
+ out << (bool)m_bits[i] << " ";
+ }
+ out << "]";
+}
diff --git a/src/mem/ruby/common/BigSet.hh b/src/mem/ruby/common/BigSet.hh
new file mode 100644
index 000000000..4eae01681
--- /dev/null
+++ b/src/mem/ruby/common/BigSet.hh
@@ -0,0 +1,125 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+// NOTE: Never include this file directly, this should only be
+// included from Set.h
+
+#ifndef SET_H
+#define SET_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "NodeID.hh"
+#include "RubyConfig.hh"
+
+enum PresenceBit {NotPresent, Present};
+
+class Set {
+public:
+ // Constructors
+ // creates and empty set
+ Set();
+ Set (int size);
+
+ // used during the replay mechanism
+ // Set(const char *str);
+
+ // Set(const Set& obj);
+ // Set& operator=(const Set& obj);
+
+ // Destructor
+ // ~Set();
+
+ // Public Methods
+
+ void add(NodeID newElement);
+ void addSet(const Set& set);
+ void addRandom();
+ void remove(NodeID newElement);
+ void removeSet(const Set& set);
+ void clear();
+ void broadcast();
+ int count() const;
+ bool isEqual(const Set& set) const;
+
+ Set OR(const Set& orSet) const; // return the logical OR of this set and orSet
+ Set AND(const Set& andSet) const; // return the logical AND of this set and andSet
+
+ // Returns true if the intersection of the two sets is non-empty
+ bool intersectionIsNotEmpty(const Set& other_set) const;
+
+ // Returns true if the intersection of the two sets is empty
+ bool intersectionIsEmpty(const Set& other_set) const;
+
+ bool isSuperset(const Set& test) const;
+ bool isSubset(const Set& test) const { return test.isSuperset(*this); }
+ bool isElement(NodeID element) const;
+ bool isBroadcast() const;
+ bool isEmpty() const;
+
+ NodeID smallestElement() const;
+
+ // int size() const;
+ void setSize (int size);
+
+ // get element for a index
+ NodeID elementAt(int index) const;
+ int getSize() const { return m_bits.size(); }
+
+ // DEPRECATED METHODS
+ void addToSet(NodeID newElement) { add(newElement); } // Deprecated
+ void removeFromSet(NodeID newElement) { remove(newElement); } // Deprecated
+ void clearSet() { clear(); } // Deprecated
+ void setBroadcast() { broadcast(); } // Deprecated
+ bool presentInSet(NodeID element) const { return isElement(element); } // Deprecated
+
+ void print(ostream& out) const;
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ Vector<uint8> m_bits; // This is an vector of uint8 to reduce the size of the set
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Set& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Set& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //SET_H
+
diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh
new file mode 100644
index 000000000..bd51af7ba
--- /dev/null
+++ b/src/mem/ruby/common/Consumer.hh
@@ -0,0 +1,89 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: This is the virtual base class of all classes that can
+ * be the targets of wakeup events. There is only two methods,
+ * wakeup() and print() and no data members.
+ *
+ */
+
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include "Global.hh"
+#include "EventQueue.hh"
+
+class MessageBuffer;
+
+class Consumer {
+public:
+ // Constructors
+ Consumer() { m_last_scheduled_wakeup = 0; m_last_wakeup = 0; m_out_link_vec.setSize(0); }
+
+ // Destructor
+ virtual ~Consumer() { }
+
+ // Public Methods - pure virtual methods
+ void triggerWakeup() { Time time = g_eventQueue_ptr->getTime(); if (m_last_wakeup != time) { wakeup(); m_last_wakeup = time; }}
+ virtual void wakeup() = 0;
+ virtual void print(ostream& out) const = 0;
+ const Time& getLastScheduledWakeup() const { return m_last_scheduled_wakeup; }
+ void setLastScheduledWakeup(const Time& time) { m_last_scheduled_wakeup = time; }
+ Vector< Vector<MessageBuffer*> > getOutBuffers() { return m_out_link_vec; }
+
+protected:
+ Vector< Vector<MessageBuffer*> > m_out_link_vec;
+
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ Time m_last_scheduled_wakeup;
+ Time m_last_wakeup;
+};
+
+// Output operator declaration
+inline extern
+ostream& operator<<(ostream& out, const Consumer& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+inline extern
+ostream& operator<<(ostream& out, const Consumer& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //CONSUMER_H
diff --git a/src/mem/ruby/common/DataBlock.cc b/src/mem/ruby/common/DataBlock.cc
new file mode 100644
index 000000000..c4d6d7a33
--- /dev/null
+++ b/src/mem/ruby/common/DataBlock.cc
@@ -0,0 +1,91 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "DataBlock.hh"
+
+DataBlock::DataBlock()
+{
+ if (DATA_BLOCK || XACT_MEMORY) {
+ m_data.setSize(RubyConfig::dataBlockBytes());
+ }
+ clear();
+}
+
+DataBlock::~DataBlock()
+{
+
+}
+
+void DataBlock::clear()
+{
+ int size = m_data.size();
+ for (int i = 0; i < size; i++) {
+ m_data[i] = 0;
+ }
+}
+
+bool DataBlock::equal(const DataBlock& obj) const
+{
+ bool value = true;
+ int size = m_data.size();
+ for (int i = 0; i < size; i++) {
+ value = value && (m_data[i] == obj.m_data[i]);
+ }
+ return value;
+}
+
+void DataBlock::print(ostream& out) const
+{
+ int size = m_data.size();
+ for (int i = 0; i < size; i+=4) {
+ out << hex << *((uint32*)(&(m_data[i]))) << " ";
+ }
+ out << dec << "]" << flush;
+}
+
+uint8 DataBlock::getByte(int whichByte) const
+{
+ if (DATA_BLOCK || XACT_MEMORY) {
+ return m_data[whichByte];
+ } else {
+ return 0;
+ }
+}
+
+void DataBlock::setByte(int whichByte, uint8 data)
+{
+ if (DATA_BLOCK || XACT_MEMORY) {
+ m_data[whichByte] = data;
+ }
+}
+
diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh
new file mode 100644
index 000000000..aae364078
--- /dev/null
+++ b/src/mem/ruby/common/DataBlock.hh
@@ -0,0 +1,82 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DATABLOCK_H
+#define DATABLOCK_H
+
+#include "Global.hh"
+#include "RubyConfig.hh"
+#include "Vector.hh"
+
+class DataBlock {
+public:
+ // Constructors
+ DataBlock();
+
+ // Destructor
+ ~DataBlock();
+
+ // Public Methods
+ void clear();
+ uint8 getByte(int whichByte) const;
+ void setByte(int whichByte, uint8 data);
+ bool equal(const DataBlock& obj) const;
+ void print(ostream& out) const;
+
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ Vector<uint8> m_data;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const DataBlock& obj);
+
+bool operator==(const DataBlock& obj1, const DataBlock& obj2);
+
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const DataBlock& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+extern inline
+bool operator==(const DataBlock& obj1,const DataBlock& obj2)
+{
+ return (obj1.equal(obj2));
+}
+
+#endif //DATABLOCK_H
diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc
new file mode 100644
index 000000000..f0319ceb8
--- /dev/null
+++ b/src/mem/ruby/common/Debug.cc
@@ -0,0 +1,369 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ */
+
+#include <fstream>
+#include <stdarg.h>
+
+#include "Global.hh"
+#include "Debug.hh"
+#include "EventQueue.hh"
+
+class Debug;
+extern Debug* g_debug_ptr;
+std::ostream * debug_cout_ptr;
+
+// component character list
+const char DEFINE_COMP_CHAR[] =
+{
+#undef DEFINE_COMP
+#define DEFINE_COMP(component, character, description) character,
+#include "Debug.def"
+};
+
+// component description list
+const char* DEFINE_COMP_DESCRIPTION[] =
+{
+#undef DEFINE_COMP
+#define DEFINE_COMP(component, character, description) description,
+#include "Debug.def"
+};
+
+extern "C" void changeDebugVerbosity(VerbosityLevel vb);
+extern "C" void changeDebugFilter(int filter);
+
+void changeDebugVerbosity(VerbosityLevel vb)
+{
+ g_debug_ptr->setVerbosity(vb);
+}
+
+void changeDebugFilter(int filter)
+{
+ g_debug_ptr->setFilter(filter);
+}
+
+Debug::Debug( const char *filterString, const char *verboseString,
+ Time filterStartTime, const char *filename )
+{
+ m_verbosityLevel = No_Verb;
+ clearFilter();
+ debug_cout_ptr = &cout;
+
+ m_starting_cycle = filterStartTime;
+ setFilterString( filterString );
+ setVerbosityString( verboseString );
+ setDebugOutputFile( filename );
+}
+
+Debug::~Debug()
+{
+}
+
+void Debug::printVerbosity(ostream& out) const
+{
+ switch (getVerbosity()) {
+ case No_Verb:
+ out << "verbosity = No_Verb" << endl;
+ break;
+ case Low_Verb:
+ out << "verbosity = Low_Verb" << endl;
+ break;
+ case Med_Verb:
+ out << "verbosity = Med_Verb" << endl;
+ break;
+ case High_Verb:
+ out << "verbosity = High_Verb" << endl;
+ break;
+ default:
+ out << "verbosity = unknown" << endl;
+ }
+}
+
+bool Debug::validDebug(int module, PriorityLevel priority)
+{
+ int local_module = (1 << module);
+ if(m_filter & local_module) {
+ if (g_eventQueue_ptr == NULL ||
+ g_eventQueue_ptr->getTime() >= m_starting_cycle) {
+ switch(m_verbosityLevel) {
+ case No_Verb:
+ return false;
+ break;
+ case Low_Verb:
+ if(priority == HighPrio) {
+ return true;
+ }else{
+ return false;
+ }
+ break;
+ case Med_Verb:
+ if(priority == HighPrio || priority == MedPrio ) {
+ return true;
+ }else{
+ return false;
+ }
+ break;
+ case High_Verb:
+ return true;
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+void Debug::setDebugTime(Time t)
+{
+ m_starting_cycle = t;
+}
+
+void Debug::setVerbosity(VerbosityLevel vb)
+{
+ m_verbosityLevel = vb;
+}
+
+void Debug::setFilter(int filter)
+{
+ m_filter = filter;
+}
+
+bool Debug::checkVerbosityString(const char *verb_str)
+{
+ if (verb_str == NULL) {
+ cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
+ return true; // error
+ } else if ( (string(verb_str) == "none") ||
+ (string(verb_str) == "low") ||
+ (string(verb_str) == "med") ||
+ (string(verb_str) == "high") ) {
+ return false;
+ }
+ cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
+ return true; // error
+}
+
+bool Debug::setVerbosityString(const char *verb_str)
+{
+ bool check_fails = checkVerbosityString(verb_str);
+ if (check_fails) {
+ return true; // error
+ }
+ if (string(verb_str) == "none") {
+ setVerbosity(No_Verb);
+ } else if (string(verb_str) == "low") {
+ setVerbosity(Low_Verb);
+ } else if (string(verb_str) == "med") {
+ setVerbosity(Med_Verb);
+ } else if (string(verb_str) == "high") {
+ setVerbosity(High_Verb);
+ } else {
+ cerr << "Error: unrecognized verbosity (use none, low, med, high): " << verb_str << endl;
+ return true; // error
+ }
+ return false; // no error
+}
+
+bool Debug::checkFilter(char ch)
+{
+ for (int i=0; i<NUMBER_OF_COMPS; i++) {
+ // Look at all components to find a character match
+ if (DEFINE_COMP_CHAR[i] == ch) {
+ // We found a match - return no error
+ return false; // no error
+ }
+ }
+ return true; // error
+}
+
+bool Debug::checkFilterString(const char *filter_str)
+{
+ if (filter_str == NULL) {
+ cerr << "Error: unrecognized component filter: NULL" << endl;
+ return true; // error
+ }
+
+ // check for default filter ("none") before reporting RUBY_DEBUG error
+ if ( (string(filter_str) == "none") ) {
+ return false; // no error
+ }
+
+ if (RUBY_DEBUG == false) {
+ cerr << "Error: User specified set of debug components, but the RUBY_DEBUG compile-time flag is false." << endl;
+ cerr << "Solution: Re-compile with RUBY_DEBUG set to true." << endl;
+ return true; // error
+ }
+
+ if ( (string(filter_str) == "all") ) {
+ return false; // no error
+ }
+
+ // scan string checking each character
+ for (unsigned int i = 0; i < strlen(filter_str); i++) {
+ bool unrecognized = checkFilter( filter_str[i] );
+ if (unrecognized == true) {
+ return true; // error
+ }
+ }
+ return false; // no error
+}
+
+bool Debug::setFilterString(const char *filter_str)
+{
+ if (checkFilterString(filter_str)) {
+ return true; // error
+ }
+
+ if (string(filter_str) == "all" ) {
+ allFilter();
+ } else if (string(filter_str) == "none") {
+ clearFilter();
+ } else {
+ // scan string adding to bit mask for each component which is present
+ for (unsigned int i = 0; i < strlen(filter_str); i++) {
+ bool error = addFilter( filter_str[i] );
+ if (error) {
+ return true; // error
+ }
+ }
+ }
+ return false; // no error
+}
+
+bool Debug::addFilter(char ch)
+{
+ for (int i=0; i<NUMBER_OF_COMPS; i++) {
+ // Look at all components to find a character match
+ if (DEFINE_COMP_CHAR[i] == ch) {
+ // We found a match - update the filter bit mask
+ cout << " Debug: Adding to filter: '" << ch << "' (" << DEFINE_COMP_DESCRIPTION[i] << ")" << endl;
+ m_filter |= (1 << i);
+ return false; // no error
+ }
+ }
+
+ // We didn't find the character
+ cerr << "Error: unrecognized component filter: " << ch << endl;
+ usageInstructions();
+ return true; // error
+}
+
+void Debug::clearFilter()
+{
+ m_filter = 0;
+}
+
+void Debug::allFilter()
+{
+ m_filter = ~0;
+}
+
+void Debug::usageInstructions(void)
+{
+ cerr << "Debug components: " << endl;
+ for (int i=0; i<NUMBER_OF_COMPS; i++) {
+ cerr << " " << DEFINE_COMP_CHAR[i] << ": " << DEFINE_COMP_DESCRIPTION[i] << endl;
+ }
+}
+
+void Debug::print(ostream& out) const
+{
+ out << "[Debug]" << endl;
+}
+
+void Debug::setDebugOutputFile (const char * filename)
+{
+ if ( (filename == NULL) ||
+ (!strcmp(filename, "none")) ) {
+ debug_cout_ptr = &cout;
+ return;
+ }
+
+ if (m_fout.is_open() ) {
+ m_fout.close ();
+ }
+ m_fout.open (filename, std::ios::out);
+ if (! m_fout.is_open() ) {
+ cerr << "setDebugOutputFile: can't open file " << filename << endl;
+ }
+ else {
+ debug_cout_ptr = &m_fout;
+ }
+}
+
+void Debug::closeDebugOutputFile ()
+{
+ if (m_fout.is_open() ) {
+ m_fout.close ();
+ debug_cout_ptr = &cout;
+ }
+}
+
+void Debug::debugMsg( const char *fmt, ... )
+{
+ va_list args;
+
+ // you could check validDebug() here before printing the message
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+}
+
+/*
+void DEBUG_OUT( const char* fmt, ...) {
+ if (RUBY_DEBUG) {
+ cout << "Debug: in fn "
+ << __PRETTY_FUNCTION__
+ << " in " << __FILE__ << ":"
+ << __LINE__ << ": ";
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+ }
+}
+
+void ERROR_OUT( const char* fmt, ... ) {
+ if (ERROR_MESSAGE_FLAG) {
+ cout << "error: in fn "
+ << __PRETTY_FUNCTION__ << " in "
+ << __FILE__ << ":"
+ << __LINE__ << ": ";
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+ }
+ assert(0);
+}
+*/
+
diff --git a/src/mem/ruby/common/Debug.def b/src/mem/ruby/common/Debug.def
new file mode 100644
index 000000000..23af06655
--- /dev/null
+++ b/src/mem/ruby/common/Debug.def
@@ -0,0 +1,17 @@
+DEFINE_COMP(SYSTEM_COMP, 's', "System")
+DEFINE_COMP(NODE_COMP, 'N', "Node")
+DEFINE_COMP(QUEUE_COMP, 'q', "Queue")
+DEFINE_COMP(EVENTQUEUE_COMP, 'e', "Event Queue")
+DEFINE_COMP(NETWORK_COMP, 'n', "Network")
+DEFINE_COMP(SEQUENCER_COMP, 'S', "Sequencer")
+DEFINE_COMP(TESTER_COMP, 't', "Tester")
+DEFINE_COMP(GENERATED_COMP, 'g', "Generated")
+DEFINE_COMP(SLICC_COMP, 'l', "SLICC")
+DEFINE_COMP(NETWORKQUEUE_COMP, 'Q', "Network Queues")
+DEFINE_COMP(TIME_COMP, 'T', "Time")
+DEFINE_COMP(NETWORK_INTERNALS_COMP, 'i', "Network Internals")
+DEFINE_COMP(STOREBUFFER_COMP, 'b', "Store Buffer")
+DEFINE_COMP(CACHE_COMP, 'c', "Cache")
+DEFINE_COMP(PREDICTOR_COMP, 'p', "Predictor")
+DEFINE_COMP(ALLOCATOR_COMP, 'a', "Allocator")
+
diff --git a/src/mem/ruby/common/Debug.hh b/src/mem/ruby/common/Debug.hh
new file mode 100644
index 000000000..afa10f57f
--- /dev/null
+++ b/src/mem/ruby/common/Debug.hh
@@ -0,0 +1,291 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <unistd.h>
+#include <iostream>
+
+extern std::ostream * debug_cout_ptr;
+
+// component enumeration
+enum DebugComponents
+{
+#undef DEFINE_COMP
+#define DEFINE_COMP(component, character, description) component,
+#include "Debug.def"
+ NUMBER_OF_COMPS
+};
+
+enum PriorityLevel {HighPrio, MedPrio, LowPrio};
+enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb};
+
+class Debug {
+public:
+ // Constructors
+ Debug( const char *filterString, const char *verboseString,
+ Time filterStartTime, const char *filename );
+
+ // Destructor
+ ~Debug();
+
+ // Public Methods
+ bool validDebug(int module, PriorityLevel priority);
+ void printVerbosity(ostream& out) const;
+ void setVerbosity(VerbosityLevel vb);
+ static bool checkVerbosityString(const char *verb_str);
+ bool setVerbosityString(const char *);
+ VerbosityLevel getVerbosity() const { return m_verbosityLevel; }
+ void setFilter(int);
+ static bool checkFilter( char);
+ static bool checkFilterString(const char *);
+ bool setFilterString(const char *);
+ void setDebugTime(Time);
+ Time getDebugTime() const { return m_starting_cycle; }
+ bool addFilter(char);
+ void clearFilter();
+ void allFilter();
+ void print(ostream& out) const;
+ /* old school debugging "vararg": sends messages to screen and log */
+ void debugMsg( const char *fmt, ... );
+
+ void setDebugOutputFile (const char * filename);
+ void closeDebugOutputFile ();
+ static void usageInstructions(void);
+
+private:
+ // Private Methods
+
+ // Private copy constructor and assignment operator
+ Debug(const Debug& obj);
+ Debug& operator=(const Debug& obj);
+
+ // Data Members (m_ prefix)
+ VerbosityLevel m_verbosityLevel;
+ int m_filter;
+ Time m_starting_cycle;
+
+ std::fstream m_fout;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Debug& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Debug& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+const bool ERROR_MESSAGE_FLAG = true;
+const bool WARNING_MESSAGE_FLAG = true;
+
+#ifdef RUBY_NO_ASSERT
+const bool ASSERT_FLAG = false;
+#else
+const bool ASSERT_FLAG = true;
+#endif
+
+#undef assert
+#define assert(EXPR) ASSERT(EXPR)
+#undef ASSERT
+#define ASSERT(EXPR)\
+{\
+ if (ASSERT_FLAG) {\
+ if (!(EXPR)) {\
+ cerr << "failed assertion '"\
+ << #EXPR << "' at fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << endl << flush;\
+ (* debug_cout_ptr) << "failed assertion '"\
+ << #EXPR << "' at fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << endl << flush;\
+ if(isatty(STDIN_FILENO)) {\
+ cerr << "At this point you might want to attach a debug to ";\
+ cerr << "the running and get to the" << endl;\
+ cerr << "crash site; otherwise press enter to continue" << endl;\
+ cerr << "PID: " << getpid();\
+ cerr << endl << flush; \
+ char c; \
+ cin.get(c); \
+ }\
+ abort();\
+ }\
+ }\
+}
+
+#define BREAK(X)\
+{\
+ cerr << "breakpoint '"\
+ << #X << "' reached at fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << endl << flush;\
+ if(isatty(STDIN_FILENO)) {\
+ cerr << "press enter to continue" << endl;\
+ cerr << "PID: " << getpid();\
+ cerr << endl << flush; \
+ char c; \
+ cin.get(c); \
+ }\
+}
+
+#define ERROR_MSG(MESSAGE)\
+{\
+ if (ERROR_MESSAGE_FLAG) {\
+ cerr << "Fatal Error: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ (* debug_cout_ptr) << "Fatal Error: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ abort();\
+ }\
+}
+
+#define WARN_MSG(MESSAGE)\
+{\
+ if (WARNING_MESSAGE_FLAG) {\
+ cerr << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ (* debug_cout_ptr) << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ }\
+}
+
+#define WARN_EXPR(EXPR)\
+{\
+ if (WARNING_MESSAGE_FLAG) {\
+ cerr << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << #EXPR << " is "\
+ << (EXPR) << endl << flush;\
+ (* debug_cout_ptr) << "Warning: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << #EXPR << " is "\
+ << (EXPR) << endl << flush;\
+ }\
+}
+
+#define DEBUG_MSG(module, priority, MESSAGE)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(module, priority)) {\
+ (* debug_cout_ptr) << "Debug: in fn "\
+ << __PRETTY_FUNCTION__\
+ << " in " << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << (MESSAGE) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_EXPR(module, priority, EXPR)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(module, priority)) {\
+ (* debug_cout_ptr) << "Debug: in fn "\
+ << __PRETTY_FUNCTION__\
+ << " in " << __FILE__ << ":"\
+ << __LINE__ << ": "\
+ << #EXPR << " is "\
+ << (EXPR) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_NEWLINE(module, priority)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(module, priority)) {\
+ (* debug_cout_ptr) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_SLICC(priority, LINE, MESSAGE)\
+{\
+ if (RUBY_DEBUG) {\
+ if (g_debug_ptr->validDebug(SLICC_COMP, priority)) {\
+ (* debug_cout_ptr) << (LINE) << (MESSAGE) << endl << flush;\
+ }\
+ }\
+}
+
+#define DEBUG_OUT( rest... ) \
+{\
+ if (RUBY_DEBUG) {\
+ cout << "Debug: in fn "\
+ << __PRETTY_FUNCTION__\
+ << " in " << __FILE__ << ":"\
+ << __LINE__ << ": "; \
+ g_debug_ptr->debugMsg(rest); \
+ }\
+}
+
+#define ERROR_OUT( rest... ) \
+{\
+ if (ERROR_MESSAGE_FLAG) {\
+ cout << "error: in fn "\
+ << __PRETTY_FUNCTION__ << " in "\
+ << __FILE__ << ":"\
+ << __LINE__ << ": ";\
+ g_debug_ptr->debugMsg(rest); \
+ }\
+}
+
+#endif //DEBUG_H
+
diff --git a/src/mem/ruby/common/Driver.cc b/src/mem/ruby/common/Driver.cc
new file mode 100644
index 000000000..019ac6403
--- /dev/null
+++ b/src/mem/ruby/common/Driver.cc
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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 "Driver.hh"
+
+Driver::Driver()
+{
+}
+
+// still need to be defined for subclasses
+Driver::~Driver()
+{
+}
diff --git a/src/mem/ruby/common/Driver.hh b/src/mem/ruby/common/Driver.hh
new file mode 100644
index 000000000..911cb742b
--- /dev/null
+++ b/src/mem/ruby/common/Driver.hh
@@ -0,0 +1,98 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+#include "Global.hh"
+#include "Consumer.hh"
+#include "NodeID.hh"
+#include "CacheRequestType.hh"
+
+class System;
+class SubBlock;
+class Address;
+class MachineID;
+class SimicsHypervisor;
+
+class Driver {
+public:
+ // Constructors
+ Driver();
+
+ // Destructor
+ virtual ~Driver() = 0;
+
+ // Public Methods
+ virtual void get_network_config() {}
+ virtual void hitCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) = 0; // Called by sequencer
+ virtual void conflictCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) { assert(0); } // Called by sequencer
+ virtual integer_t getInstructionCount(int procID) const { return 1; }
+ virtual integer_t getCycleCount(int procID) const { return 1; }
+ virtual SimicsHypervisor * getHypervisor() { return NULL; }
+ virtual void notifySendNack( int procID, const Address & addr, uint64 remote_timestamp, const MachineID & remote_id) { assert(0); }; //Called by Sequencer
+ virtual void notifyReceiveNack( int procID, const Address & addr, uint64 remote_timestamp, const MachineID & remote_id) { assert(0); }; //Called by Sequencer
+ virtual void notifyReceiveNackFinal( int procID, const Address & addr) { assert(0); }; // Called by Sequencer
+ virtual void notifyTrapStart( int procID, const Address & handlerPC, int threadID, int smtThread ) { assert(0); } //called by Sequencer
+ virtual void notifyTrapComplete( int procID, const Address & newPC, int smtThread ) {assert(0); } // called by Sequencer
+ virtual int getOpalTransactionLevel(int procID, int thread) const {
+ cout << "Driver.hh getOpalTransactionLevel() " << endl;
+ return 0; } //called by Sequencer
+ virtual void addThreadDependency(int procID, int requestor_thread, int conflict_thread) const { assert(0);}
+ virtual uint64 getOpalTime(int procID) const{ return 0; } //called by Sequencer
+ virtual uint64 getOpalTimestamp(int procID, int thread) const{
+ cout << "Driver.hh getOpalTimestamp " << endl;
+ return 0; } // called by Sequencer
+ virtual int inTransaction(int procID, int thread ) const{
+ cout << "Driver.hh inTransaction " << endl;
+return false; } //called by Sequencer
+ virtual void printDebug(){} //called by Sequencer
+
+ virtual void printStats(ostream& out) const = 0;
+ virtual void clearStats() = 0;
+
+ virtual void printConfig(ostream& out) const = 0;
+
+ //virtual void abortCallback(NodeID proc){}
+
+ virtual integer_t readPhysicalMemory(int procID, physical_address_t address,
+ int len ){ ASSERT(0); return 0; }
+
+ virtual void writePhysicalMemory( int procID, physical_address_t address,
+ integer_t value, int len ){ ASSERT(0); }
+
+protected:
+ // accessible by subclasses
+
+private:
+ // inaccessible by subclasses
+
+};
+
+#endif //DRIVER_H
diff --git a/src/mem/ruby/common/Global.cc b/src/mem/ruby/common/Global.cc
new file mode 100644
index 000000000..e60cd4fd3
--- /dev/null
+++ b/src/mem/ruby/common/Global.cc
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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 "Global.hh"
+
+EventQueue* g_eventQueue_ptr = NULL;
+System* g_system_ptr = NULL;
+Debug* g_debug_ptr = NULL;
+
diff --git a/src/mem/ruby/common/Global.hh b/src/mem/ruby/common/Global.hh
new file mode 100644
index 000000000..eaec05d46
--- /dev/null
+++ b/src/mem/ruby/common/Global.hh
@@ -0,0 +1,110 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * */
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#ifdef SINGLE_LEVEL_CACHE
+const bool TWO_LEVEL_CACHE = false;
+#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // currently all protocols require L1s == nodes
+#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // "
+#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // "
+#define L2_CACHE_VARIABLE m_L1Cache_cacheMemory_vec
+#else
+const bool TWO_LEVEL_CACHE = true;
+#ifdef IS_CMP
+#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version]
+#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version]
+#define L2_CACHE_MEMBER_VARIABLE m_L2Cache_L2cacheMemory_vec[m_version]
+#define L2_CACHE_VARIABLE m_L2Cache_L2cacheMemory_vec
+#else // not IS_CMP
+#define L1I_CACHE_MEMBER_VARIABLE m_L1Cache_L1IcacheMemory_vec[m_version] // currently all protocols require L1s == nodes
+#define L1D_CACHE_MEMBER_VARIABLE m_L1Cache_L1DcacheMemory_vec[m_version] // "
+// #define L2_CACHE_MEMBER_VARIABLE m_L1Cache_L2cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes
+#define L2_CACHE_MEMBER_VARIABLE m_L1Cache_cacheMemory_vec[m_version] // old exclusive caches don't support L2s != nodes
+#define L2_CACHE_VARIABLE m_L1Cache_L2cacheMemory_vec
+#endif // IS_CMP
+#endif //SINGLE_LEVEL_CACHE
+
+#define DIRECTORY_MEMBER_VARIABLE m_Directory_directory_vec[m_version]
+#define TBE_TABLE_MEMBER_VARIABLE m_L1Cache_TBEs_vec[m_version]
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+typedef signed char int8;
+typedef int int32;
+typedef long long int64;
+
+typedef long long integer_t;
+typedef unsigned long long uinteger_t;
+
+typedef int64 Time;
+typedef uint64 physical_address_t;
+typedef uint64 la_t;
+typedef uint64 pa_t;
+typedef integer_t simtime_t;
+
+// external includes for all classes
+#include "std-includes.hh"
+#include "Debug.hh"
+
+// simple type declarations
+typedef Time LogicalTime;
+typedef int64 Index; // what the address bit ripper returns
+typedef int word; // one word of a cache line
+typedef unsigned int uint;
+typedef int SwitchID;
+typedef int LinkID;
+
+class EventQueue;
+extern EventQueue* g_eventQueue_ptr;
+
+class System;
+extern System* g_system_ptr;
+
+class Debug;
+extern Debug* g_debug_ptr;
+
+// FIXME: this is required by the contructor of Directory_Entry.h. It can't go
+// into slicc_util.h because it opens a can of ugly worms
+extern inline int max_tokens()
+{
+ return 1024;
+}
+
+
+#endif //GLOBAL_H
+
diff --git a/src/mem/ruby/common/Histogram.cc b/src/mem/ruby/common/Histogram.cc
new file mode 100644
index 000000000..9c5e8e623
--- /dev/null
+++ b/src/mem/ruby/common/Histogram.cc
@@ -0,0 +1,185 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ */
+
+#include "Histogram.hh"
+
+Histogram::Histogram(int binsize, int bins)
+{
+ m_binsize = binsize;
+ m_bins = bins;
+ clear();
+}
+
+Histogram::~Histogram()
+{
+}
+
+void Histogram::clear(int binsize, int bins)
+{
+ m_binsize = binsize;
+ clear(bins);
+}
+
+void Histogram::clear(int bins)
+{
+ m_bins = bins;
+ m_largest_bin = 0;
+ m_max = 0;
+ m_data.setSize(m_bins);
+ for (int i = 0; i < m_bins; i++) {
+ m_data[i] = 0;
+ }
+ m_count = 0;
+ m_max = 0;
+
+ m_sumSamples = 0;
+ m_sumSquaredSamples = 0;
+}
+
+
+void Histogram::add(int64 value)
+{
+ assert(value >= 0);
+ m_max = max(m_max, value);
+ m_count++;
+
+ m_sumSamples += value;
+ m_sumSquaredSamples += (value*value);
+
+ int index;
+ if (m_binsize == -1) {
+ // This is a log base 2 histogram
+ if (value == 0) {
+ index = 0;
+ } else {
+ index = int(log(double(value))/log(2.0))+1;
+ if (index >= m_data.size()) {
+ index = m_data.size()-1;
+ }
+ }
+ } else {
+ // This is a linear histogram
+ while (m_max >= (m_bins * m_binsize)) {
+ for (int i = 0; i < m_bins/2; i++) {
+ m_data[i] = m_data[i*2] + m_data[i*2 + 1];
+ }
+ for (int i = m_bins/2; i < m_bins; i++) {
+ m_data[i] = 0;
+ }
+ m_binsize *= 2;
+ }
+ index = value/m_binsize;
+ }
+ assert(index >= 0);
+ m_data[index]++;
+ m_largest_bin = max(m_largest_bin, index);
+}
+
+void Histogram::add(const Histogram& hist)
+{
+ assert(hist.getBins() == m_bins);
+ assert(hist.getBinSize() == -1); // assume log histogram
+ assert(m_binsize == -1);
+
+ for (int j = 0; j < hist.getData(0); j++) {
+ add(0);
+ }
+
+ for (int i = 1; i < m_bins; i++) {
+ for (int j = 0; j < hist.getData(i); j++) {
+ add(1<<(i-1)); // account for the + 1 index
+ }
+ }
+
+}
+
+// Computation of standard deviation of samples a1, a2, ... aN
+// variance = [SUM {ai^2} - (SUM {ai})^2/N]/(N-1)
+// std deviation equals square root of variance
+double Histogram::getStandardDeviation() const
+{
+ double variance;
+ if(m_count > 1){
+ variance = (double)(m_sumSquaredSamples - m_sumSamples*m_sumSamples/m_count)/(m_count - 1);
+ } else {
+ return 0;
+ }
+ return sqrt(variance);
+}
+
+void Histogram::print(ostream& out) const
+{
+ printWithMultiplier(out, 1.0);
+}
+
+void Histogram::printPercent(ostream& out) const
+{
+ if (m_count == 0) {
+ printWithMultiplier(out, 0.0);
+ } else {
+ printWithMultiplier(out, 100.0/double(m_count));
+ }
+}
+
+void Histogram::printWithMultiplier(ostream& out, double multiplier) const
+{
+ if (m_binsize == -1) {
+ out << "[binsize: log2 ";
+ } else {
+ out << "[binsize: " << m_binsize << " ";
+ }
+ out << "max: " << m_max << " ";
+ out << "count: " << m_count << " ";
+ // out << "total: " << m_sumSamples << " ";
+ if (m_count == 0) {
+ out << "average: NaN |";
+ out << "standard deviation: NaN |";
+ } else {
+ out << "average: " << setw(5) << ((double) m_sumSamples)/m_count << " | ";
+ out << "standard deviation: " << getStandardDeviation() << " |";
+ }
+ for (int i = 0; i < m_bins && i <= m_largest_bin; i++) {
+ if (multiplier == 1.0) {
+ out << " " << m_data[i];
+ } else {
+ out << " " << double(m_data[i]) * multiplier;
+ }
+ }
+ out << " ]";
+}
+
+bool node_less_then_eq(const Histogram* n1, const Histogram* n2)
+{
+ return (n1->size() > n2->size());
+}
diff --git a/src/mem/ruby/common/Histogram.hh b/src/mem/ruby/common/Histogram.hh
new file mode 100644
index 000000000..e48efc35f
--- /dev/null
+++ b/src/mem/ruby/common/Histogram.hh
@@ -0,0 +1,104 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ * Description: The histogram class implements a simple histogram
+ *
+ */
+
+#ifndef HISTOGRAM_H
+#define HISTOGRAM_H
+
+#include "Global.hh"
+#include "Vector.hh"
+
+class Histogram {
+public:
+ // Constructors
+ Histogram(int binsize = 1, int bins = 50);
+
+ // Destructor
+ ~Histogram();
+
+ // Public Methods
+
+ void add(int64 value);
+ void add(const Histogram& hist);
+ void clear() { clear(m_bins); }
+ void clear(int bins);
+ void clear(int binsize, int bins);
+ int64 size() const { return m_count; }
+ int getBins() const { return m_bins; }
+ int getBinSize() const { return m_binsize; }
+ int64 getTotal() const { return m_sumSamples; }
+ int64 getData(int index) const { return m_data[index]; }
+
+ void printWithMultiplier(ostream& out, double multiplier) const;
+ void printPercent(ostream& out) const;
+ void print(ostream& out) const;
+private:
+ // Private Methods
+
+ // Private copy constructor and assignment operator
+ // Histogram(const Histogram& obj);
+ // Histogram& operator=(const Histogram& obj);
+
+ // Data Members (m_ prefix)
+ Vector<int64> m_data;
+ int64 m_max; // the maximum value seen so far
+ int64 m_count; // the number of elements added
+ int m_binsize; // the size of each bucket
+ int m_bins; // the number of buckets
+ int m_largest_bin; // the largest bin used
+
+ int64 m_sumSamples; // the sum of all samples
+ int64 m_sumSquaredSamples; // the sum of the square of all samples
+
+ double getStandardDeviation() const;
+};
+
+bool node_less_then_eq(const Histogram* n1, const Histogram* n2);
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Histogram& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Histogram& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //HISTOGRAM_H
diff --git a/src/mem/ruby/common/Message.cc b/src/mem/ruby/common/Message.cc
new file mode 100644
index 000000000..baad8ac9b
--- /dev/null
+++ b/src/mem/ruby/common/Message.cc
@@ -0,0 +1,34 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "Message.hh"
diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc
new file mode 100644
index 000000000..79a6078e9
--- /dev/null
+++ b/src/mem/ruby/common/NetDest.cc
@@ -0,0 +1,259 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * NetDest.C
+ *
+ * Description: See NetDest.h
+ *
+ * $Id$
+ *
+ */
+
+#include "NetDest.hh"
+#include "RubyConfig.hh"
+#include "Protocol.hh"
+
+NetDest::NetDest()
+{
+ setSize();
+}
+
+void NetDest::add(MachineID newElement)
+{
+ m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
+}
+
+void NetDest::addNetDest(const NetDest& netDest)
+{
+ assert(m_bits.size() == netDest.getSize());
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].addSet(netDest.m_bits[i]);
+ }
+}
+
+void NetDest::addRandom()
+{
+ int i = random()%m_bits.size();
+ m_bits[i].addRandom();
+}
+
+void NetDest::setNetDest(MachineType machine, const Set& set)
+{
+ // assure that there is only one set of destinations for this machine
+ assert(MachineType_base_level((MachineType)(machine+1)) - MachineType_base_level(machine) == 1);
+ m_bits[MachineType_base_level(machine)] = set;
+}
+
+void NetDest::remove(MachineID oldElement)
+{
+ m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
+}
+
+void NetDest::removeNetDest(const NetDest& netDest)
+{
+ assert(m_bits.size() == netDest.getSize());
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].removeSet(netDest.m_bits[i]);
+
+ }
+}
+
+void NetDest::clear()
+{
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].clear();
+ }
+}
+
+void NetDest::broadcast()
+{
+ for (MachineType machine = MachineType_FIRST; machine < MachineType_NUM; ++machine) {
+ broadcast(machine);
+ }
+}
+
+void NetDest::broadcast(MachineType machineType) {
+
+ for (int i = 0; i < MachineType_base_count(machineType); i++) {
+ MachineID mach = {machineType, i};
+ add(mach);
+ }
+}
+
+//For Princeton Network
+Vector<NodeID> NetDest::getAllDest() {
+ Vector<NodeID> dest;
+ dest.clear();
+ for (int i=0; i<m_bits.size(); i++) {
+ for (int j=0; j<m_bits[i].getSize(); j++) {
+ if (m_bits[i].isElement(j)) {
+ dest.insertAtBottom((NodeID) (MachineType_base_number((MachineType) i) + j));
+ }
+ }
+ }
+ return dest;
+}
+
+int NetDest::count() const
+{
+ int counter = 0;
+ for (int i=0; i<m_bits.size(); i++) {
+ counter += m_bits[i].count();
+ }
+ return counter;
+}
+
+NodeID NetDest::elementAt(MachineID index) {
+ return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
+}
+
+NodeID NetDest::smallestElement() const
+{
+ assert(count() > 0);
+ for (int i=0; i<m_bits.size(); i++) {
+ for (int j=0; j<m_bits[i].getSize(); j++) {
+ if (m_bits[i].isElement(j)) {
+ return j;
+ }
+ }
+ }
+ ERROR_MSG("No smallest element of an empty set.");
+}
+
+MachineID NetDest::smallestElement(MachineType machine) const
+{
+ for (int j = 0; j < m_bits[MachineType_base_level(machine)].getSize(); j++) {
+ if (m_bits[MachineType_base_level(machine)].isElement(j)) {
+ MachineID mach = {machine, j};
+ return mach;
+ }
+ }
+
+ ERROR_MSG("No smallest element of given MachineType.");
+}
+
+
+// Returns true iff all bits are set
+bool NetDest::isBroadcast() const
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ if (!m_bits[i].isBroadcast()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Returns true iff no bits are set
+bool NetDest::isEmpty() const
+{
+ for (int i=0; i<m_bits.size(); i++) {
+ if (!m_bits[i].isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// returns the logical OR of "this" set and orNetDest
+NetDest NetDest::OR(const NetDest& orNetDest) const
+{
+ assert(m_bits.size() == orNetDest.getSize());
+ NetDest result;
+ for (int i=0; i<m_bits.size(); i++) {
+ result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
+ }
+ return result;
+}
+
+
+// returns the logical AND of "this" set and andNetDest
+NetDest NetDest::AND(const NetDest& andNetDest) const
+{
+ assert(m_bits.size() == andNetDest.getSize());
+ NetDest result;
+ for (int i=0; i<m_bits.size(); i++) {
+ result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
+ }
+ return result;
+}
+
+// Returns true if the intersection of the two sets is non-empty
+bool NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
+{
+ assert(m_bits.size() == other_netDest.getSize());
+ for (int i=0; i<m_bits.size(); i++) {
+ if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool NetDest::isSuperset(const NetDest& test) const
+{
+ assert(m_bits.size() == test.getSize());
+
+ for (int i=0; i<m_bits.size(); i++) {
+ if (!m_bits[i].isSuperset(test.m_bits[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool NetDest::isElement(MachineID element) const
+{
+ return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
+}
+
+void NetDest::setSize()
+{
+ m_bits.setSize(MachineType_base_level(MachineType_NUM));
+ assert(m_bits.size() == MachineType_NUM);
+
+ for (int i = 0; i < m_bits.size(); i++) {
+ m_bits[i].setSize(MachineType_base_count((MachineType)i));
+ }
+}
+
+void NetDest::print(ostream& out) const
+{
+ out << "[NetDest (" << m_bits.size() << ") ";
+
+ for (int i=0; i<m_bits.size(); i++) {
+ for (int j=0; j<m_bits[i].getSize(); j++) {
+ out << (bool) m_bits[i].isElement(j) << " ";
+ }
+ out << " - ";
+ }
+ out << "]";
+}
+
diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh
new file mode 100644
index 000000000..04f7871f6
--- /dev/null
+++ b/src/mem/ruby/common/NetDest.hh
@@ -0,0 +1,145 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ */
+
+// NetDest specifies the network destination of a NetworkMessage
+// This is backward compatible with the Set class that was previously
+// used to specify network destinations.
+// NetDest supports both node networks and component networks
+
+#ifndef NETDEST_H
+#define NETDEST_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "NodeID.hh"
+#include "MachineID.hh"
+#include "RubyConfig.hh"
+#include "Set.hh"
+#include "MachineType.hh"
+
+class Set;
+
+class NetDest {
+public:
+ // Constructors
+ // creates and empty set
+ NetDest();
+ explicit NetDest(int bit_size);
+
+ NetDest& operator=(const Set& obj);
+
+ // Destructor
+ // ~NetDest();
+
+ // Public Methods
+ void add(MachineID newElement);
+ void addNetDest(const NetDest& netDest);
+ void addRandom();
+ void setNetDest(MachineType machine, const Set& set);
+ void remove(MachineID oldElement);
+ void removeNetDest(const NetDest& netDest);
+ void clear();
+ void broadcast();
+ void broadcast(MachineType machine);
+ int count() const;
+ bool isEqual(const NetDest& netDest);
+
+ NetDest OR(const NetDest& orNetDest) const; // return the logical OR of this netDest and orNetDest
+ NetDest AND(const NetDest& andNetDest) const; // return the logical AND of this netDest and andNetDest
+
+ // Returns true if the intersection of the two netDests is non-empty
+ bool intersectionIsNotEmpty(const NetDest& other_netDest) const;
+
+ // Returns true if the intersection of the two netDests is empty
+ bool intersectionIsEmpty(const NetDest& other_netDest) const;
+
+ bool isSuperset(const NetDest& test) const;
+ bool isSubset(const NetDest& test) const { return test.isSuperset(*this); }
+ bool isElement(MachineID element) const;
+ bool isBroadcast() const;
+ bool isEmpty() const;
+
+ //For Princeton Network
+ Vector<NodeID> getAllDest();
+
+ NodeID smallestElement() const;
+ MachineID smallestElement(MachineType machine) const;
+
+ void setSize();
+ int getSize() const { return m_bits.size(); }
+
+ // get element for a index
+ NodeID elementAt(MachineID index);
+
+ void print(ostream& out) const;
+
+private:
+
+ // Private Methods
+ // returns a value >= MachineType_base_level("this machine") and < MachineType_base_level("next highest machine")
+ int vecIndex(MachineID m) const {
+ int vec_index = MachineType_base_level(m.type);
+ assert(vec_index < m_bits.size());
+ return vec_index;
+ }
+
+ NodeID bitIndex(NodeID index) const {
+ return index;
+ }
+
+ // Data Members (m_ prefix)
+ Vector < Set > m_bits; // a Vector of bit vectors - i.e. Sets
+
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const NetDest& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const NetDest& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //NETDEST_H
+
diff --git a/src/mem/ruby/common/OptBigSet.cc b/src/mem/ruby/common/OptBigSet.cc
new file mode 100644
index 000000000..51214e936
--- /dev/null
+++ b/src/mem/ruby/common/OptBigSet.cc
@@ -0,0 +1,576 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.C
+ *
+ * Description: See Set.h
+ *
+ * $Id: BigSet.C 1.9 05/01/19 13:12:25-06:00 mikem@maya.cs.wisc.edu $
+ *
+ */
+
+// modified (rewritten) 05/20/05 by Dan Gibson to accomimdate FASTER >32 bit
+// set sizes
+
+#include "Set.hh"
+#include "RubyConfig.hh"
+
+#if __amd64__ || __LP64__
+#define __64BITS__
+#else
+#define __32BITS__
+#endif
+
+Set::Set()
+{
+ m_p_nArray = NULL;
+ setSize(RubyConfig::numberOfProcessors());
+}
+
+// copy constructor
+Set::Set(const Set& obj) {
+ m_p_nArray = NULL;
+ setSize(obj.m_nSize);
+
+ // copy from the host to this array
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] = obj.m_p_nArray[i];
+ }
+
+}
+
+Set::Set(int size)
+{
+ m_p_nArray = NULL;
+ assert(size>0);
+ setSize(size);
+}
+
+Set::~Set() {
+ if( (m_p_nArray != (&m_p_nArray_Static[0])) && (m_p_nArray != NULL))
+ delete [] m_p_nArray;
+ m_p_nArray = NULL;
+}
+
+
+// /*
+// * This function should set the bit corresponding to index
+// * to 1.
+// */
+
+// void Set::add(NodeID index)
+// {
+// assert(index<m_nSize && index >= 0);
+
+// #ifdef __32BITS__
+// m_p_nArray[index>>5] |= (1 << (index & 0x01F));
+// #else
+// m_p_nArray[index>>6] |= (((unsigned long) 1) << (index & 0x03F));
+// #endif // __32BITS__
+
+// }
+
+/*
+ * This function should set all the bits in the current set
+ * that are already set in the parameter set
+ */
+void Set::addSet(const Set& set)
+{
+ assert(getSize()==set.getSize());
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] |= set.m_p_nArray[i];
+ }
+
+}
+
+/*
+ * This function should randomly assign 1 to the bits in the set--
+ * it should not clear the bits bits first, though?
+ */
+void Set::addRandom()
+{
+
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] |= random() ^ (random() << 4); // this ensures that all 32 bits are subject to random effects,
+ // as RAND_MAX typically = 0x7FFFFFFF
+ }
+
+ // now just ensure that no bits over the maximum size were set
+#ifdef __32BITS__
+ long mask = 0x7FFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 32, so the uppermost 32 - m_nSize%32 bits should be
+ // cleared
+
+ if((m_nSize % 32) != 0) {
+ for(int j=0; j<32-(m_nSize&0x01F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#else
+ long mask = 0x7FFFFFFFFFFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 64, so the uppermost 64 - m_nSize%64 bits should be
+ // cleared
+
+ if((m_nSize % 64) != 0) {
+ for(int j=0; j<64-(m_nSize&0x03F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#endif // __32BITS__
+
+}
+
+// /*
+// * This function unsets the bit associated with index
+// */
+// void Set::remove(NodeID index)
+// {
+// assert(index<m_nSize && index>=0);
+
+// #ifdef __32BITS__
+// m_p_nArray[index>>5] &= ~(0x00000001 << (index & 0x01F));
+// #else
+// m_p_nArray[index>>6] &= ~(((unsigned long) 0x0000000000000001) << (index & 0x03F));
+// #endif // __32BITS__
+
+// }
+
+
+/*
+ * This function clears bits that are =1 in the parameter set
+ */
+void Set::removeSet(const Set& set)
+{
+
+ assert(m_nSize==set.m_nSize);
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] &= ~(set.m_p_nArray[i]);
+ }
+
+}
+
+// /*
+// * This function clears all bits in the set
+// */
+// void Set::clear()
+// {
+// for(int i=0; i<m_nArrayLen; i++) {
+// m_p_nArray[i] = 0;
+// }
+// }
+
+/*
+ * this function sets all bits in the set
+ */
+void Set::broadcast()
+{
+
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] = -1; // note that -1 corresponds to all 1's in 2's comp.
+ }
+
+ // now just ensure that no bits over the maximum size were set
+#ifdef __32BITS__
+ long mask = 0x7FFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 32, so the uppermost 32 - m_nSize%32 bits should be
+ // cleared
+
+ if((m_nSize % 32) != 0) {
+ for(int j=0; j<32-(m_nSize&0x01F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#else
+ long mask = 0x7FFFFFFFFFFFFFFF;
+
+ // the number of populated spaces in the higest-order array slot is:
+ // m_nSize % 64, so the uppermost 64 - m_nSize%64 bits should be
+ // cleared
+
+ if((m_nSize % 64) != 0) {
+ for(int j=0; j<64-(m_nSize&0x03F); j++) {
+ m_p_nArray[m_nArrayLen-1] &= mask;
+ mask = mask >> 1;
+ }
+ }
+#endif // __32BITS__
+
+}
+
+/*
+ * This function returns the population count of 1's in the set
+ */
+int Set::count() const
+{
+ int counter = 0;
+ long mask;
+ for( int i=0; i<m_nArrayLen; i++) {
+ mask = (long) 0x01;
+
+#ifdef __32BITS__
+ for( int j=0; j<32; j++) {
+ if(m_p_nArray[i] & mask) counter++;
+ mask = mask << 1;
+ }
+
+#else
+
+ for( int j=0; j<64; j++) { // FIXME - significant performance loss when array population << 64
+ if((m_p_nArray[i] & mask) != 0) {
+ counter++;
+ }
+ mask = mask << 1;
+ }
+
+#endif // __32BITS__
+
+ }
+
+ return counter;
+}
+
+/*
+ * This function checks for set equality
+ */
+
+bool Set::isEqual(const Set& set) const
+{
+ assert(m_nSize==set.m_nSize);
+
+ for(int i=0;i<m_nArrayLen;i++) {
+ if(m_p_nArray[i] != set.m_p_nArray[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
+ * This function returns the NodeID (int) of the
+ * least set bit
+ */
+NodeID Set::smallestElement() const
+{
+ assert(count() > 0);
+ long x;
+ for( int i=0; i<m_nArrayLen; i++) {
+ if(m_p_nArray[i]!=0) {
+ // the least-set bit must be in here
+ x = m_p_nArray[i];
+
+#ifdef __32BITS__
+ for( int j=0; j<32; j++) {
+ if(x & 0x00000001) {
+ return 32*i+j;
+ }
+
+ x = x >> 1;
+ }
+#else
+ for( int j=0; j<64; j++) {
+ if(x & 0x0000000000000001) {
+ return 64*i+j;
+ }
+
+ x = x >> 1;
+ }
+#endif // __32BITS__
+
+ ERROR_MSG("No smallest element of an empty set.");
+ }
+ }
+
+ ERROR_MSG("No smallest element of an empty set.");
+
+ return 0;
+}
+
+/*
+ * this function returns true iff all bits are set
+ */
+bool Set::isBroadcast() const
+{
+ // check the fully-loaded words by equal to 0xffffffff
+ // only the last word may not be fully loaded, it is not
+ // fully loaded iff m_nSize % 32 or 64 !=0 => fully loaded iff
+ // m_nSize % 32 or 64 == 0
+
+#ifdef __32BITS__
+ for(int i=0; i< (((m_nSize % 32)==0) ? m_nArrayLen : m_nArrayLen-1); i++) {
+ if(m_p_nArray[i]!=-1) {
+ return false;
+ }
+ }
+
+ // now check the last word, which may not be fully loaded
+ long mask = 1;
+ for(int j=0; j< (m_nSize % 32); j++) {
+ if((mask & m_p_nArray[m_nArrayLen-1])==0) {
+ return false;
+ }
+ mask = mask << 1;
+ }
+#else
+ for(int i=0; i< (((m_nSize % 64)==0) ? m_nArrayLen : m_nArrayLen-1); i++) {
+ if(m_p_nArray[i]!=-1) {
+ return false;
+ }
+ }
+
+ // now check the last word, which may not be fully loaded
+ long mask = 1;
+ for(int j=0; j< (m_nSize % 64); j++) {
+ if((mask & m_p_nArray[m_nArrayLen-1])==0) {
+ return false;
+ }
+ mask = mask << 1;
+ }
+
+#endif // __32BITS__
+
+ return true;
+}
+
+/*
+ * this function returns true iff no bits are set
+ */
+bool Set::isEmpty() const
+{
+
+ // here we can simply check if all = 0, since we ensure
+ // that "extra slots" are all zero
+ for(int i=0; i< m_nArrayLen ; i++) {
+ if(m_p_nArray[i]!=0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// returns the logical OR of "this" set and orSet
+Set Set::OR(const Set& orSet) const
+{
+ Set result(m_nSize);
+ assert(m_nSize == orSet.m_nSize);
+ for(int i=0; i< m_nArrayLen; i++) {
+ result.m_p_nArray[i] = m_p_nArray[i] | orSet.m_p_nArray[i];
+ }
+
+ return result;
+
+}
+
+// returns the logical AND of "this" set and andSet
+Set Set::AND(const Set& andSet) const
+{
+ Set result(m_nSize);
+ assert(m_nSize == andSet.m_nSize);
+
+ for(int i=0; i< m_nArrayLen; i++) {
+ result.m_p_nArray[i] = m_p_nArray[i] & andSet.m_p_nArray[i];
+ }
+
+ return result;
+}
+
+// // Returns true if the intersection of the two sets is non-empty
+// bool Set::intersectionIsNotEmpty(const Set& other_set) const
+// {
+// assert(m_nSize == other_set.m_nSize);
+// for(int i=0; i< m_nArrayLen; i++) {
+// if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+// return true;
+// }
+// }
+
+// return false;
+
+// }
+
+// // Returns true if the intersection of the two sets is empty
+// bool Set::intersectionIsEmpty(const Set& other_set) const
+// {
+// assert(m_nSize == other_set.m_nSize);
+// for(int i=0; i< m_nArrayLen; i++) {
+// if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+// return false;
+// }
+// }
+
+// return true;
+
+// }
+
+/*
+ * Returns false if a bit is set in the parameter set that is
+ * NOT set in this set
+ */
+bool Set::isSuperset(const Set& test) const
+{
+ assert(m_nSize == test.m_nSize);
+
+ for(int i=0;i<m_nArrayLen;i++) {
+ if(((test.m_p_nArray[i] & m_p_nArray[i]) | ~test.m_p_nArray[i]) != -1) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// /*
+// * Returns true iff this bit is set
+// */
+// bool Set::isElement(NodeID element) const
+// {
+// bool result;
+
+// #ifdef __32BITS__
+// result = ((m_p_nArray[element>>5] & (0x00000001 << (element & 0x01F)))!=0);
+// #else
+// result = ((m_p_nArray[element>>6] & (((unsigned long) 0x0000000000000001) << (element & 0x03F)))!=0);
+// #endif // __32BITS__
+
+// return result;
+// }
+
+/*
+ * "Supposed" to return the node id of the (n+1)th set
+ * bit, IE n=0 => returns nodeid of first set bit, BUT
+ * since BigSet.C behaves strangely, this implementation
+ * will behave strangely just for reverse compatability.
+ *
+ * Was originally implemented for the flight data recorder
+ * FDR
+ */
+
+// NodeID Set::elementAt(int n) const
+// {
+// if(isElement(n)) return (NodeID) true;
+// else return 0;
+
+// /*
+// int match = -1;
+// for(int i=0;i<m_nSize;i++) {
+// if(isElement(i)) match++;
+// if(match==n) {
+// return i;
+// }
+// }
+
+// return -1;
+// */
+// }
+
+void Set::setSize(int size)
+{
+ m_nSize = size;
+
+#ifdef __32BITS__
+ m_nArrayLen = m_nSize/32 + ((m_nSize%32==0) ? 0 : 1 );
+#else
+ m_nArrayLen = m_nSize/64 + ((m_nSize%64==0) ? 0 : 1 );
+#endif // __32BITS__
+
+ // decide whether to use dynamic or static alloction
+ if(m_nArrayLen<=NUMBER_WORDS_PER_SET) { // constant defined in RubyConfig.h
+ // its OK to use the static allocation, and it will
+ // probably be faster (as m_nArrayLen is already in the
+ // cache and they will probably share the same cache line)
+
+ // if switching from dyanamic to static allocation (which
+ // is probably rare, but why not be complete?), must delete
+ // the dynamically allocated space
+ if((m_p_nArray != NULL) && (m_p_nArray != &m_p_nArray_Static[0]))
+ delete [] m_p_nArray;
+
+ m_p_nArray = & m_p_nArray_Static[0];
+ } else {
+
+ // can't use static allocation...simply not enough room
+ // so dynamically allocate some space
+ if((m_p_nArray != NULL) && (m_p_nArray != &m_p_nArray_Static[0]))
+ delete [] m_p_nArray;
+
+ m_p_nArray = new long[m_nArrayLen];
+ }
+
+ clear();
+}
+
+Set& Set::operator=(const Set& obj) {
+ if(this == &obj) {
+ // do nothing
+ } else {
+
+ // resize this item
+ setSize(obj.getSize());
+
+ // copy the elements from obj to this
+ for(int i=0; i<m_nArrayLen; i++) {
+ m_p_nArray[i] = obj.m_p_nArray[i];
+ }
+ }
+
+ return *this;
+}
+
+void Set::print(ostream& out) const
+{
+ if(m_p_nArray==NULL) {
+ out << "[Set {Empty}]";
+ return;
+ }
+ char buff[24];
+ out << "[Set 0x ";
+ for (int i=m_nArrayLen-1; i>=0; i--) {
+#ifdef __32BITS__
+ sprintf(buff,"%08X ",m_p_nArray[i]);
+#else
+ sprintf(buff,"0x %016llX ",m_p_nArray[i]);
+#endif // __32BITS__
+ out << buff;
+ }
+ out << " ]";
+
+}
+
+
diff --git a/src/mem/ruby/common/OptBigSet.hh b/src/mem/ruby/common/OptBigSet.hh
new file mode 100644
index 000000000..a57a07e13
--- /dev/null
+++ b/src/mem/ruby/common/OptBigSet.hh
@@ -0,0 +1,202 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.h
+ *
+ * Description:
+ *
+ * $Id: BigSet.h 1.6 05/01/19 13:12:25-06:00 mikem@maya.cs.wisc.edu $
+ *
+ */
+
+// modified by Dan Gibson on 05/20/05 to accomidate FASTER
+// >32 set lengths, using an array of ints w/ 32 bits/int
+
+// NOTE: Never include this file directly, this should only be
+// included from Set.h
+
+#ifndef SET_H
+#define SET_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "NodeID.hh"
+#include "RubyConfig.hh"
+
+// gibson 05/20/05
+// enum PresenceBit {NotPresent, Present};
+
+class Set {
+public:
+ // Constructors
+ // creates and empty set
+ Set();
+ Set (int size);
+
+ // used during the replay mechanism
+ // Set(const char *str);
+
+ Set(const Set& obj);
+ Set& operator=(const Set& obj);
+
+ // Destructor
+ ~Set();
+
+ // Public Methods
+
+ inline void add(NodeID index)
+ {
+#ifdef __32BITS__
+ m_p_nArray[index>>5] |= (1 << (index & 0x01F));
+#else
+ m_p_nArray[index>>6] |= (((unsigned long) 1) << (index & 0x03F));
+#endif // __32BITS__
+ }
+
+ void addSet(const Set& set);
+ void addRandom();
+
+ inline void remove(NodeID index)
+ {
+#ifdef __32BITS__
+ m_p_nArray[index>>5] &= ~(0x00000001 << (index & 0x01F));
+#else
+ m_p_nArray[index>>6] &= ~(((unsigned long) 0x0000000000000001) << (index & 0x03F));
+#endif // __32BITS__
+ }
+
+
+ void removeSet(const Set& set);
+
+ inline void clear() { for(int i=0; i<m_nArrayLen; i++) m_p_nArray[i] = 0; }
+
+ void broadcast();
+ int count() const;
+ bool isEqual(const Set& set) const;
+
+ Set OR(const Set& orSet) const; // return the logical OR of this set and orSet
+ Set AND(const Set& andSet) const; // return the logical AND of this set and andSet
+
+ // Returns true if the intersection of the two sets is non-empty
+ inline bool intersectionIsNotEmpty(const Set& other_set) const
+ {
+ for(int i=0; i< m_nArrayLen; i++) {
+ if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Returns true if the intersection of the two sets is empty
+ inline bool intersectionIsEmpty(const Set& other_set) const
+ {
+ for(int i=0; i< m_nArrayLen; i++) {
+ if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool isSuperset(const Set& test) const;
+ bool isSubset(const Set& test) const { return test.isSuperset(*this); }
+
+ inline bool isElement(NodeID element) const
+ {
+#ifdef __32BITS__
+ return ((m_p_nArray[element>>5] & (0x00000001 << (element & 0x01F)))!=0);
+#else
+ return ((m_p_nArray[element>>6] & (((unsigned long) 0x0000000000000001) << (element & 0x03F)))!=0);
+#endif // __32BITS__
+
+ }
+
+ bool isBroadcast() const;
+ bool isEmpty() const;
+
+ NodeID smallestElement() const;
+
+ // int size() const;
+ void setSize (int size);
+
+ // get element for a index
+ inline NodeID elementAt(int index) const
+ {
+ if(isElement(index)) return (NodeID) true;
+ else return 0;
+ }
+
+ // gibson 05/20/05
+ int getSize() const { return m_nSize; }
+
+ // DEPRECATED METHODS
+ void addToSet(NodeID newElement) { add(newElement); } // Deprecated
+ void removeFromSet(NodeID newElement) { remove(newElement); } // Deprecated
+ void clearSet() { clear(); } // Deprecated
+ void setBroadcast() { broadcast(); } // Deprecated
+ bool presentInSet(NodeID element) const { return isElement(element); } // Deprecated
+
+ void print(ostream& out) const;
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ // gibson 05/20/05
+ // Vector<uint8> m_bits; // This is an vector of uint8 to reduce the size of the set
+
+ int m_nSize; // the number of bits in this set
+ int m_nArrayLen; // the number of 32-bit words that are held in the array
+
+ // Changed 5/24/05 for static allocation of array
+ // note that "long" corresponds to 32 bits on a 32-bit machine,
+ // 64 bits if the -m64 parameter is passed to g++, which it is
+ // for an AMD opteron under our configuration
+
+ long * m_p_nArray; // an word array to hold the bits in the set
+ long m_p_nArray_Static[NUMBER_WORDS_PER_SET];
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Set& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Set& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //SET_H
+
diff --git a/src/mem/ruby/common/Set.cc b/src/mem/ruby/common/Set.cc
new file mode 100644
index 000000000..1f5b49f90
--- /dev/null
+++ b/src/mem/ruby/common/Set.cc
@@ -0,0 +1,231 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.C
+ *
+ * Description: See Set.h
+ *
+ * $Id$
+ *
+ */
+
+#include "Set.hh"
+#include "RubyConfig.hh"
+
+#ifdef OPTBIGSET
+#include "OptBigSet.cc"
+#else
+
+#ifdef BIGSET
+#include "BigSet.cc" // code to supports sets larger than 32
+#else
+
+Set::Set()
+{
+ setSize(RubyConfig::numberOfChips());
+}
+
+Set::Set(int size)
+{
+ setSize(size);
+}
+
+bool Set::isEqual(const Set& set)
+{
+ return (m_bits == set.m_bits);
+}
+
+void Set::add(NodeID index)
+{
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+ assert(index < m_size);
+ m_bits |= (1 << index);
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+}
+
+void Set::addSet(const Set& set)
+{
+ assert(m_size == set.m_size);
+ m_bits |= set.m_bits;
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+}
+
+void Set::addRandom()
+{
+ m_bits |= random();
+ m_bits &= m_mask;
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+}
+
+void Set::remove(NodeID index)
+{
+ assert(index < m_size);
+ m_bits &= ~(1 << index);
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+}
+
+void Set::removeSet(const Set& set)
+{
+ assert(m_size == set.m_size);
+ m_bits &= ~(set.m_bits);
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+}
+
+void Set::clear()
+{
+ m_bits = 0;
+}
+
+void Set::broadcast()
+{
+ m_bits = m_mask;
+}
+
+int Set::count() const
+{
+ int counter = 0;
+ for (int i=0; i<m_size; i++) {
+ if ((m_bits & (1 << i)) != 0) {
+ counter++;
+ }
+ }
+ return counter;
+}
+
+NodeID Set::elementAt(int index) {
+ // count from right to left, index starts from 0
+ for (int i=0; i<m_size; i++) {
+ if ((m_bits & (1 << i)) != 0) {
+ if (index == 0) return i;
+ index --;
+ }
+ }
+ assert(0); // index out of range
+ return 0;
+}
+
+NodeID Set::smallestElement() const
+{
+ assert(count() > 0);
+ int counter = 0;
+ for (int i=0; i<m_size; i++) {
+ if (isElement(i)) {
+ return i;
+ }
+ }
+ ERROR_MSG("No smallest element of an empty set.");
+}
+
+// Returns true iff all bits are set
+bool Set::isBroadcast() const
+{
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+ return (m_mask == m_bits);
+}
+
+// Returns true iff no bits are set
+bool Set::isEmpty() const
+{
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+ return (m_bits == 0);
+}
+
+// returns the logical OR of "this" set and orSet
+Set Set::OR(const Set& orSet) const
+{
+ assert(m_size == orSet.m_size);
+ Set result(m_size);
+ result.m_bits = (m_bits | orSet.m_bits);
+ assert((result.m_bits & result.m_mask) == result.m_bits); // check for any bits outside the range
+ return result;
+}
+
+// returns the logical AND of "this" set and andSet
+Set Set::AND(const Set& andSet) const
+{
+ assert(m_size == andSet.m_size);
+ Set result(m_size);
+ result.m_bits = (m_bits & andSet.m_bits);
+ assert((result.m_bits & result.m_mask) == result.m_bits); // check for any bits outside the range
+ return result;
+}
+
+// Returns true if the intersection of the two sets is non-empty
+bool Set::intersectionIsNotEmpty(const Set& other_set) const
+{
+ assert(m_size == other_set.m_size);
+ return ((m_bits & other_set.m_bits) != 0);
+}
+
+// Returns true if the intersection of the two sets is empty
+bool Set::intersectionIsEmpty(const Set& other_set) const
+{
+ assert(m_size == other_set.m_size);
+ return ((m_bits & other_set.m_bits) == 0);
+}
+
+bool Set::isSuperset(const Set& test) const
+{
+ assert(m_size == test.m_size);
+ uint32 temp = (test.m_bits & (~m_bits));
+ return (temp == 0);
+}
+
+bool Set::isElement(NodeID element) const
+{
+ return ((m_bits & (1 << element)) != 0);
+}
+
+void Set::setSize(int size)
+{
+ // We're using 32 bit ints, and the 32nd bit acts strangely due to
+ // signed/unsigned, so restrict the set size to 31 bits.
+ assert(size < 32);
+ m_size = size;
+ m_bits = 0;
+ m_mask = ~((~0) << m_size);
+ assert(m_mask != 0);
+ assert((m_bits & m_mask) == m_bits); // check for any bits outside the range
+}
+
+void Set::print(ostream& out) const
+{
+ out << "[Set (" << m_size << ") ";
+
+ for (int i=0; i<m_size; i++) {
+ out << (bool) isElement(i) << " ";
+ }
+ out << "]";
+}
+
+#endif // BIGSET
+
+#endif // OPTBIGSET
+
diff --git a/src/mem/ruby/common/Set.hh b/src/mem/ruby/common/Set.hh
new file mode 100644
index 000000000..7c33c840d
--- /dev/null
+++ b/src/mem/ruby/common/Set.hh
@@ -0,0 +1,149 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * Set.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ */
+
+// Define this to use the BigSet class which is slower, but supports
+// sets of size larger than 32.
+
+// #define BIGSET
+
+#define OPTBIGSET
+
+#ifdef OPTBIGSET
+#include "OptBigSet.hh"
+#else
+
+#ifdef BIGSET
+#include "BigSet.hh" // code to supports sets larger than 32
+#else
+
+#ifndef SET_H
+#define SET_H
+
+#include "Global.hh"
+#include "Vector.hh"
+#include "NodeID.hh"
+#include "RubyConfig.hh"
+
+class Set {
+public:
+ // Constructors
+ // creates and empty set
+ Set();
+ Set(int size);
+
+ // used during the replay mechanism
+ // Set(const char *str);
+
+ // Set(const Set& obj);
+ // Set& operator=(const Set& obj);
+
+ // Destructor
+ // ~Set();
+
+ // Public Methods
+
+ void add(NodeID newElement);
+ void addSet(const Set& set);
+ void addRandom();
+ void remove(NodeID newElement);
+ void removeSet(const Set& set);
+ void clear();
+ void broadcast();
+ int count() const;
+ bool isEqual(const Set& set);
+
+ Set OR(const Set& orSet) const; // return the logical OR of this set and orSet
+ Set AND(const Set& andSet) const; // return the logical AND of this set and andSet
+
+ // Returns true if the intersection of the two sets is non-empty
+ bool intersectionIsNotEmpty(const Set& other_set) const;
+
+ // Returns true if the intersection of the two sets is empty
+ bool intersectionIsEmpty(const Set& other_set) const;
+
+ bool isSuperset(const Set& test) const;
+ bool isSubset(const Set& test) const { return test.isSuperset(*this); }
+ bool isElement(NodeID element) const;
+ bool isBroadcast() const;
+ bool isEmpty() const;
+
+ NodeID smallestElement() const;
+
+ // int size() const;
+ void setSize (int size);
+
+ // get element for a index
+ NodeID elementAt(int index);
+ int getSize() const { return m_size; }
+
+ // DEPRECATED METHODS
+ void addToSet(NodeID newElement) { add(newElement); } // Deprecated
+ void removeFromSet(NodeID newElement) { remove(newElement); } // Deprecated
+ void clearSet() { clear(); } // Deprecated
+ void setBroadcast() { broadcast(); } // Deprecated
+ bool presentInSet(NodeID element) const { return isElement(element); } // Deprecated
+
+ void print(ostream& out) const;
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ int m_size;
+ uint32 m_bits; // Set as a bit vector
+ uint32 m_mask; // a 000001111 mask where the number of 1s is equal to m_size
+
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const Set& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const Set& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //SET_H
+#endif //BIGSET
+#endif //OPTBIGSET
+
diff --git a/src/mem/ruby/common/SubBlock.cc b/src/mem/ruby/common/SubBlock.cc
new file mode 100644
index 000000000..f79e33d9c
--- /dev/null
+++ b/src/mem/ruby/common/SubBlock.cc
@@ -0,0 +1,81 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ */
+
+#include "SubBlock.hh"
+
+SubBlock::SubBlock(const Address& addr, int size)
+{
+ m_address = addr;
+ setSize(size);
+ for(int i=0; i<size; i++) {
+ setByte(i, 0);
+ }
+}
+
+SubBlock::SubBlock(const Address& addr, const Address& logicalAddress, int size)
+{
+ m_address = addr;
+ m_logicalAddress = logicalAddress;
+ setSize(size);
+ for(int i=0; i<size; i++) {
+ setByte(i, 0);
+ }
+}
+
+void SubBlock::internalMergeFrom(const DataBlock& data)
+{
+ int size = getSize();
+ assert(size > 0);
+ int offset = m_address.getOffset();
+ for(int i=0; i<size; i++) {
+ this->setByte(i, data.getByte(offset+i));
+ }
+}
+
+void SubBlock::internalMergeTo(DataBlock& data) const
+{
+ int size = getSize();
+ assert(size > 0);
+ int offset = m_address.getOffset();
+ for(int i=0; i<size; i++) {
+ data.setByte(offset+i, this->getByte(i)); // This will detect crossing a cache line boundary
+ }
+}
+
+void SubBlock::print(ostream& out) const
+{
+ out << "[" << m_address << ", " << getSize() << ", " << m_data << "]";
+}
+
+
+
diff --git a/src/mem/ruby/common/SubBlock.hh b/src/mem/ruby/common/SubBlock.hh
new file mode 100644
index 000000000..43f91e191
--- /dev/null
+++ b/src/mem/ruby/common/SubBlock.hh
@@ -0,0 +1,105 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * 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.
+ */
+
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SubBlock_H
+#define SubBlock_H
+
+#include "Global.hh"
+#include "Address.hh"
+#include "RubyConfig.hh"
+#include "DataBlock.hh"
+#include "Vector.hh"
+
+class SubBlock {
+public:
+ // Constructors
+ SubBlock() { }
+ SubBlock(const Address& addr, int size);
+ SubBlock(const Address& addr, const Address& logicalAddress, int size);
+
+ // Destructor
+ ~SubBlock() { }
+
+ // Public Methods
+ const Address& getAddress() const { return m_address; }
+ const Address& getLogicalAddress() const { return m_logicalAddress; }
+ void setAddress(const Address& addr) { m_address = addr; }
+ void setLogicalAddress(const Address& addr) { m_logicalAddress = addr; }
+
+ int getSize() const { return m_data.size(); }
+ void setSize(int size) { m_data.setSize(size); }
+ uint8 getByte(int offset) const { return m_data[offset]; }
+ void setByte(int offset, uint8 data) { m_data[offset] = data; }
+
+ // Shorthands
+ uint8 readByte() const { return getByte(0); }
+ void writeByte(uint8 data) { setByte(0, data); }
+
+ // Merging to and from DataBlocks - We only need to worry about
+ // updates when we are using DataBlocks
+ void mergeTo(DataBlock& data) const { if (DATA_BLOCK) { internalMergeTo(data); } }
+ void mergeFrom(const DataBlock& data) { if (DATA_BLOCK) { internalMergeFrom(data); } }
+
+ void print(ostream& out) const;
+private:
+ // Private Methods
+ // SubBlock(const SubBlock& obj);
+ // SubBlock& operator=(const SubBlock& obj);
+ // bool bytePresent(const Address& addr) { return ((addr.getAddress() >= m_address.getAddress()) && (addr.getAddress() < (m_address.getAddress()+getSize()))); }
+ // uint8 getByte(const Address& addr) { return m_data[addr.getAddress() - m_address.getAddress()]; }
+
+ void internalMergeTo(DataBlock& data) const;
+ void internalMergeFrom(const DataBlock& data);
+
+ // Data Members (m_ prefix)
+ Address m_address;
+ Address m_logicalAddress;
+ Vector<uint> m_data;
+};
+
+// Output operator declaration
+ostream& operator<<(ostream& out, const SubBlock& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const SubBlock& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //SubBlock_H