cpu: Remove the "SingleThreaded" fetch policy from the O3 CPU.
[gem5.git] / src / cpu / timebuf.hh
1 /*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef __BASE_TIMEBUF_HH__
30 #define __BASE_TIMEBUF_HH__
31
32 #include <cassert>
33 #include <cstring>
34 #include <vector>
35
36 template <class T>
37 class TimeBuffer
38 {
39 protected:
40 int past;
41 int future;
42 unsigned size;
43 int _id;
44
45 char *data;
46 std::vector<char *> index;
47 unsigned base;
48
49 void valid(int idx) const
50 {
51 assert (idx >= -past && idx <= future);
52 }
53
54 public:
55 friend class wire;
56 class wire
57 {
58 friend class TimeBuffer;
59 protected:
60 TimeBuffer<T> *buffer;
61 int index;
62
63 void set(int idx)
64 {
65 buffer->valid(idx);
66 index = idx;
67 }
68
69 wire(TimeBuffer<T> *buf, int i)
70 : buffer(buf), index(i)
71 { }
72
73 public:
74 wire()
75 { }
76
77 wire(const wire &i)
78 : buffer(i.buffer), index(i.index)
79 { }
80
81 const wire &operator=(const wire &i)
82 {
83 buffer = i.buffer;
84 set(i.index);
85 return *this;
86 }
87
88 const wire &operator=(int idx)
89 {
90 set(idx);
91 return *this;
92 }
93
94 const wire &operator+=(int offset)
95 {
96 set(index + offset);
97 return *this;
98 }
99
100 const wire &operator-=(int offset)
101 {
102 set(index - offset);
103 return *this;
104 }
105
106 wire &operator++()
107 {
108 set(index + 1);
109 return *this;
110 }
111
112 wire &operator++(int)
113 {
114 int i = index;
115 set(index + 1);
116 return wire(this, i);
117 }
118
119 wire &operator--()
120 {
121 set(index - 1);
122 return *this;
123 }
124
125 wire &operator--(int)
126 {
127 int i = index;
128 set(index - 1);
129 return wire(this, i);
130 }
131 T &operator*() const { return *buffer->access(index); }
132 T *operator->() const { return buffer->access(index); }
133 };
134
135
136 public:
137 TimeBuffer(int p, int f)
138 : past(p), future(f), size(past + future + 1),
139 data(new char[size * sizeof(T)]), index(size), base(0)
140 {
141 assert(past >= 0 && future >= 0);
142 char *ptr = data;
143 for (unsigned i = 0; i < size; i++) {
144 index[i] = ptr;
145 std::memset(ptr, 0, sizeof(T));
146 new (ptr) T;
147 ptr += sizeof(T);
148 }
149
150 _id = -1;
151 }
152
153 TimeBuffer()
154 : data(NULL)
155 {
156 }
157
158 ~TimeBuffer()
159 {
160 for (unsigned i = 0; i < size; ++i)
161 (reinterpret_cast<T *>(index[i]))->~T();
162 delete [] data;
163 }
164
165 void id(int id)
166 {
167 _id = id;
168 }
169
170 int id()
171 {
172 return _id;
173 }
174
175 void
176 advance()
177 {
178 if (++base >= size)
179 base = 0;
180
181 int ptr = base + future;
182 if (ptr >= (int)size)
183 ptr -= size;
184 (reinterpret_cast<T *>(index[ptr]))->~T();
185 std::memset(index[ptr], 0, sizeof(T));
186 new (index[ptr]) T;
187 }
188
189 protected:
190 //Calculate the index into this->index for element at position idx
191 //relative to now
192 inline int calculateVectorIndex(int idx) const
193 {
194 //Need more complex math here to calculate index.
195 valid(idx);
196
197 int vector_index = idx + base;
198 if (vector_index >= (int)size) {
199 vector_index -= size;
200 } else if (vector_index < 0) {
201 vector_index += size;
202 }
203
204 return vector_index;
205 }
206
207 public:
208 T *access(int idx)
209 {
210 int vector_index = calculateVectorIndex(idx);
211
212 return reinterpret_cast<T *>(index[vector_index]);
213 }
214
215 T &operator[](int idx)
216 {
217 int vector_index = calculateVectorIndex(idx);
218
219 return reinterpret_cast<T &>(*index[vector_index]);
220 }
221
222 const T &operator[] (int idx) const
223 {
224 int vector_index = calculateVectorIndex(idx);
225
226 return reinterpret_cast<const T &>(*index[vector_index]);
227 }
228
229 wire getWire(int idx)
230 {
231 valid(idx);
232
233 return wire(this, idx);
234 }
235
236 wire zero()
237 {
238 return wire(this, 0);
239 }
240
241 unsigned getSize()
242 {
243 return size;
244 }
245 };
246
247 #endif // __BASE_TIMEBUF_HH__
248