summaryrefslogtreecommitdiff
path: root/src/mem/gems_common
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
committerNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
commit2f30950143cc70bc42a3c8a4111d7cf8198ec881 (patch)
tree708f6c22edb3c6feb31dd82866c26623a5329580 /src/mem/gems_common
parentc70241810d4e4f523f173c1646b008dc40faad8e (diff)
downloadgem5-2f30950143cc70bc42a3c8a4111d7cf8198ec881.tar.xz
ruby: Import ruby and slicc from GEMS
We eventually plan to replace the m5 cache hierarchy with the GEMS hierarchy, but for now we will make both live alongside eachother.
Diffstat (limited to 'src/mem/gems_common')
-rw-r--r--src/mem/gems_common/Allocator.hh83
-rw-r--r--src/mem/gems_common/Map.hh186
-rw-r--r--src/mem/gems_common/PrioHeap.hh249
-rw-r--r--src/mem/gems_common/RefCnt.hh162
-rw-r--r--src/mem/gems_common/RefCnt_tester.cc78
-rw-r--r--src/mem/gems_common/RefCountable.hh59
-rw-r--r--src/mem/gems_common/Vector.hh334
-rwxr-xr-xsrc/mem/gems_common/calc_host.sh38
-rw-r--r--src/mem/gems_common/ioutil/attrlex.ll229
-rw-r--r--src/mem/gems_common/ioutil/attrparse.yy232
-rw-r--r--src/mem/gems_common/ioutil/confio.cc456
-rw-r--r--src/mem/gems_common/ioutil/confio.hh192
-rw-r--r--src/mem/gems_common/ioutil/embedtext.py54
-rw-r--r--src/mem/gems_common/ioutil/initvar.cc626
-rw-r--r--src/mem/gems_common/ioutil/initvar.hh181
-rw-r--r--src/mem/gems_common/ioutil/vardecl.hh75
-rw-r--r--src/mem/gems_common/std-includes.hh51
-rw-r--r--src/mem/gems_common/util.cc109
-rw-r--r--src/mem/gems_common/util.hh68
19 files changed, 3462 insertions, 0 deletions
diff --git a/src/mem/gems_common/Allocator.hh b/src/mem/gems_common/Allocator.hh
new file mode 100644
index 000000000..109696601
--- /dev/null
+++ b/src/mem/gems_common/Allocator.hh
@@ -0,0 +1,83 @@
+/*
+ * 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 ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include "Vector.hh"
+
+template <class TYPE>
+class Allocator {
+public:
+ // Constructors
+ Allocator() { m_counter = 0; }
+
+ // Destructor
+ ~Allocator() { for(int i=0; i<m_pool_vec.size(); i++) { delete m_pool_vec[i]; }}
+
+ // Public Methods
+ TYPE* allocate(const TYPE& obj);
+ void deallocate(TYPE* obj_ptr);
+private:
+ // Private copy constructor and assignment operator
+ Allocator(const Allocator& obj);
+ Allocator& operator=(const Allocator& obj);
+
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ Vector<TYPE*> m_pool_vec;
+ int m_counter;
+};
+
+template <class TYPE>
+inline
+TYPE* Allocator<TYPE>::allocate(const TYPE& obj)
+{
+ m_counter++;
+ DEBUG_EXPR(ALLOCATOR_COMP, LowPrio, m_counter);
+ TYPE* new_obj_ptr;
+
+ // See if we need to allocate any new objects
+ if (m_pool_vec.size() == 0) {
+ // Allocate a new item
+ m_pool_vec.insertAtBottom(new TYPE);
+ }
+
+ // Pop the pointer from the stack/pool
+ int size = m_pool_vec.size();
+ new_obj_ptr = m_pool_vec[size-1];
+ m_pool_vec.setSize(size-1);
+
+ // Copy the object
+ *new_obj_ptr = obj;
+ return new_obj_ptr;
+}
+
+template <class TYPE>
+inline
+void Allocator<TYPE>::deallocate(TYPE* obj)
+{
+ m_pool_vec.insertAtBottom(obj);
+}
+
+#endif //ALLOCATOR_H
diff --git a/src/mem/gems_common/Map.hh b/src/mem/gems_common/Map.hh
new file mode 100644
index 000000000..1ecd13d64
--- /dev/null
+++ b/src/mem/gems_common/Map.hh
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 1999-2005 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 MAP_H
+#define MAP_H
+
+#include "Vector.hh"
+
+namespace __gnu_cxx {
+ template <> struct hash <std::string>
+ {
+ size_t operator()(const string& s) const { return hash<char*>()(s.c_str()); }
+ };
+}
+
+typedef unsigned long long uint64;
+//hack for uint64 hashes...
+namespace __gnu_cxx {
+ template <> struct hash <uint64>
+ {
+ size_t operator()(const uint64 & s) const { return (size_t) s; }
+ };
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+class Map
+{
+public:
+ Map() { /* empty */ }
+ ~Map() { /* empty */ }
+
+ void add(const KEY_TYPE& key, const VALUE_TYPE& value);
+ bool exist(const KEY_TYPE& key) const;
+ int size() const { return m_map.size(); }
+ void erase(const KEY_TYPE& key) { assert(exist(key)); m_map.erase(key); }
+ Vector<KEY_TYPE> keys() const;
+ Vector<VALUE_TYPE> values() const;
+ void deleteKeys();
+ void deleteValues();
+ VALUE_TYPE& lookup(const KEY_TYPE& key) const;
+ void clear() { m_map.clear(); }
+ void print(ostream& out) const;
+
+ // Synonyms
+ void remove(const KEY_TYPE& key) { erase(key); }
+ void deallocate(const KEY_TYPE& key) { erase(key); }
+ void allocate(const KEY_TYPE& key) { add(key, VALUE_TYPE()); }
+ void insert(const KEY_TYPE& key, const VALUE_TYPE& value) { add(key, value); }
+
+ // Use default copy constructor and assignment operator
+private:
+ // Data members
+
+ // m_map is declared mutable because some methods from the STL "map"
+ // class that should be const are not. Thus we define this as
+ // mutable so we can still have conceptually const accessors.
+ mutable __gnu_cxx::hash_map<KEY_TYPE, VALUE_TYPE> m_map;
+};
+
+template <class KEY_TYPE, class VALUE_TYPE>
+ostream& operator<<(ostream& out, const Map<KEY_TYPE, VALUE_TYPE>& map);
+
+// *********************
+
+template <class KEY_TYPE, class VALUE_TYPE>
+void Map<KEY_TYPE, VALUE_TYPE>::add(const KEY_TYPE& key, const VALUE_TYPE& value)
+{
+ // Update or add a new key/value pair
+ m_map[key] = value;
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+bool Map<KEY_TYPE, VALUE_TYPE>::exist(const KEY_TYPE& key) const
+{
+ return (m_map.count(key) != 0);
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+VALUE_TYPE& Map<KEY_TYPE, VALUE_TYPE>::lookup(const KEY_TYPE& key) const
+{
+ assert(exist(key));
+ return m_map[key];
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+Vector<KEY_TYPE> Map<KEY_TYPE, VALUE_TYPE>::keys() const
+{
+ Vector<KEY_TYPE> keys;
+ typename hash_map<KEY_TYPE, VALUE_TYPE>::const_iterator iter;
+ for (iter = m_map.begin(); iter != m_map.end(); iter++) {
+ keys.insertAtBottom((*iter).first);
+ }
+ return keys;
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+Vector<VALUE_TYPE> Map<KEY_TYPE, VALUE_TYPE>::values() const
+{
+ Vector<VALUE_TYPE> values;
+ typename hash_map<KEY_TYPE, VALUE_TYPE>::const_iterator iter;
+ pair<KEY_TYPE, VALUE_TYPE> p;
+
+ for (iter = m_map.begin(); iter != m_map.end(); iter++) {
+ p = *iter;
+ values.insertAtBottom(p.second);
+ }
+ return values;
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+void Map<KEY_TYPE, VALUE_TYPE>::deleteKeys()
+{
+ typename hash_map<KEY_TYPE, VALUE_TYPE>::const_iterator iter;
+ pair<KEY_TYPE, VALUE_TYPE> p;
+
+ for (iter = m_map.begin(); iter != m_map.end(); iter++) {
+ p = *iter;
+ delete p.first;
+ }
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+void Map<KEY_TYPE, VALUE_TYPE>::deleteValues()
+{
+ typename hash_map<KEY_TYPE, VALUE_TYPE>::const_iterator iter;
+ pair<KEY_TYPE, VALUE_TYPE> p;
+
+ for (iter = m_map.begin(); iter != m_map.end(); iter++) {
+ p = *iter;
+ delete p.second;
+ }
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+void Map<KEY_TYPE, VALUE_TYPE>::print(ostream& out) const
+{
+ typename hash_map<KEY_TYPE, VALUE_TYPE>::const_iterator iter;
+ pair<KEY_TYPE, VALUE_TYPE> p;
+
+ out << "[";
+ for (iter = m_map.begin(); iter != m_map.end(); iter++) {
+ // unparse each basic block
+ p = *iter;
+ out << " " << p.first << "=" << p.second;
+ }
+ out << " ]";
+}
+
+template <class KEY_TYPE, class VALUE_TYPE>
+ostream& operator<<(ostream& out, const Map<KEY_TYPE, VALUE_TYPE>& map)
+{
+ map.print(out);
+ return out;
+}
+
+#endif //MAP_H
diff --git a/src/mem/gems_common/PrioHeap.hh b/src/mem/gems_common/PrioHeap.hh
new file mode 100644
index 000000000..d549f0944
--- /dev/null
+++ b/src/mem/gems_common/PrioHeap.hh
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1999-2005 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 PRIOHEAP_H
+#define PRIOHEAP_H
+
+#include "Vector.hh"
+
+typedef unsigned int HeapIndex;
+
+template <class TYPE>
+class PrioHeap {
+public:
+ // Constructors
+ PrioHeap() { init(); }
+
+ // Destructor
+ //~PrioHeap();
+
+ // Public Methods
+ void init() { m_current_size = 0; }
+ int size() const { return m_current_size; }
+ void insert(const TYPE& key);
+ const TYPE& peekMin() const;
+ const TYPE& peekElement(int index) const;
+ TYPE extractMin();
+ void print(ostream& out) const;
+private:
+ // Private Methods
+ bool verifyHeap() const;
+ bool verifyHeap(HeapIndex index) const;
+ void heapify();
+
+ // Private copy constructor and assignment operator
+ PrioHeap(const PrioHeap& obj);
+ PrioHeap<TYPE>& operator=(const PrioHeap& obj);
+
+ // Data Members (m_ prefix)
+ Vector<TYPE> m_heap;
+ HeapIndex m_current_size;
+};
+
+// Output operator declaration
+template <class TYPE>
+ostream& operator<<(ostream& out, const PrioHeap<TYPE>& obj);
+
+// ******************* Helper Functions *******************
+inline
+HeapIndex get_parent(HeapIndex i)
+{
+ // return (i/2);
+ return (i>>1);
+}
+
+inline
+HeapIndex get_right(HeapIndex i)
+{
+ // return (2*i) + 1;
+ return (i<<1) | 1;
+}
+
+inline
+HeapIndex get_left(HeapIndex i)
+{
+ // return (2*i);
+ return (i<<1);
+}
+
+template <class TYPE>
+void prio_heap_swap(TYPE& n1, TYPE& n2)
+{
+ TYPE temp = n1;
+ n1 = n2;
+ n2 = temp;
+}
+
+// ******************* Definitions *******************
+
+template <class TYPE>
+void PrioHeap<TYPE>::insert(const TYPE& key)
+{
+ int i;
+ // grow the vector size
+ m_current_size++;
+ m_heap.setSize(m_current_size+1);
+
+ if(m_current_size == 1){ // HACK: need to initialize index 0 to avoid purify UMCs
+ m_heap[0] = key;
+ }
+
+ i = m_current_size;
+ while ((i > 1) && (node_less_then_eq(key, m_heap[get_parent(i)]))) {
+ m_heap[i] = m_heap[get_parent(i)];
+ i = get_parent(i);
+ }
+ m_heap[i] = key;
+ // assert(verifyHeap());
+}
+
+template <class TYPE>
+const TYPE& PrioHeap<TYPE>::peekMin() const
+{
+ assert(size() > 0);
+ return m_heap[1]; // 1, not 0, is the first element
+}
+
+template <class TYPE>
+const TYPE& PrioHeap<TYPE>::peekElement(int index) const
+{
+ assert(size() > 0);
+ return m_heap[index];
+}
+
+template <class TYPE>
+TYPE PrioHeap<TYPE>::extractMin()
+{
+ // TYPE temp;
+ assert(size() > 0);
+ TYPE temp = m_heap[1]; // 1, not 0, is the first element
+ m_heap[1] = m_heap[m_current_size];
+ m_current_size--;
+ heapify();
+ return temp;
+}
+
+template <class TYPE>
+bool PrioHeap<TYPE>::verifyHeap() const
+{
+ return verifyHeap(1);
+}
+
+template <class TYPE>
+bool PrioHeap<TYPE>::verifyHeap(HeapIndex index) const
+{
+ // Recursively verify that each node is <= its parent
+ if(index > m_current_size) {
+ return true;
+ } else if (index == 1) {
+ return
+ verifyHeap(get_right(index)) &&
+ verifyHeap(get_left(index));
+ } else if (node_less_then_eq(m_heap[get_parent(index)], m_heap[index])) {
+ return
+ verifyHeap(get_right(index)) &&
+ verifyHeap(get_left(index));
+ } else {
+ // Heap property violation
+ return false;
+ }
+}
+
+template <class TYPE>
+void PrioHeap<TYPE>::heapify()
+{
+ HeapIndex current_node = 1;
+ HeapIndex left, right, smallest;
+ // HeapIndex size = m_current_size;
+
+ while(true) {
+ left = get_left(current_node);
+ right = get_right(current_node);
+
+ // Find the smallest of the current node and children
+ if (left <= m_current_size && node_less_then_eq(m_heap[left], m_heap[current_node])) {
+ smallest = left;
+ } else {
+ smallest = current_node;
+ }
+
+ if (right <= m_current_size && node_less_then_eq(m_heap[right], m_heap[smallest])) {
+ smallest = right;
+ }
+
+ // Check to see if we are done
+ if (smallest == current_node) {
+ // We are done
+ break;
+ } else {
+ // Not done, heapify on the smallest child
+ prio_heap_swap(m_heap[current_node], m_heap[smallest]);
+ current_node = smallest;
+ }
+ }
+ // assert(verifyHeap());
+}
+
+template <class TYPE>
+void PrioHeap<TYPE>::print(ostream& out) const
+{
+ Vector<TYPE> copyHeap(m_heap);
+
+ // sort copyHeap (inefficient, but will not be done often)
+
+ for(HeapIndex i=0;i<m_current_size; i++){
+ for(HeapIndex j=0; j< m_current_size; j++){
+ if(copyHeap[i].m_time < copyHeap[j].m_time){
+ prio_heap_swap(copyHeap[i], copyHeap[j]);
+ }
+ }
+ }
+
+ out << "[PrioHeap: ";
+
+ for(HeapIndex i=1; i<= m_current_size; i++){
+ out << copyHeap[i];
+
+ if(i != m_current_size-1){
+ out << ",";
+ }
+ out << " ";
+ }
+ out << "]";
+}
+
+// Output operator definition
+template <class TYPE>
+ostream& operator<<(ostream& out, const PrioHeap<TYPE>& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif //PRIOHEAP_H
diff --git a/src/mem/gems_common/RefCnt.hh b/src/mem/gems_common/RefCnt.hh
new file mode 100644
index 000000000..fc1ddbae9
--- /dev/null
+++ b/src/mem/gems_common/RefCnt.hh
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1999-2005 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 REFCNT_H
+#define REFCNT_H
+
+template <class TYPE>
+class RefCnt {
+public:
+ // Constructors
+ RefCnt();
+ RefCnt(const TYPE& data);
+
+ // Destructor
+ ~RefCnt();
+
+ // Public Methods
+ const TYPE* ref() const { return m_data_ptr; }
+ TYPE* ref() { return m_data_ptr; }
+ TYPE* mod_ref() const { return m_data_ptr; }
+ void freeRef();
+ void print(ostream& out) const;
+
+ // Public copy constructor and assignment operator
+ RefCnt(const RefCnt& obj);
+ RefCnt& operator=(const RefCnt& obj);
+
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ TYPE* m_data_ptr;
+ // int* m_count_ptr; // Not used yet
+};
+
+// Output operator declaration
+template <class TYPE>
+inline
+ostream& operator<<(ostream& out, const RefCnt<TYPE>& obj);
+
+// ******************* Definitions *******************
+
+// Constructors
+template <class TYPE>
+inline
+RefCnt<TYPE>::RefCnt()
+{
+ m_data_ptr = NULL;
+}
+
+template <class TYPE>
+inline
+RefCnt<TYPE>::RefCnt(const TYPE& data)
+{
+ m_data_ptr = data.clone();
+ m_data_ptr->setRefCnt(1);
+}
+
+template <class TYPE>
+inline
+RefCnt<TYPE>::~RefCnt()
+{
+ freeRef();
+}
+
+template <class TYPE>
+inline
+void RefCnt<TYPE>::freeRef()
+{
+ if (m_data_ptr != NULL) {
+ m_data_ptr->decRefCnt();
+ if (m_data_ptr->getRefCnt() == 0) {
+ m_data_ptr->destroy();
+ }
+ m_data_ptr = NULL;
+ }
+}
+
+template <class TYPE>
+inline
+void RefCnt<TYPE>::print(ostream& out) const
+{
+ if (m_data_ptr == NULL) {
+ out << "[RefCnt: Null]";
+ } else {
+ out << "[RefCnt: ";
+ m_data_ptr->print(out);
+ out << "]";
+ }
+}
+
+// Copy constructor
+template <class TYPE>
+inline
+RefCnt<TYPE>::RefCnt(const RefCnt<TYPE>& obj)
+{
+ // m_data_ptr = obj.m_data_ptr->clone();
+ m_data_ptr = obj.m_data_ptr;
+
+ // Increment the reference count
+ if (m_data_ptr != NULL) {
+ m_data_ptr->incRefCnt();
+ }
+}
+
+// Assignment operator
+template <class TYPE>
+inline
+RefCnt<TYPE>& RefCnt<TYPE>::operator=(const RefCnt<TYPE>& obj)
+{
+ if (this == &obj) {
+ // If this is the case, do nothing
+ // assert(false);
+ } else {
+ freeRef();
+ m_data_ptr = obj.m_data_ptr;
+ if (m_data_ptr != NULL) {
+ m_data_ptr->incRefCnt();
+ }
+ }
+ return *this;
+}
+
+
+// Output operator definition
+template <class TYPE>
+inline
+ostream& operator<<(ostream& out, const RefCnt<TYPE>& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+
+
+#endif //REFCNT_H
diff --git a/src/mem/gems_common/RefCnt_tester.cc b/src/mem/gems_common/RefCnt_tester.cc
new file mode 100644
index 000000000..574f8fe3c
--- /dev/null
+++ b/src/mem/gems_common/RefCnt_tester.cc
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999-2005 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.
+ */
+
+/*
+ * Code used to test the RefCnt class
+ */
+
+#include "RefCnt.hh"
+#include "RefCountable.hh"
+
+class Foo : public RefCountable {
+public:
+ int m_data;
+ Foo* clone() const;
+private:
+};
+
+Foo* Foo::clone() const
+{
+ Foo* temp_ptr;
+ temp_ptr = new Foo;
+ *temp_ptr = *this;
+ cout << "Cloned!" << endl;
+ return temp_ptr;
+}
+
+void bar(RefCnt<Foo> f)
+{
+ cout << f.ref()->m_data << endl;
+}
+
+Foo f2;
+
+int main()
+{
+ Foo f;
+ f.m_data = 2;
+
+ {
+ RefCnt<Foo> a(f);
+
+ f.m_data = 3;
+ cout << a.ref()->m_data << endl;
+ cout << f.m_data << endl;
+ f2 = f;
+ }
+
+ bar(f2);
+
+ return 0;
+}
+
+
diff --git a/src/mem/gems_common/RefCountable.hh b/src/mem/gems_common/RefCountable.hh
new file mode 100644
index 000000000..88aba07e6
--- /dev/null
+++ b/src/mem/gems_common/RefCountable.hh
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1999-2005 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.
+ */
+
+/*
+ * Virtual base class for things that can be reference counted
+ */
+
+#ifndef REFCOUNTABLE_H
+#define REFCOUNTABLE_H
+
+#include "RefCnt.hh"
+
+class RefCountable {
+public:
+ // Public Methods
+
+ RefCountable() { m_refcnt = 0; }
+
+ // These are used by the RefCnt class to hold the reference count
+ // for the object. These really should be private and accessed by a
+ // friend class, but I can't figure out how to make a template class
+ // a friend.
+ void incRefCnt() { m_refcnt++; }
+ void decRefCnt() { m_refcnt--; }
+ int getRefCnt() const { return m_refcnt; }
+ void setRefCnt(int cnt) { m_refcnt = cnt; }
+private:
+ // Private Methods
+
+ // Data Members (m_ prefix)
+ int m_refcnt;
+};
+
+#endif //REFCOUNTABLE_H
diff --git a/src/mem/gems_common/Vector.hh b/src/mem/gems_common/Vector.hh
new file mode 100644
index 000000000..744dc698c
--- /dev/null
+++ b/src/mem/gems_common/Vector.hh
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 1999-2005 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.
+ */
+
+/*
+ * Description: The Vector class is a generic container which acts
+ * much like an array. The Vector class handles dynamic sizing and
+ * resizing as well as performing bounds checking on each access. An
+ * "insertAtBottom" operation is supported to allow adding elements to
+ * the Vector much like you would add new elements to a linked list or
+ * queue.
+ */
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include "std-includes.hh"
+
+template <class TYPE>
+class Vector
+{
+public:
+ Vector();
+ explicit Vector(int initial_size); // Construct with an initial max size
+ ~Vector();
+ const TYPE& ref(int index) const; // Get an element of the vector
+ TYPE& ref(int index); // Get an element of the vector
+ void clear(); // remove all elements of the vector
+ void sortVector(); // sort all elements using < operator
+ int size() const { return m_size; }
+ void setSize(int new_size); // Increase size, reallocates memory as needed
+ void expand(int num) { setSize(m_size+num); } // Increase size by num
+ void increaseSize(int new_size, const TYPE& reset); // and adds num of slots at the bottom set to reset value
+ void insertAtTop(const TYPE& element); // Increase size by one and set last element
+ // FIXME - WARNING: insertAtTop is currently O(n) and needs to be fixed
+ void insertAtBottom(const TYPE& element); // Increase size by one and set last element
+ TYPE sum() const; // Uses the += operator to sum all the elements of the vector
+ void deletePointers(); // Walks the Vector calling delete on all
+ // elements and sets them to NULL, can only
+ // be used when the TYPE is a pointer type.
+ void removeFromTop(int num); // removes elements from top
+ void print(ostream& out) const;
+
+
+ // Array Reference operator overloading
+ const TYPE& operator[](int index) const { return ref(index); }
+ TYPE& operator[](int index) { return ref(index); }
+
+ // Public copy constructor and assignment operator
+ Vector(const Vector& vec);
+ Vector<TYPE>& operator=(const Vector& vec);
+private:
+
+ void grow(int new_max_size); // Expands vector to new_max_size
+
+ // Data members
+ TYPE* m_vec; // Array to hold the elements
+ int m_size; // Number of elements in use
+ int m_max_size; // Size of allocated array
+};
+
+template <class TYPE>
+ostream& operator<<(ostream& out, const Vector<TYPE>& vec);
+
+// *********************
+
+template <class TYPE>
+Vector<TYPE>::Vector()
+{
+ m_size = 0;
+ m_max_size = 0;
+ m_vec = NULL;
+}
+
+template <class TYPE>
+Vector<TYPE>::Vector(int initial_size)
+{
+ m_size = 0;
+ m_max_size = initial_size;
+ m_vec = NULL;
+ grow(initial_size);
+}
+
+template <class TYPE>
+Vector<TYPE>::~Vector()
+{
+ delete [] m_vec;
+}
+
+template <class TYPE>
+const TYPE& Vector<TYPE>::ref(int index) const
+{
+#ifndef NO_VECTOR_BOUNDS_CHECKS
+ assert(m_size != 0);
+ assert(index < m_size);
+ assert(index >= 0);
+#endif
+ return m_vec[index];
+}
+
+template <class TYPE>
+TYPE& Vector<TYPE>::ref(int index)
+{
+#ifndef NO_VECTOR_BOUNDS_CHECKS
+ assert(m_size != 0);
+ assert(index < m_size);
+ assert(index >= 0);
+#endif
+ return m_vec[index];
+}
+
+
+template <class TYPE>
+void Vector<TYPE>::setSize(int new_size)
+{
+ // FIXME - this should also decrease or shrink the size of the array at some point.
+ if (new_size > m_max_size) {
+ grow(max((m_max_size+1)*2, new_size));
+ }
+ m_size = new_size;
+#ifndef NO_VECTOR_BOUNDS_CHECKS
+ assert(m_size <= m_max_size);
+ assert(m_size >= 0);
+#endif
+}
+
+template <class TYPE>
+inline
+void Vector<TYPE>::increaseSize(int new_size, const TYPE& reset)
+{
+ assert(new_size >= m_size);
+ if (new_size >= m_max_size) {
+ grow(max((m_max_size+1)*2, new_size));
+ }
+ int old_size = m_size;
+ m_size = new_size;
+ for (int j = old_size; j < m_size; j++) {
+ ref(j) = reset;
+ }
+
+#ifndef NO_VECTOR_BOUNDS_CHECKS
+ assert(m_size <= m_max_size);
+ assert(m_size >= 0);
+#endif
+}
+
+template <class TYPE>
+inline
+void Vector<TYPE>::clear()
+{
+ m_size = 0;
+ m_max_size = 0;
+ delete [] m_vec;
+ m_vec = NULL;
+}
+
+template <class TYPE>
+inline
+void Vector<TYPE>::sortVector()
+{
+ sort(&m_vec[0], &m_vec[m_size]);
+}
+
+template <class TYPE>
+inline
+void Vector<TYPE>::insertAtTop(const TYPE& element)
+{
+ setSize(m_size+1);
+ for (int i = m_size-1; i >= 1; i--) {
+ ref(i) = ref(i-1);
+ }
+ ref(0) = element;
+}
+
+template <class TYPE>
+inline
+void Vector<TYPE>::removeFromTop(int num)
+{
+ if (num > m_size) {
+ num = m_size;
+ }
+ for (int i = 0; i < m_size - num; i++) {
+ m_vec[i] = m_vec[i+num];
+ }
+ m_size = m_size - num;
+
+}
+
+template <class TYPE>
+void Vector<TYPE>::insertAtBottom(const TYPE& element)
+{
+ setSize(m_size+1);
+ ref(m_size-1) = element;
+}
+
+template <class TYPE>
+TYPE Vector<TYPE>::sum() const
+{
+ assert(m_size > 0);
+ TYPE sum = ref(0);
+ for(int i=1; i<m_size; i++) {
+ sum += ref(i);
+ }
+ return sum;
+}
+
+template <class TYPE>
+void Vector<TYPE>::deletePointers()
+{
+ assert(m_size >= 0);
+ for(int i=0; i<m_size; i++) {
+ // FIXME this function should be non-member function, otherwise this
+ // prevent template instantiation for non-pointer types
+ //
+ // Also, there is warning of Switch.cc which use void* here
+ delete ref(i);
+ ref(i) = NULL;
+ }
+}
+
+template <class TYPE>
+void Vector<TYPE>::print(ostream& out) const
+{
+ out << "[ ";
+ for(int i=0; i<m_size; i++) {
+ if (i != 0) {
+ out << " ";
+ }
+ out << ref(i);
+ }
+ out << " ]";
+ out << flush;
+}
+
+// Copy constructor
+template <class TYPE>
+Vector<TYPE>::Vector(const Vector& vec)
+{
+ // Setup the new memory
+ m_size = vec.m_size;
+ m_max_size = vec.m_max_size;
+ if (m_max_size != 0) {
+ m_vec = new TYPE[m_max_size];
+ assert(m_vec != NULL);
+ } else {
+ m_vec = NULL;
+ }
+
+ // Copy the elements of the array
+ for(int i=0; i<m_size; i++) {
+ m_vec[i] = vec.m_vec[i]; // Element copy
+ }
+}
+
+template <class TYPE>
+Vector<TYPE>& Vector<TYPE>::operator=(const Vector& vec)
+{
+ if (this == &vec) {
+ // assert(0);
+ } else {
+ // Free the old memory
+ delete [] m_vec;
+
+ // Setup the new memory
+ m_size = vec.m_size;
+ m_max_size = vec.m_max_size;
+
+ if (m_max_size != 0) {
+ m_vec = new TYPE[m_max_size];
+ assert(m_vec != NULL);
+ } else {
+ m_vec = NULL;
+ }
+
+ // Copy the elements of the array
+ for(int i=0; i<m_size; i++) {
+ m_vec[i] = vec.m_vec[i]; // Element copy
+ }
+ }
+ return *this;
+}
+
+template <class TYPE>
+void Vector<TYPE>::grow(int new_max_size)
+{
+ TYPE* temp_vec;
+ m_max_size = new_max_size;
+ if (new_max_size != 0) {
+ temp_vec = new TYPE[new_max_size];
+ assert(temp_vec != NULL);
+ } else {
+ temp_vec = NULL;
+ }
+
+ // Copy the elements of the array
+ for(int i=0; i<m_size; i++) {
+ temp_vec[i] = m_vec[i]; // Element copy
+ }
+ delete [] m_vec;
+ m_vec = temp_vec;
+}
+
+template <class TYPE>
+ostream& operator<<(ostream& out, const Vector<TYPE>& vec)
+{
+ vec.print(out);
+ return out;
+}
+
+#endif //VECTOR_H
diff --git a/src/mem/gems_common/calc_host.sh b/src/mem/gems_common/calc_host.sh
new file mode 100755
index 000000000..f7a6116c1
--- /dev/null
+++ b/src/mem/gems_common/calc_host.sh
@@ -0,0 +1,38 @@
+#!/bin/csh -f
+
+set OS=`uname -s`
+set HOST_ARCH=`uname -m`
+
+switch ($OS)
+ case Linux:
+ set OS_PART=linux
+ breaksw
+ case SunOS:
+ set OS_PART=sol8-64
+ breaksw
+ case OSF1:
+ set OS_PART=tru64-gcc
+ breaksw
+ default:
+ set OS_PART=`echo $OS | sed 's/ /-/g'`
+endsw
+
+switch ($HOST_ARCH)
+ case i586:
+ set ARCH=x86
+ breaksw
+ case i686:
+ set ARCH=x86
+ breaksw
+ case x86_64:
+ set ARCH=amd64
+ breaksw
+ case sun4u:
+ set ARCH=v9
+ breaksw
+ default:
+ set ARCH=`echo $HOST_ARCH | sed 's/ /-/g'`
+endsw
+
+echo $ARCH-$OS_PART
+
diff --git a/src/mem/gems_common/ioutil/attrlex.ll b/src/mem/gems_common/ioutil/attrlex.ll
new file mode 100644
index 000000000..293350b23
--- /dev/null
+++ b/src/mem/gems_common/ioutil/attrlex.ll
@@ -0,0 +1,229 @@
+/*
+ Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the
+ Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
+ http://www.cs.wisc.edu/gems/
+
+ --------------------------------------------------------------------
+
+ This file a component of the Multifacet GEMS (General
+ Execution-driven Multiprocessor Simulator) software toolset
+ originally developed at the University of Wisconsin-Madison.
+
+ Ruby was originally developed primarily by Milo Martin and Daniel
+ Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
+ Plakal.
+
+ SLICC was originally developed by Milo Martin with substantial
+ contributions from Daniel Sorin.
+
+ Opal was originally developed by Carl Mauer based upon code by
+ Craig Zilles.
+
+ Substantial further development of Multifacet GEMS at the
+ University of Wisconsin was performed by Alaa Alameldeen, Brad
+ Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty,
+ Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and
+ Luke Yen.
+
+ --------------------------------------------------------------------
+
+ If your use of this software contributes to a published paper, we
+ request that you (1) cite our summary paper that appears on our
+ website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation
+ for your published paper to gems@cs.wisc.edu.
+
+ If you redistribute derivatives of this software, we request that
+ you notify us and either (1) ask people to register with us at our
+ website (http://www.cs.wisc.edu/gems/) or (2) collect registration
+ information and periodically send it to us.
+
+ --------------------------------------------------------------------
+
+ Multifacet GEMS is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ Multifacet GEMS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the Multifacet GEMS; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA
+
+ The GNU General Public License is contained in the file LICENSE.
+
+### END HEADER ###
+*/
+
+
+%option noyywrap
+
+ALPHADIGIT [^\:\,\(\)\n\t\(\) \0\#]
+HEXDIGIT [0-9a-fA-Fx]
+NEWLINE [\n]
+WHITESPACE [ \t]
+
+%{
+
+#ifdef IS_RUBY
+#include "Global.hh"
+#endif
+
+using namespace std;
+#include <string>
+#include <map>
+#include <stdlib.h>
+
+// Maurice
+// extern "C" {
+// #include "simics/api.h"
+// };
+
+#include "FakeSimicsDataTypes.hh"
+
+// CM: simics 1.6.5 API redefines fwrite, much to my chagrin
+#undef fwrite
+#undef printf
+#include "attrparse.h"
+
+#define MAX_INCLUDE_DEPTH 10
+
+/** global result of parsing file */
+extern attr_value_t g_attr_map;
+
+extern int atparse(void);
+
+static int linenum=1; /* the current line number */
+static int colnum=1; /* the current column number */
+static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+static int include_stack_ptr = 0;
+static char g_relative_include_path[256];
+
+
+// forward declaration of aterror
+void aterror(const char *msg);
+%}
+
+%x SLASHCOMMENT INCLUDE
+
+%%
+
+%{ /* PATTERNS FOR STRING TOKENS */
+%}
+
+"//".*[\n] { linenum++; colnum=1; } /* C++ style comments */
+
+\#include { colnum+=yyleng; BEGIN(INCLUDE); }
+<INCLUDE>{WHITESPACE}* { colnum+=yyleng; }
+<INCLUDE>[^ \t\n]+ {
+ // should really be FILEIO_MAX_FILENAME or MAX_NAME
+ char str[256];
+ if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
+ {
+ ERROR_OUT( "Includes nested too deeply" );
+ exit( 1 );
+ }
+ include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
+
+ yyin = fopen( yytext, "r" );
+ if ( ! yyin ) {
+ sprintf( str, "%s%s", g_relative_include_path, yytext );
+ yyin = fopen( str, "r" );
+ }
+ if ( ! yyin ) {
+ sprintf( str, "%s%s%s", g_relative_include_path, "config/", yytext );
+ yyin = fopen( str, "r" );
+ }
+ if ( ! yyin ) {
+ ERROR_OUT("unable to open included file: %s or %s\n", yytext, str);
+ aterror("file open error.\n");
+ }
+ yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ));
+ BEGIN(INITIAL);
+ }
+<<EOF>> {
+ if ( --include_stack_ptr < 0 ) {
+ yyterminate();
+ } else {
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ fclose(yyin);
+ yy_switch_to_buffer(include_stack[include_stack_ptr] );
+ }
+ }
+
+\( { colnum+=yyleng; return (LPAREN); }
+\) { colnum+=yyleng; return (RPAREN); }
+\: { colnum+=yyleng; return (':'); }
+\, { colnum+=yyleng; return (','); }
+{HEXDIGIT}+ {
+ colnum+=yyleng;
+ attr_value_t *val = (attr_value_t *)
+ malloc( sizeof(attr_value_t) );
+ memset( val, 0, sizeof(attr_value_t) );
+ atlval.attrval = val;
+ val->kind = Sim_Val_Integer;
+ val->u.integer = strtoull( yytext, NULL, 0 );
+ return (INTEGER); }
+{ALPHADIGIT}+ {
+ colnum+=yyleng;
+ attr_value_t *val = (attr_value_t *)
+ malloc( sizeof(attr_value_t) );
+ memset( val, 0, sizeof(attr_value_t) );
+ atlval.attrval = val;
+ val->kind = Sim_Val_String;
+ val->u.string = strdup(yytext);
+ return (STRING); }
+
+%{ /* OTHER PATTERNS */
+%}
+
+{WHITESPACE}+ {colnum += yyleng;}
+{NEWLINE} {linenum++; colnum = 1;}
+
+%%
+
+extern "C" void parseInitialize( void )
+{
+ // since no global variables are set in simics, we must do it manually
+ // this is also necessary now that the parser can be used more than once.
+ // (it is used to parse the defaults, and can be used after that)
+ linenum = 1;
+ colnum = 1;
+ include_stack_ptr = 0;
+}
+
+extern "C" int parseAttrFile( FILE *inputFile, const char *relative_include_path, attr_value_t *myTable )
+{
+ parseInitialize();
+ strncpy( g_relative_include_path, relative_include_path, 255 );
+
+ int result;
+ yyin = inputFile;
+ YY_BUFFER_STATE scan_state = yy_create_buffer( yyin, YY_BUF_SIZE );
+ yy_switch_to_buffer( scan_state );
+ result = atparse();
+ *myTable = g_attr_map;
+ yy_delete_buffer( scan_state );
+ return (result);
+}
+
+extern "C" int parseAttrString( const char *str, attr_value_t *myTable )
+{
+ parseInitialize();
+
+ int result;
+ YY_BUFFER_STATE scan_state = yy_scan_string( str );
+ result = atparse();
+ *myTable = g_attr_map;
+ yy_delete_buffer( scan_state );
+ return (result);
+}
+
+extern void aterror(const char *msg)
+{
+ ERROR_OUT("%d:%d: ERROR while parsing config file%s\n", linenum, colnum, msg );
+}
+
diff --git a/src/mem/gems_common/ioutil/attrparse.yy b/src/mem/gems_common/ioutil/attrparse.yy
new file mode 100644
index 000000000..8a0190e06
--- /dev/null
+++ b/src/mem/gems_common/ioutil/attrparse.yy
@@ -0,0 +1,232 @@
+/*
+ Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the
+ Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
+ http://www.cs.wisc.edu/gems/
+
+ --------------------------------------------------------------------
+
+ This file a component of the Multifacet GEMS (General
+ Execution-driven Multiprocessor Simulator) software toolset
+ originally developed at the University of Wisconsin-Madison.
+
+ Ruby was originally developed primarily by Milo Martin and Daniel
+ Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
+ Plakal.
+
+ SLICC was originally developed by Milo Martin with substantial
+ contributions from Daniel Sorin.
+
+ Opal was originally developed by Carl Mauer based upon code by
+ Craig Zilles.
+
+ Substantial further development of Multifacet GEMS at the
+ University of Wisconsin was performed by Alaa Alameldeen, Brad
+ Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty,
+ Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and
+ Luke Yen.
+
+ --------------------------------------------------------------------
+
+ If your use of this software contributes to a published paper, we
+ request that you (1) cite our summary paper that appears on our
+ website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation
+ for your published paper to gems@cs.wisc.edu.
+
+ If you redistribute derivatives of this software, we request that
+ you notify us and either (1) ask people to register with us at our
+ website (http://www.cs.wisc.edu/gems/) or (2) collect registration
+ information and periodically send it to us.
+
+ --------------------------------------------------------------------
+
+ Multifacet GEMS is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ Multifacet GEMS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the Multifacet GEMS; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA
+
+ The GNU General Public License is contained in the file LICENSE.
+
+### END HEADER ###
+*/
+
+
+
+%{
+/*------------------------------------------------------------------------*/
+/* Includes */
+/*------------------------------------------------------------------------*/
+
+#ifdef IS_RUBY
+#include "Global.hh"
+#endif
+
+using namespace std;
+#include <string>
+#include <map>
+#include <stdlib.h>
+
+// Maurice
+// extern "C" {
+// #include "simics/api.h"
+// };
+
+#include "FakeSimicsDataTypes.hh"
+
+#include "confio.hh"
+
+// CM FIX: if I wasn't working on a paper: I'd re-write the grammer to
+// be left (or right) recursive, which ever is more efficient
+// This only affects extremely large cache sizes / BP sizes on read in.
+#define YYMAXDEPTH 100000
+
+extern char* attext;
+
+extern void aterror(const char *);
+extern int atlex();
+attr_value_t g_attr_map;
+
+extern void fprintAttr( FILE *fp, attr_value_t attr );
+
+%}
+
+/*------------------------------------------------------------------------*/
+/* Union declarations */
+/*------------------------------------------------------------------------*/
+// The types of the tokens and nonterminals
+%union {
+ attr_value_t *attrval;
+};
+
+%token <attrval> STRING INTEGER
+%token MY_END LPAREN RPAREN
+
+%type <attrval> confmapping confpair attributes attrlist
+%%
+
+conffile : confmapping
+{
+ g_attr_map = *($1);
+ free( $1 )
+}
+
+confmapping : confmapping confpair
+{
+ attr_value_t *newattr = mallocAttribute(1);
+ newattr->kind = Sim_Val_List;
+ if ( $1 == NULL ) {
+ newattr->u.list.size = 1;
+ newattr->u.list.vector = $2;
+ } else {
+ // add the latest mapping to the return mapping
+ uint32 newsize = $1->u.list.size + 1;
+ attr_value_t *vector = mallocAttribute( newsize );
+ newattr->u.list.size = newsize;
+ newattr->u.list.vector = vector;
+ for (uint32 i = 0; i < newsize - 1; i++) {
+ vector[i] = $1->u.list.vector[i];
+ }
+ vector[newsize - 1] = *($2);
+ free( $1->u.list.vector );
+ free( $1 );
+ free( $2 );
+ }
+ $$ = newattr;
+}
+ | // nothing
+{
+ $$ = NULL;
+}
+
+confpair : STRING ':' attributes
+{
+ attr_value_t *newattr = mallocAttribute(1);
+ newattr->kind = Sim_Val_List;
+ newattr->u.list.size = 2;
+ newattr->u.list.vector = mallocAttribute(2);
+ newattr->u.list.vector[0] = *($1);
+ newattr->u.list.vector[1] = *($3);
+ free( $1 );
+ free( $3 );
+ $$ = newattr;
+}
+
+attributes : INTEGER
+{
+ $$ = $1;
+}
+ | STRING
+{
+ $$ = $1;
+}
+ | LPAREN attrlist RPAREN
+{
+ attr_value_t *newattr = mallocAttribute(1);
+ newattr->kind = Sim_Val_List;
+ if ( $2->kind != CONF_ATTR_SINGLE &&
+ $2->kind != CONF_ATTR_PAIR ) {
+ newattr->u.list.size = 1;
+ newattr->u.list.vector = $2;
+ } else {
+ newattr->u.list.size = $2->u.list.size;
+ newattr->u.list.vector = mallocAttribute(newattr->u.list.size);
+ attr_value_t *curattr = $2;
+ uint32 i = 0;
+ while ( i < newattr->u.list.size ) {
+ if (curattr->kind == CONF_ATTR_SINGLE) {
+ newattr->u.list.vector[i] = curattr->u.list.vector[0];
+ i++;
+
+ curattr = NULL;
+ } else if (curattr->kind == CONF_ATTR_PAIR) {
+ newattr->u.list.vector[i] = curattr->u.list.vector[0];
+ i++;
+ if ( i < newattr->u.list.size )
+ curattr = &(curattr->u.list.vector[1]);
+ else
+ curattr = NULL;
+
+ } else {
+ ERROR_OUT("error: unknown kind in pair: %d\n", curattr->kind);
+ ASSERT(0);
+ }
+ }
+ // FIX memory leak: around 600 KB
+ // freeAttribute( $2 ); // with gcc-3.4 this free call tries to free memory from the stack
+ }
+ $$ = newattr;
+}
+
+attrlist : attributes
+{
+ attr_value_t *newattr = mallocAttribute(1);
+ newattr->kind = CONF_ATTR_SINGLE;
+ newattr->u.list.size = 1;
+ newattr->u.list.vector = $1;
+ $$ = newattr;
+}
+ | attributes ',' attrlist
+{
+ // allocate the pair ( x , y ) attribute
+ attr_value_t *newattr = mallocAttribute(1);
+ int newsize = $3->u.list.size + 1;
+ attr_value_t *vector = mallocAttribute(2);
+ newattr->kind = CONF_ATTR_PAIR;
+ newattr->u.list.size = newsize;
+ newattr->u.list.vector = vector;
+
+ // assign the LH attribute
+ vector[0] = *($1);
+ vector[1] = *($3);
+ free( $1 );
+ free( $3 );
+ $$ = newattr;
+}
diff --git a/src/mem/gems_common/ioutil/confio.cc b/src/mem/gems_common/ioutil/confio.cc
new file mode 100644
index 000000000..68d44197a
--- /dev/null
+++ b/src/mem/gems_common/ioutil/confio.cc
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 1999-2005 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.
+ */
+
+/*
+ * saves configuration information for later runs
+ */
+
+/*------------------------------------------------------------------------*/
+/* Includes */
+/*------------------------------------------------------------------------*/
+
+#ifdef IS_OPAL
+#include "hfa.hh"
+#endif
+
+#ifdef IS_RUBY
+#include "Global.hh"
+#define SIM_HALT ASSERT(0)
+#endif
+
+#ifdef IS_TOURMALINE
+#include "Tourmaline_Global.hh"
+#endif
+
+using namespace std;
+#include <string>
+#include <map>
+#include <stdlib.h>
+
+// Maurice
+// extern "C" {
+// #include "global.hh"
+// #include "simics/api.hh"
+//
+// #ifdef SIMICS22X
+// #include "sparc_api.hh"
+// #endif
+// #ifdef SIMICS30
+// #ifdef SPARC
+// #include "sparc.hh"
+// #else
+// #include "x86.hh"
+// #endif
+// #endif
+// };
+
+#include "FakeSimicsDataTypes.hh"
+
+#include "confio.hh"
+
+/*------------------------------------------------------------------------*/
+/* Macro declarations */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Variable declarations */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Forward declarations */
+/*------------------------------------------------------------------------*/
+
+// C++ Template: explicit instantiation
+template class map<string, confnode_t *>;
+
+// These functions are defined in parser/attrlex.l
+extern "C" int parseAttrFile( FILE *inputFile, const char *relative_include_path, attr_value_t *myTable );
+extern "C" int parseAttrString( const char *str, attr_value_t *myTable );
+
+/*------------------------------------------------------------------------*/
+/* Constructor(s) / destructor */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+confio_t::confio_t( )
+{
+ m_verbose = false;
+}
+
+//**************************************************************************
+confio_t::~confio_t( )
+{
+ ConfTable::iterator iter;
+
+ for ( iter = m_table.begin(); iter != m_table.end(); iter++ ) {
+ confnode_t *cfnode = (*iter).second;
+ free( cfnode );
+ }
+}
+
+/*------------------------------------------------------------------------*/
+/* Public methods */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Accessor(s) / mutator(s) */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+int confio_t::register_attribute( const char *name,
+ get_confio_t get_attr, void *get_attr_data,
+ set_confio_t set_attr, void *set_attr_data )
+{
+ confnode_t *newnode;
+ if ( m_table.find(name) == m_table.end() ) {
+ if (m_verbose)
+ DEBUG_OUT(" registering checkpoint attribute: \"%s\"\n", name);
+
+ // add a new entry to the table
+ newnode = (confnode_t *) malloc( sizeof( confnode_t ) );
+ newnode->get_attr = get_attr;
+ newnode->set_attr = set_attr;
+ newnode->set_attr_data = set_attr_data;
+ newnode->get_attr_data = get_attr_data;
+ newnode->attr_is_set = false;
+ string key(name);
+ m_table[key] = newnode;
+ } else {
+ ERROR_OUT(" warning: confio: adding existing conf node: %s\n", name);
+ }
+ return 0;
+}
+
+//**************************************************************************
+void fprintAttr( FILE *fp, attr_value_t attr )
+{
+ switch (attr.kind) {
+ case Sim_Val_Invalid:
+ fprintf(fp, "invalid");
+ break;
+
+ case Sim_Val_String:
+ fprintf(fp, "%s", attr.u.string);
+ break;
+
+ case Sim_Val_Integer:
+ fprintf(fp, "0x%llx", attr.u.integer);
+ break;
+
+ case Sim_Val_Floating:
+ fprintf(fp, "0x%llx", attr.u.integer);
+ break;
+
+ case Sim_Val_List:
+ fprintf(fp, "(");
+ for (uint32 i = 0; i < attr.u.list.size; i++) {
+ fprintAttr(fp, attr.u.list.vector[i]);
+ if (i != attr.u.list.size -1) {
+ fprintf(fp, ", ");
+ }
+ }
+ fprintf(fp, ")");
+ break;
+
+ default:
+ ERROR_OUT("fprintAttr: unknown/unimplemented attribute %d\n", attr.kind);
+ }
+}
+
+//**************************************************************************
+void freeAttribute( attr_value_t *attr )
+{
+ switch (attr->kind) {
+ case Sim_Val_Invalid:
+ break;
+
+ case Sim_Val_String:
+ free( (char *) attr->u.string );
+ break;
+
+ case Sim_Val_Integer:
+ break;
+
+ case Sim_Val_Floating:
+ break;
+
+ case Sim_Val_List:
+ for (uint32 i = 0; i < attr->u.list.size; i++) {
+ freeAttribute( &(attr->u.list.vector[i]) );
+ }
+ free( attr->u.list.vector );
+ break;
+
+ default:
+ ERROR_OUT("freeAttr: unknown/unimplemented attribute %d\n", attr->kind);
+ }
+}
+
+/**
+ * Allocates, and initializes a attribute value.
+ * @param number The number of values to allocate.
+ * @return A pointer to the newly allocated structure.
+ */
+//**************************************************************************
+attr_value_t *mallocAttribute( uint32 number )
+{
+ attr_value_t *newattr = (attr_value_t *) malloc( number *
+ sizeof(attr_value_t) );
+ if ( newattr == NULL ) {
+ ERROR_OUT( "confio: mallocAttribute: out of memory\n" );
+ exit(1);
+ }
+ memset( newattr, 0, number*sizeof(attr_value_t) );
+ return (newattr);
+}
+
+
+//**************************************************************************
+void fprintMap( FILE *fp, attr_value_t attr )
+{
+ attr_value_t name;
+ attr_value_t value;
+
+ if (attr.kind != Sim_Val_List)
+ return;
+
+ for (int i = 0; i < attr.u.list.size; i++) {
+
+ if (attr.u.list.vector[i].kind != Sim_Val_List ||
+ attr.u.list.vector[i].u.list.size != 2)
+ return;
+
+ name = attr.u.list.vector[i].u.list.vector[0];
+ value = attr.u.list.vector[i].u.list.vector[1];
+ fprintf( fp, " %s: ", name.u.string);
+ fprintAttr( fp, value );
+ fprintf( fp, "\n");
+ }
+}
+
+/**
+ * write a configuration file: e.g. save state
+ */
+//**************************************************************************
+int confio_t::writeConfiguration( const char *outputFilename )
+{
+ FILE *fp;
+ ConfTable::iterator iter;
+ confnode_t *cfnode;
+ attr_value_t attr;
+
+ memset( &attr, 0, sizeof(attr_value_t) );
+ if ( outputFilename == NULL ) {
+ fp = stdout;
+ } else {
+ fp = fopen( outputFilename, "w" );
+ if ( fp == NULL ) {
+ ERROR_OUT("error: writeConfiguration: unable to open file %s\n",
+ outputFilename );
+ return (-1);
+ }
+ }
+
+ for (iter = m_table.begin(); iter != m_table.end(); iter++) {
+ fprintf( fp, " %s: ", (*iter).first.c_str() );
+ cfnode = (*iter).second;
+ attr = (*(cfnode->get_attr))( cfnode->get_attr_data, NULL );
+ fprintAttr( fp, attr );
+ fprintf(fp, "\n");
+ }
+
+ if ( outputFilename != NULL ) {
+ // wrote to a file: now close it!
+ fclose( fp );
+ }
+ return 0;
+}
+
+/**
+ * read state from an existing configuration file
+ */
+//**************************************************************************
+int confio_t::readConfiguration( const char *inputFilename,
+ const char *relativeIncludePath )
+{
+ // parse the input stream
+ FILE *fp;
+ char relativeFilename[256];
+
+ fp = fopen( inputFilename, "r" );
+ if ( fp == NULL ) {
+ sprintf( relativeFilename, "%s%s", relativeIncludePath, inputFilename );
+ fp = fopen( relativeFilename, "r" );
+ }
+ if ( fp == NULL ) {
+ sprintf( relativeFilename, "%s%s%s", relativeIncludePath, "config/",
+ inputFilename );
+ fp = fopen( relativeFilename, "r" );
+ }
+ if ( fp == NULL ) {
+ ERROR_OUT("error: readConfiguration: unable to open file %s or %s\n",
+ inputFilename, relativeFilename);
+ return (-1);
+ }
+
+ attr_value_t *myattr = mallocAttribute(1);
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parsing conf file\n");
+#endif
+ int rc = parseAttrFile( fp, relativeIncludePath, myattr );
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parse completed\n");
+#endif
+ if ( rc == 0 ) {
+ applyConfiguration( myattr );
+ freeAttribute( myattr );
+ free(myattr);
+ }
+
+ fclose( fp );
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() completed\n");
+#endif
+ return (rc);
+}
+
+/**
+ * read state from a configuration string
+ */
+//**************************************************************************
+int confio_t::readConfigurationString( const char *inputBuffer )
+{
+ if ( inputBuffer == NULL ) {
+ ERROR_OUT( "error: readConfiguration: NULL inputBuffer\n" );
+ return (-1);
+ }
+
+ attr_value_t *myattr = mallocAttribute(1);
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parsing conf string\n");
+#endif
+
+ int rc = parseAttrString( inputBuffer, myattr );
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parse completed\n");
+#endif
+ if ( rc == 0 ) {
+ applyConfiguration( myattr );
+ freeAttribute( myattr );
+ free(myattr);
+ }
+ return (rc);
+}
+
+//**************************************************************************
+void confio_t::checkInitialization( void )
+{
+ ConfTable::iterator iter;
+ confnode_t *cfnode;
+
+ for (iter = m_table.begin(); iter != m_table.end(); iter++) {
+ cfnode = (*iter).second;
+ if ( !cfnode->attr_is_set ) {
+ DEBUG_OUT(" warning: %s is not set in configuration file.\n", (*iter).first.c_str() );
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+/* Private methods */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+int confio_t::applyConfiguration( attr_value_t *attr )
+{
+ confnode_t *cfnode;
+ attr_value_t name;
+ attr_value_t value;
+ set_error_t seterr;
+
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() data in memory\n");
+ fprintMap( stdout, *attr );
+#endif
+
+ // apply the configuration the the m_table
+ if (attr->kind != Sim_Val_List ||
+ attr->u.list.size <= 0) {
+ ERROR_OUT("readconfiguration: internal error #1\n");
+ return -1;
+ }
+
+ for (int i = 0; i < attr->u.list.size; i++) {
+
+ if (attr->u.list.vector[i].kind != Sim_Val_List ||
+ attr->u.list.vector[i].u.list.size != 2) {
+ ERROR_OUT("readconfiguration: illegal configuration kind:%d size:%lld\n",
+ attr->u.list.vector[i].kind,
+ attr->u.list.vector[i].u.list.size);
+ continue;
+ }
+
+ name = attr->u.list.vector[i].u.list.vector[0];
+ value = attr->u.list.vector[i].u.list.vector[1];
+ string newstr((char *) name.u.string);
+ if ( m_table.find(newstr) != m_table.end()) {
+
+ // set the value found in the configuration
+ cfnode = m_table[newstr];
+ seterr = (*cfnode->set_attr)( cfnode->set_attr_data, NULL,
+ &(value) );
+ if ( seterr == Sim_Set_Ok ) {
+ cfnode->attr_is_set = true;
+ if (m_verbose)
+ DEBUG_OUT("configuration set for: %s\n", name.u.string);
+ } else {
+ ERROR_OUT("error: \"%s\" unable to set value: %d\n",
+ name.u.string, (int) seterr);
+ }
+ } else {
+ ERROR_OUT("error: \"%s\" not found. unable to set value.\n",
+ name.u.string);
+ }
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------------*/
+/* Static methods */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Global functions */
+/*------------------------------------------------------------------------*/
+
+
+/** [Memo].
+ * [Internal Documentation]
+ */
+//**************************************************************************
+
diff --git a/src/mem/gems_common/ioutil/confio.hh b/src/mem/gems_common/ioutil/confio.hh
new file mode 100644
index 000000000..143c4da8b
--- /dev/null
+++ b/src/mem/gems_common/ioutil/confio.hh
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1999-2005 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 _CONFIO_H_
+#define _CONFIO_H_
+
+/*------------------------------------------------------------------------*/
+/* Includes */
+/*------------------------------------------------------------------------*/
+
+#include "FakeSimicsDataTypes.hh"
+
+/*------------------------------------------------------------------------*/
+/* Macro declarations */
+/*------------------------------------------------------------------------*/
+
+/// constant for attribute parsing: a (x) single value
+const attr_kind_t CONF_ATTR_SINGLE = (attr_kind_t) (Sim_Val_Object + 1);
+/// constant for attribute parsing: a (x,y) pair of values
+const attr_kind_t CONF_ATTR_PAIR = (attr_kind_t) (Sim_Val_Object + 2);
+
+/*------------------------------------------------------------------------*/
+/* Class declaration(s) */
+/*------------------------------------------------------------------------*/
+
+/*
+ * Functions for modifying the micro-architectural configuation of
+ * a class.
+ */
+
+/// function for getting the configuration value
+typedef attr_value_t (*get_confio_t)( void *ptr, void *obj );
+/// function for setting the configuration value
+typedef set_error_t (*set_confio_t)( void *ptr, void *obj,
+ attr_value_t *value );
+
+/// a struture containing the functional callbacks for each conf node
+typedef struct confnode {
+ get_confio_t get_attr;
+ set_confio_t set_attr;
+ void *set_attr_data;
+ void *get_attr_data;
+ bool attr_is_set;
+} confnode_t;
+
+/// a mapping from a string to a configuration structure
+typedef map<string, confnode_t *> ConfTable;
+
+/**
+* Configuration state saving: allows the user to save the micro-architectural
+* state in a text file for later runs. This file is also used to set
+* globals during simulation.
+*
+* @author cmauer
+* @version $Id$
+*/
+class confio_t {
+
+public:
+
+
+ /**
+ * @name Constructor(s) / destructor
+ */
+ //@{
+
+ /**
+ * Constructor: creates object
+ */
+ confio_t();
+
+ /**
+ * Destructor: frees object.
+ */
+ ~confio_t();
+ //@}
+
+ /**
+ * @name Methods
+ */
+ //@{
+ //@}
+
+ /**
+ * @name Accessor(s) / mutator(s)
+ */
+ //@{
+ /**
+ * register a configuration variable with the configuration manager.
+ * @param get_attr A function to get the attribute value
+ * @param get_attr_data Void pointer, available to get_attr
+ * @param set_attr A function to set the attribute value
+ * @param set_attr_data Void pointer, available to set_attr
+ * @return [Description of return value]
+ */
+ int register_attribute( const char *name,
+ get_confio_t get_attr, void *get_attr_data,
+ set_confio_t set_attr, void *set_attr_data );
+
+ /**
+ * Set verbosity of the configuration
+ * @param verbose True causes more info to be printed out, False doesn't
+ */
+ void setVerbosity( bool verbose ) {
+ m_verbose = verbose;
+ }
+
+ /**
+ * write a configuration file: e.g. save state
+ */
+ int writeConfiguration( const char *outputFilename );
+
+ /**
+ * read state from an existing configuration file
+ * @param inputFilename The file to read
+ * @param relativeIncludePath The path to search on 'include' statements
+ */
+ int readConfiguration( const char *inputFilename,
+ const char *relativeIncludePath );
+
+ /**
+ * read state from a string
+ */
+ int readConfigurationString( const char *inputBuffer );
+
+ /**
+ * check that each registered configuration is set (reports a warning if
+ * they are not.)
+ */
+ void checkInitialization( void );
+ //@}
+
+private:
+ /**
+ * Apply an attribute list to the configuration table
+ */
+ int applyConfiguration( attr_value_t *attr );
+
+ /// configuration table: contains a map from a string -> conf node
+ ConfTable m_table;
+
+ /// if false, nothing is printed under normal operation
+ bool m_verbose;
+};
+
+/*------------------------------------------------------------------------*/
+/* Global variables */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Global functions */
+/*------------------------------------------------------------------------*/
+
+/**
+ * Allocates an array of attributes.
+ */
+attr_value_t *mallocAttribute( uint32 number );
+
+/**
+ * Walks an attribute tree, freeing all memory under attr. Does not free
+ * attr itself.
+ */
+void freeAttribute( attr_value_t *attr );
+
+#endif /* _CONFIO_H_ */
+
+
diff --git a/src/mem/gems_common/ioutil/embedtext.py b/src/mem/gems_common/ioutil/embedtext.py
new file mode 100644
index 000000000..64e1c97f3
--- /dev/null
+++ b/src/mem/gems_common/ioutil/embedtext.py
@@ -0,0 +1,54 @@
+
+import sys
+
+#---------------------------------------------------------------------------
+
+class embedText:
+ """
+ embedText converts a text file into a file that can be embedded in C
+ using an #include statement, that defines a \"const char *\" pointing
+ to the same text.
+
+ This is useful to embed scripts and configuration files in object files.
+ """
+ def __init__(self, filename):
+ self.filename = filename
+ self.escape = [ "\'", "\"", "\\", "\?" ]
+
+ def write(self, outputfile, varname):
+ # reads the text file in, line by line, converting it to a C string
+ fin = open( self.filename, 'r' )
+ fout= open( outputfile, 'w' )
+ fout.write("static const char *%s =\n" % varname);
+ l = " "
+ while l != "":
+ l = fin.readline()
+
+ # add escape sequences for the characters in escape
+ fout.write("\"")
+ for char in l:
+ if char == "\n":
+ break
+ if char in self.escape:
+ fout.write( "\\" )
+ fout.write( char )
+ else:
+ fout.write( char )
+ fout.write("\\n\"\n");
+ fout.write(";\n");
+ fin.close()
+ fout.close()
+
+#---------------------------------------------------------------------------
+
+if __name__ == "__main__":
+ if len(sys.argv) != 4:
+ print len(sys.argv)
+ print "usage:", sys.argv[0], " input-file output-file varname"
+ sys.exit(1)
+ inputfile = sys.argv[1]
+ outputfile = sys.argv[2]
+ varname = sys.argv[3]
+ print "generating embedded text file: %s from %s\n" % (outputfile, inputfile)
+ inc = embedText( inputfile )
+ inc.write( outputfile, varname )
diff --git a/src/mem/gems_common/ioutil/initvar.cc b/src/mem/gems_common/ioutil/initvar.cc
new file mode 100644
index 000000000..9cccdf64b
--- /dev/null
+++ b/src/mem/gems_common/ioutil/initvar.cc
@@ -0,0 +1,626 @@
+/*
+ * Copyright (c) 1999-2005 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.
+ */
+
+/*
+ This file has been modified by Kevin Moore and Dan Nussbaum of the
+ Scalable Systems Research Group at Sun Microsystems Laboratories
+ (http://research.sun.com/scalable/) to support the Adaptive
+ Transactional Memory Test Platform (ATMTP).
+
+ Please send email to atmtp-interest@sun.com with feedback, questions, or
+ to request future announcements about ATMTP.
+
+ ----------------------------------------------------------------------
+
+ File modification date: 2008-02-23
+
+ ----------------------------------------------------------------------
+*/
+
+/*
+ * FileName: initvar.C
+ * Synopsis: implementation of global variable initialization in simics
+ * Author: cmauer
+ * Version: $Id$
+ */
+
+/*------------------------------------------------------------------------*/
+/* Includes */
+/*------------------------------------------------------------------------*/
+
+using namespace std;
+#include <string>
+#include <map>
+#include <stdlib.h>
+
+// Maurice
+// extern "C" {
+// #include "global.hh"
+// #include "simics/api.hh"
+// #ifdef SIMICS22X
+// #include "configuration_api.hh"
+// #endif
+// #ifdef SIMICS30
+// #include "configuration.hh"
+// #endif
+// };
+
+#include "FakeSimicsDataTypes.hh"
+
+#ifdef IS_OPAL
+#include "hfatypes.hh"
+#include "debugio.hh"
+#endif
+
+#ifdef IS_RUBY
+#include "Global.hh"
+#endif
+
+#ifdef IS_TOURMALINE
+#include "Tourmaline_Global.hh"
+#endif
+
+#include "confio.hh"
+#include "initvar.hh"
+
+/*------------------------------------------------------------------------*/
+/* Macro declarations */
+/*------------------------------------------------------------------------*/
+
+#define CONFIG_VAR_FILENAME "config.include"
+
+/*------------------------------------------------------------------------*/
+/* Variable declarations */
+/*------------------------------------------------------------------------*/
+
+// define global "constants" using centralized file
+#define PARAM( NAME ) \
+ int32 NAME;
+#define PARAM_UINT( NAME ) \
+ uint32 NAME;
+#define PARAM_ULONG( NAME ) \
+ uint64 NAME;
+#define PARAM_BOOL( NAME ) \
+ bool NAME;
+#define PARAM_DOUBLE( NAME ) \
+ double NAME;
+#define PARAM_STRING( NAME ) \
+ char *NAME;
+#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \
+ PTYPE NAME[ARRAY_SIZE];
+#include CONFIG_VAR_FILENAME
+#undef PARAM
+#undef PARAM_UINT
+#undef PARAM_ULONG
+#undef PARAM_BOOL
+#undef PARAM_DOUBLE
+#undef PARAM_STRING
+#undef PARAM_ARRAY
+
+/** global initvar object */
+initvar_t *initvar_t::m_inst = NULL;
+
+/*------------------------------------------------------------------------*/
+/* Forward declarations */
+/*------------------------------------------------------------------------*/
+
+static attr_value_t initvar_get_attr( void *ptr, void *obj );
+static set_error_t initvar_set_attr( void *ptr, void *obj,
+ attr_value_t *value );
+
+/*------------------------------------------------------------------------*/
+/* Constructor(s) / destructor */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+initvar_t::initvar_t( const char *name, const char *relativeIncludePath,
+ const char *initializingString,
+ void (*allocate_fn)(void),
+ void (*my_generate_fn)(void),
+ get_attr_t my_get_attr, set_attr_t my_set_attr )
+{
+ m_is_init = false;
+ m_name = (char *) malloc( sizeof(char)*(strlen( name ) + 2) );
+ m_rel_include_path = (char *) malloc( sizeof(char)*(strlen( relativeIncludePath ) + 2) );
+ m_config_filename = NULL;
+ strcpy( m_name, name );
+ strcpy( m_rel_include_path, relativeIncludePath );
+ m_allocate_f = allocate_fn;
+ m_generate_values_f = my_generate_fn;
+ m_my_get_attr = my_get_attr;
+ m_my_set_attr = my_set_attr;
+
+ initvar_t::m_inst = this;
+ init_config_reader( initializingString );
+}
+
+//**************************************************************************
+initvar_t::~initvar_t( )
+{
+#define PARAM( NAME )
+#define PARAM_UINT( NAME )
+#define PARAM_ULONG( NAME )
+#define PARAM_BOOL( NAME )
+#define PARAM_DOUBLE( NAME )
+#define PARAM_STRING( NAME ) \
+ if (NAME != NULL) { \
+ free( NAME ); \
+ NAME = NULL; \
+ }
+#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE )
+#include CONFIG_VAR_FILENAME
+#undef PARAM
+#undef PARAM_UINT
+#undef PARAM_ULONG
+#undef PARAM_BOOL
+#undef PARAM_DOUBLE
+#undef PARAM_STRING
+#undef PARAM_ARRAY
+ if (m_name) {
+ free( m_name );
+ }
+ if (m_rel_include_path) {
+ free( m_rel_include_path );
+ }
+ if (m_config_reader) {
+ delete m_config_reader;
+ }
+ if (m_config_filename) {
+ delete m_config_filename;
+ }
+}
+
+//**************************************************************************
+void initvar_t::init_config_reader( const char *initString )
+{
+ int rc;
+ const char *name;
+
+ m_config_reader = new confio_t();
+ m_config_reader->setVerbosity( false );
+
+ // Initialize the config reader object to identify each parameter
+#define PARAM_UINT PARAM
+#define PARAM_ULONG PARAM
+#define PARAM_BOOL PARAM
+#define PARAM_DOUBLE PARAM
+#define PARAM( NAME ) \
+ name = #NAME; \
+ rc = m_config_reader->register_attribute( name, \
+ initvar_get_attr, (void *) name, \
+ initvar_set_attr, (void *) name );
+#define PARAM_STRING( NAME ) \
+ NAME = NULL; \
+ name = #NAME; \
+ rc = m_config_reader->register_attribute( name, \
+ initvar_get_attr, (void *) name, \
+ initvar_set_attr, (void *) name );
+#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \
+ name = #NAME; \
+ rc = m_config_reader->register_attribute( name, \
+ initvar_get_attr, (void *) name, \
+ initvar_set_attr, (void *) name );
+
+#include CONFIG_VAR_FILENAME
+#undef PARAM
+#undef PARAM_UINT
+#undef PARAM_ULONG
+#undef PARAM_BOOL
+#undef PARAM_DOUBLE
+#undef PARAM_STRING
+#undef PARAM_ARRAY
+
+ // read the default configuration from the embedded text file
+ rc = m_config_reader->readConfigurationString( initString );
+ (*m_generate_values_f)();
+}
+
+/*------------------------------------------------------------------------*/
+/* Public methods */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+void initvar_t::allocate( void )
+{
+ if ( confirm_init() ) {
+ DEBUG_OUT("error: %s initvar::allocate() called twice\n", m_name);
+ return;
+ }
+
+ (*m_generate_values_f)();
+ (*m_allocate_f)();
+ m_is_init = true;
+}
+
+//**************************************************************************
+void initvar_t::checkInitialization( void )
+{
+ m_config_reader->checkInitialization();
+}
+
+//**************************************************************************
+attr_value_t initvar_t::dispatch_get( void *id, void *obj,
+ attr_value_t *idx )
+{
+ const char *command = (const char *) id;
+ if ( !confirm_init() ) {
+ DEBUG_OUT("error: %s is uninitialized. unable to get \'%s\'\n", m_name, command);
+ DEBUG_OUT(" : you must initialize %s with a configuration file first.\n", m_name);
+ DEBUG_OUT(" : use the command \'%s0.init\'\n", m_name);
+
+ attr_value_t ret;
+ ret.kind = Sim_Val_Invalid;
+ ret.u.integer = 0;
+ return ret;
+ }
+
+ return ((*m_my_get_attr)(id, obj, idx));
+}
+
+
+//**************************************************************************
+set_error_t initvar_t::dispatch_set( void *id, void *obj,
+ attr_value_t *val, attr_value_t *idx )
+{
+ const char *command = (const char *) id;
+
+ // DEBUG_OUT("set attribute: %s\n", command);
+ if (!strcmp(command, "init")) {
+ if (val->kind == Sim_Val_String) {
+ if (!strcmp( val->u.string, "" )) {
+ // update generated values, then allocate
+ allocate();
+ } else {
+ read_config( val->u.string );
+ allocate();
+ }
+ return Sim_Set_Ok;
+ } else {
+ return Sim_Set_Need_String;
+ }
+ } else if (!strcmp(command, "readparam")) {
+ if (val->kind == Sim_Val_String) {
+ read_config( val->u.string );
+ return Sim_Set_Ok;
+ } else {
+ return Sim_Set_Need_String;
+ }
+ } else if (!strcmp(command, "saveparam")) {
+ if (val->kind == Sim_Val_String) {
+ FILE *fp = fopen( val->u.string, "w" );
+ if (fp == NULL) {
+ ERROR_OUT("error: unable to open file: %s\n", val->u.string);
+ return Sim_Set_Illegal_Value;
+ }
+ list_param( fp );
+ if (fp != NULL) {
+ fclose( fp );
+ }
+ return Sim_Set_Ok;
+ } else {
+ ERROR_OUT("error: saveparam given wrong type.\n");
+ return Sim_Set_Illegal_Value;
+ }
+ } else if (!strcmp(command, "param")) {
+ if (val->kind == Sim_Val_Integer) {
+ list_param( stdout );
+ return Sim_Set_Ok;
+ } else if ( val->kind == Sim_Val_List &&
+ val->u.list.size == 2 &&
+ val->u.list.vector[0].kind == Sim_Val_String ) {
+ return (set_param( val->u.list.vector[0].u.string,
+ &val->u.list.vector[1] ));
+ } else {
+ DEBUG_OUT("error: set parameter given wrong type.\n");
+ return Sim_Set_Illegal_Value;
+ }
+ }
+
+ if ( !confirm_init() ) {
+ DEBUG_OUT("error: %s is uninitialized. unable to set \'%s\'\n", m_name, id);
+ DEBUG_OUT(" : you must initialize %s with a configuration file first.\n", m_name);
+ DEBUG_OUT(" : use the command \'%s0.init\'\n", m_name);
+ return Sim_Set_Illegal_Value;
+ }
+
+ return (*m_my_set_attr)( id, obj, val, idx );
+}
+
+/*------------------------------------------------------------------------*/
+/* Accessor(s) / mutator(s) */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Private methods */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Static methods */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+static attr_value_t initvar_get_attr( void *ptr, void *obj )
+{
+ const char *name = (const char *) ptr;
+ attr_value_t ret;
+ memset( &ret, 0, sizeof(attr_value_t) );
+
+#define PARAM_UINT PARAM
+#define PARAM_ULONG PARAM
+#define PARAM_BOOL PARAM
+#define PARAM( NAME ) \
+ if (!strcmp(name, #NAME)) { \
+ ret.kind = Sim_Val_Integer; \
+ ret.u.integer = NAME; \
+ return (ret); \
+ }
+#define PARAM_DOUBLE( NAME ) \
+ if (!strcmp(name, #NAME)) { \
+ ret.kind = Sim_Val_Floating; \
+ ret.u.floating = NAME; \
+ return (ret); \
+ }
+#define PARAM_STRING( NAME ) \
+ if (!strcmp(name, #NAME)) { \
+ ret.kind = Sim_Val_String; \
+ ret.u.string = NAME; \
+ return (ret); \
+ }
+#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \
+ if (!strcmp(name, #NAME)) { \
+ ret.kind = Sim_Val_List; \
+ ret.u.list.size = ARRAY_SIZE; \
+ ret.u.list.vector = mallocAttribute( ARRAY_SIZE ); \
+ for (int i = 0; i < ARRAY_SIZE; i++) { \
+ ret.u.list.vector[i].u.integer = NAME[i]; \
+ } \
+ return (ret); \
+ }
+
+#include CONFIG_VAR_FILENAME
+#undef PARAM
+#undef PARAM_UINT
+#undef PARAM_ULONG
+#undef PARAM_BOOL
+#undef PARAM_DOUBLE
+#undef PARAM_STRING
+#undef PARAM_ARRAY
+
+ DEBUG_OUT("error: %s not found.\n", name);
+ ret.kind = Sim_Val_Invalid;
+ return (ret);
+}
+
+//***************************************************************************
+static set_error_t initvar_set_attr( void *ptr, void *obj,
+ attr_value_t *value )
+{
+ const char *name = (const char *) ptr;
+
+#define PARAM_UINT PARAM
+#define PARAM_ULONG PARAM
+#define PARAM( NAME ) \
+ if (!strcmp(name, #NAME)) { \
+ if ( value->kind != Sim_Val_Integer ) { \
+ ERROR_OUT("error: %s is not an integer\n", name );\
+ return Sim_Set_Need_Integer; \
+ } \
+ NAME = value->u.integer; \
+ return Sim_Set_Ok; \
+ }
+#define PARAM_BOOL( NAME ) \
+ if (!strcmp(name, #NAME)) { \
+ if ( value->kind != Sim_Val_String ) { \
+ ERROR_OUT("error: %s is not an bool string\n", name );\
+ return Sim_Set_Need_String; \
+ } \
+ if (!strcmp(value->u.string, "true")) { \
+ NAME = true; \
+ } else if (!strcmp(value->u.string, "false")) { \
+ NAME = false; \
+ } else { \
+ ERROR_OUT("error: value %s for %s is not an bool string (set to false)\n", value->u.string, name );\
+ NAME = false; \
+ } \
+ return Sim_Set_Ok; \
+ }
+#define PARAM_DOUBLE( NAME ) \
+ if (!strcmp(name, #NAME)) { \
+ if ( value->kind != Sim_Val_String ) { \
+ ERROR_OUT("error: %s is not a float\n", name );\
+ return Sim_Set_Need_Floating; \
+ } \
+ NAME = atof( value->u.string ); \
+ return Sim_Set_Ok; \
+ }
+#define PARAM_STRING( NAME ) \
+ if (!strcmp(name, #NAME)) { \
+ if ( value->kind != Sim_Val_String ) { \
+ ERROR_OUT("error: %s is not an string\n", name ); \
+ return Sim_Set_Need_String; \
+ } \
+ if (NAME != NULL) { \
+ free( NAME ); \
+ } \
+ NAME = strdup( value->u.string ); \
+ return Sim_Set_Ok; \
+ }
+#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \
+ if (!strcmp(name, #NAME)) { \
+ if ( value->kind != Sim_Val_List ) { \
+ ERROR_OUT("error: %s is not an list\n", name ); \
+ return Sim_Set_Need_List; \
+ } \
+ if ( value->u.list.size != ARRAY_SIZE ) { \
+ ERROR_OUT("error: %s has %lld elements (should be %d)\n", name, value->u.list.size, ARRAY_SIZE); \
+ return Sim_Set_Illegal_Value; \
+ } \
+ for (int i = 0; i < ARRAY_SIZE; i++) { \
+ NAME[i] = value->u.list.vector[i].u.integer; \
+ } \
+ return Sim_Set_Ok; \
+ }
+
+#include CONFIG_VAR_FILENAME
+#undef PARAM
+#undef PARAM_UINT
+#undef PARAM_ULONG
+#undef PARAM_BOOL
+#undef PARAM_DOUBLE
+#undef PARAM_STRING
+#undef PARAM_ARRAY
+
+ ERROR_OUT("error: %s not a parameter\n", name);
+ return Sim_Set_Illegal_Value;
+}
+
+//***************************************************************************
+void initvar_t::read_config( const char *parameterFile )
+{
+ DEBUG_OUT("read configuration: %s\n", parameterFile );
+ m_config_filename = strdup( parameterFile );
+ int rc = m_config_reader->readConfiguration( parameterFile,
+ m_rel_include_path );
+ if ( rc < 0 ) {
+ ERROR_OUT("fatal error in read configuration: unable to continue.\n");
+ exit(1);
+ }
+ // update generated values
+ (*m_generate_values_f)();
+}
+
+/** sets one of the parameters */
+//**************************************************************************
+set_error_t initvar_t::set_param( const char *name, attr_value_t *value )
+{
+
+ // [dann 2007-04-04] ATMTP VV
+ //
+ // HACK ALERT: allow setting REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH,
+ // PROFILE_EXCEPTIONS, PROFILE_XACT, ATMTP_DEBUG_LEVEL and
+ // ATMTP_ENABLED after initialization. This works is because ruby's
+ // m_generate_values_f() does nothing -- more particularly, nothing
+ // that depends on any of these parameters is pre-calculated
+ // anywhere.
+ //
+ if (strcmp(name, "REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH") != 0 &&
+ strcmp(name, "PROFILE_EXCEPTIONS") != 0 &&
+ strcmp(name, "PROFILE_XACT") != 0 &&
+ strcmp(name, "ATMTP_DEBUG_LEVEL") != 0 &&
+ strcmp(name, "ATMTP_ENABLED") != 0) {
+ //
+ // [dann 2007-04-04] ATMTP ^^
+ if ( confirm_init() ) {
+ DEBUG_OUT("error: %s is already initialized.\n", m_name);
+ DEBUG_OUT(" : setting parameters after initialization is unsupported\n");
+ return (Sim_Set_Illegal_Value);
+ }
+ // [dann 2007-04-04] ATMTP VV
+ //
+ }
+ //
+ // [dann 2007-04-04] ATMTP ^^
+
+ set_error_t result = initvar_set_attr( (void *) name, NULL, value );
+ (*m_generate_values_f)();
+ return (result);
+}
+
+/** print out a list of valid parameters */
+//**************************************************************************
+void initvar_t::list_param( FILE *fp )
+{
+ if (!fp)
+ fp = stdout;
+
+#define PARAM( NAME ) \
+ fprintf( fp, "%-44.44s: %26d\n", #NAME, NAME );
+#define PARAM_UINT( NAME ) \
+ fprintf( fp, "%-44.44s: %26u\n", #NAME, NAME );
+#define PARAM_ULONG( NAME ) \
+ fprintf( fp, "%-44.44s: %26llu\n", #NAME, NAME );
+#define PARAM_BOOL( NAME ) \
+ if (NAME == true) { \
+ fprintf( fp, "%-44.44s: %26.26s\n", #NAME, "true" ); \
+ } else { \
+ fprintf( fp, "%-44.44s: %26.26s\n", #NAME, "false" );\
+ }
+#define PARAM_DOUBLE( NAME ) \
+ fprintf( fp, "%-44.44s: %26f\n", #NAME, NAME );
+#define PARAM_STRING( NAME ) \
+ if ( NAME != NULL ) { \
+ fprintf( fp, "%-44.44s: %26.26s\n", #NAME, NAME ); \
+ }
+#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \
+ fprintf( fp, "%-44.44s: (", #NAME ); \
+ for (int i = 0; i < ARRAY_SIZE; i++) { \
+ if ( i != 0 ) { \
+ fprintf( fp, ", " ); \
+ } \
+ fprintf( fp, "%d", NAME[i] ); \
+ } \
+ fprintf( fp, ")\n" );
+
+#include CONFIG_VAR_FILENAME
+#undef PARAM
+#undef PARAM_UINT
+#undef PARAM_ULONG
+#undef PARAM_BOOL
+#undef PARAM_DOUBLE
+#undef PARAM_STRING
+#undef PARAM_ARRAY
+}
+
+//**************************************************************************
+const char *initvar_t::get_config_name( void )
+{
+ if (m_config_filename == NULL) {
+ return "default";
+ }
+ return m_config_filename;
+}
+
+/*------------------------------------------------------------------------*/
+/* Global functions */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+attr_value_t initvar_dispatch_get( void *id, void *obj,
+ attr_value_t *idx )
+{
+ initvar_t *init_obj = initvar_t::m_inst;
+ return (init_obj->dispatch_get( id, obj, idx ));
+}
+
+//**************************************************************************
+set_error_t initvar_dispatch_set( void *id, void *obj,
+ attr_value_t *val, attr_value_t *idx )
+{
+ initvar_t *init_obj = initvar_t::m_inst;
+ return (init_obj->dispatch_set( id, obj, val, idx ));
+}
diff --git a/src/mem/gems_common/ioutil/initvar.hh b/src/mem/gems_common/ioutil/initvar.hh
new file mode 100644
index 000000000..8dea8dfc1
--- /dev/null
+++ b/src/mem/gems_common/ioutil/initvar.hh
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 1999-2005 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 _INCLUDE_H_
+#define _INCLUDE_H_
+
+/*------------------------------------------------------------------------*/
+/* Includes */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Macro declarations */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Class declaration(s) */
+/*------------------------------------------------------------------------*/
+
+/**
+* This class deals with initializing the global variables in the object,
+* setting the varibles (from the command line), printing the configuration,
+* and saving it to a file.
+*
+* Before including this file, you must define the variable CONFIG_VAR_FILENAME
+* to define which variables are to be used.
+*
+* @see confio_t
+* @author cmauer
+* @version $Id$
+*/
+class initvar_t {
+public:
+ /**
+ * @name Constructor(s) / destructor
+ */
+ //@{
+
+ /**
+ * Constructor: creates object
+ * @param name The name of this object
+ * @param relativeIncludePath The relative path to config files
+ * @param initializingString A string (with value pairs) for initialization
+ * @param allocate_f A ptr to the allocate function
+ * @param generate_values A ptr to the generate values function
+ * @param my_get_attr A ptr to the get attribute function
+ * @param my_set_attr A ptr to the set attribute function
+ */
+ initvar_t( const char *name, const char *relativeIncludePath,
+ const char *initializingString,
+ void (*allocate_fn)(void),
+ void (*my_generate_fn)(void),
+ get_attr_t my_get_attr, set_attr_t my_set_attr );
+
+ /**
+ * Destructor: frees object.
+ */
+ ~initvar_t();
+ //@}
+
+ /**
+ * @name Methods
+ */
+ //@{
+ /// calls the allocation routine explicitly (used by the tester)
+ void allocate( void );
+
+ /// checks to see if all vars have been initialized
+ void checkInitialization( void );
+
+ /// list all parameters: to a file (or stdout if file is NULL)
+ void list_param( FILE *fp );
+
+ /// returns the name of the last config file to be read ("default" is none)
+ const char *get_config_name( void );
+
+ /// calls through to the get_attr function, if object is initialized
+ attr_value_t dispatch_get( void *id, void *obj,
+ attr_value_t *idx );
+
+ /** adds initialization attributes, calls through to the set_attr function,
+ * if object is initialized.
+ */
+ set_error_t dispatch_set( void *id, void *obj,
+ attr_value_t *val, attr_value_t *idx );
+ //@}
+ /// (single) instance of the init var object
+ static initvar_t *m_inst;
+
+protected:
+ ///returns true if the variables are initialized
+ bool confirm_init( void ) {
+ return m_is_init;
+ }
+
+ ///read a configuration file
+ void read_config( const char *parameterFile );
+
+ /// set a parameter to be a particular value
+ set_error_t set_param( const char *name, attr_value_t *value );
+
+ /// initializes the configuration reader
+ void init_config_reader( const char *initString );
+
+ /// bool value (true if initialized)
+ bool m_is_init;
+
+ /// configuration reader
+ confio_t *m_config_reader;
+
+ /// a pointer to a string (corresponding to this objects name)
+ char *m_name;
+
+ /// a pointer to a string (representing the last config file read)
+ char *m_config_filename;
+
+ /// the relative include path to the configuration files
+ char *m_rel_include_path;
+
+ /// a pointer to the allocation function
+ void (*m_allocate_f)(void);
+
+ /// a pointer to the generate values function
+ void (*m_generate_values_f)(void);
+
+ /// a pointer to the session get function
+ get_attr_t m_my_get_attr;
+ /// a pointer to the session set function
+ set_attr_t m_my_set_attr;
+};
+
+
+/*------------------------------------------------------------------------*/
+/* Global variables */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Global functions */
+/*------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///provides a dispatch mechanism that catches a few commands to get variables
+attr_value_t initvar_dispatch_get( void *id, void *obj,
+ attr_value_t *idx );
+
+///provides a dispatch mechanism that catches a few commands to set variables
+set_error_t initvar_dispatch_set( void *id, void *obj,
+ attr_value_t *val, attr_value_t *idx );
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* _INCLUDE_H_ */
diff --git a/src/mem/gems_common/ioutil/vardecl.hh b/src/mem/gems_common/ioutil/vardecl.hh
new file mode 100644
index 000000000..21bc62d02
--- /dev/null
+++ b/src/mem/gems_common/ioutil/vardecl.hh
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1999-2005 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 _VARDECL_H_
+#define _VARDECL_H_
+
+/*------------------------------------------------------------------------*/
+/* Includes */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Macro declarations */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Class declaration(s) */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Global variables */
+/*------------------------------------------------------------------------*/
+
+#define PARAM( NAME ) \
+ extern int32 NAME;
+#define PARAM_UINT( NAME ) \
+ extern uint32 NAME;
+#define PARAM_ULONG( NAME ) \
+ extern uint64 NAME;
+#define PARAM_BOOL( NAME ) \
+ extern bool NAME;
+#define PARAM_DOUBLE( NAME ) \
+ extern double NAME;
+#define PARAM_STRING( NAME ) \
+ extern char *NAME;
+#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \
+ extern PTYPE NAME[ARRAY_SIZE];
+#include CONFIG_VAR_FILENAME
+#undef PARAM
+#undef PARAM_UINT
+#undef PARAM_ULONG
+#undef PARAM_BOOL
+#undef PARAM_DOUBLE
+#undef PARAM_STRING
+#undef PARAM_ARRAY
+
+/*------------------------------------------------------------------------*/
+/* Global functions */
+/*------------------------------------------------------------------------*/
+
+#endif /* _VARDECL_H_ */
diff --git a/src/mem/gems_common/std-includes.hh b/src/mem/gems_common/std-includes.hh
new file mode 100644
index 000000000..619214f1d
--- /dev/null
+++ b/src/mem/gems_common/std-includes.hh
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1999-2005 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 INCLUDES_H
+#define INCLUDES_H
+
+#include <cstring>
+#include <iomanip>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <ext/hash_map>
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <cassert>
+
+using namespace std;
+using namespace __gnu_cxx;
+
+#endif //INCLUDES_H
diff --git a/src/mem/gems_common/util.cc b/src/mem/gems_common/util.cc
new file mode 100644
index 000000000..c5b8f22b5
--- /dev/null
+++ b/src/mem/gems_common/util.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1999-2005 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 "assert.h"
+#include "util.hh"
+
+// Split a string into a head and tail strings on the specified
+// character. Return the head and the string passed in is modified by
+// removing the head, leaving just the tail.
+
+string string_split(string& str, char split_character)
+{
+ string head = "";
+ string tail = "";
+
+ uint counter = 0;
+ while(counter < str.size()) {
+ if (str[counter] == split_character) {
+ counter++;
+ break;
+ } else {
+ head += str[counter];
+ }
+ counter++;
+ }
+
+ while(counter < str.size()) {
+ tail += str[counter];
+ counter++;
+ }
+ str = tail;
+ return head;
+}
+
+string bool_to_string(bool value)
+{
+ if (value) {
+ return "true";
+ } else {
+ return "false";
+ }
+}
+
+string int_to_string(int n, bool zero_fill, int width)
+{
+ ostringstream sstr;
+ if(zero_fill) {
+ sstr << setw(width) << setfill('0') << n;
+ } else {
+ sstr << n;
+ }
+ string str = sstr.str();
+ return str;
+}
+
+float string_to_float(string& str)
+{
+ stringstream sstr(str);
+ float ret;
+ sstr >> ret;
+ return ret;
+}
+
+// Log functions
+int log_int(long long n)
+{
+ assert(n > 0);
+ int counter = 0;
+ while (n >= 2) {
+ counter++;
+ n = n>>(long long)(1);
+ }
+ return counter;
+}
+
+bool is_power_of_2(long long n)
+{
+ return (n == ((long long)(1) << log_int(n)));
+}
+
diff --git a/src/mem/gems_common/util.hh b/src/mem/gems_common/util.hh
new file mode 100644
index 000000000..d9e9fec3e
--- /dev/null
+++ b/src/mem/gems_common/util.hh
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1999-2005 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 UTIL_H
+#define UTIL_H
+
+#include "std-includes.hh"
+
+string string_split(string& str, char split_character);
+string bool_to_string(bool value);
+string int_to_string(int n, bool zero_fill = false, int width = 0);
+float string_to_float(string& str);
+int log_int(long long n);
+bool is_power_of_2(long long n);
+
+// Min and Max functions (since they are extern inline, they are as
+// fast as macros)
+
+extern inline
+int max(int n1, int n2)
+{
+ if (n1 > n2) {
+ return n1;
+ } else {
+ return n2;
+ }
+}
+
+extern inline
+int min(int n1, int n2)
+{
+ if (n1 < n2) {
+ return n1;
+ } else {
+ return n2;
+ }
+}
+
+#endif //UTIL_H