summaryrefslogtreecommitdiff
path: root/src/mem/gems_common
diff options
context:
space:
mode:
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