Merge zizzer.eecs.umich.edu:/bk/newmem/
[gem5.git] / src / arch / sparc / regfile.cc
1 /*
2 * Copyright (c) 2003-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 * Authors: Gabe Black
29 * Ali Saidi
30 */
31
32 #include "arch/sparc/regfile.hh"
33 #include "cpu/thread_context.hh"
34
35 class Checkpoint;
36
37 using namespace SparcISA;
38 using namespace std;
39
40 //RegFile class methods
41 Addr RegFile::readPC()
42 {
43 return pc;
44 }
45
46 void RegFile::setPC(Addr val)
47 {
48 pc = val;
49 }
50
51 Addr RegFile::readNextPC()
52 {
53 return npc;
54 }
55
56 void RegFile::setNextPC(Addr val)
57 {
58 npc = val;
59 }
60
61 Addr RegFile::readNextNPC()
62 {
63 return nnpc;
64 }
65
66 void RegFile::setNextNPC(Addr val)
67 {
68 nnpc = val;
69 }
70
71 void RegFile::clear()
72 {
73 intRegFile.clear();
74 floatRegFile.clear();
75 }
76
77 MiscReg RegFile::readMiscReg(int miscReg)
78 {
79 return miscRegFile.readReg(miscReg);
80 }
81
82 MiscReg RegFile::readMiscRegWithEffect(int miscReg, ThreadContext *tc)
83 {
84 return miscRegFile.readRegWithEffect(miscReg, tc);
85 }
86
87 void RegFile::setMiscReg(int miscReg, const MiscReg &val)
88 {
89 miscRegFile.setReg(miscReg, val);
90 }
91
92 void RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
93 ThreadContext * tc)
94 {
95 miscRegFile.setRegWithEffect(miscReg, val, tc);
96 }
97
98 FloatReg RegFile::readFloatReg(int floatReg, int width)
99 {
100 return floatRegFile.readReg(floatReg, width);
101 }
102
103 FloatReg RegFile::readFloatReg(int floatReg)
104 {
105 //Use the "natural" width of a single float
106 return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
107 }
108
109 FloatRegBits RegFile::readFloatRegBits(int floatReg, int width)
110 {
111 return floatRegFile.readRegBits(floatReg, width);
112 }
113
114 FloatRegBits RegFile::readFloatRegBits(int floatReg)
115 {
116 //Use the "natural" width of a single float
117 return floatRegFile.readRegBits(floatReg,
118 FloatRegFile::SingleWidth);
119 }
120
121 void RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
122 {
123 floatRegFile.setReg(floatReg, val, width);
124 }
125
126 void RegFile::setFloatReg(int floatReg, const FloatReg &val)
127 {
128 //Use the "natural" width of a single float
129 setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
130 }
131
132 void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
133 {
134 floatRegFile.setRegBits(floatReg, val, width);
135 }
136
137 void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
138 {
139 //Use the "natural" width of a single float
140 floatRegFile.setRegBits(floatReg, val, FloatRegFile::SingleWidth);
141 }
142
143 IntReg RegFile::readIntReg(int intReg)
144 {
145 return intRegFile.readReg(intReg);
146 }
147
148 void RegFile::setIntReg(int intReg, const IntReg &val)
149 {
150 intRegFile.setReg(intReg, val);
151 }
152
153 void RegFile::serialize(std::ostream &os)
154 {
155 intRegFile.serialize(os);
156 floatRegFile.serialize(os);
157 miscRegFile.serialize(os);
158 SERIALIZE_SCALAR(pc);
159 SERIALIZE_SCALAR(npc);
160 }
161
162 void RegFile::unserialize(Checkpoint *cp, const std::string &section)
163 {
164 intRegFile.unserialize(cp, section);
165 floatRegFile.unserialize(cp, section);
166 miscRegFile.unserialize(cp, section);
167 UNSERIALIZE_SCALAR(pc);
168 UNSERIALIZE_SCALAR(npc);
169 }
170
171 void RegFile::changeContext(RegContextParam param, RegContextVal val)
172 {
173 switch(param)
174 {
175 case CONTEXT_CWP:
176 intRegFile.setCWP(val);
177 break;
178 case CONTEXT_GLOBALS:
179 intRegFile.setGlobals(val);
180 break;
181 default:
182 panic("Tried to set illegal context parameter in the SPARC regfile.\n");
183 }
184 }
185
186 int SparcISA::InterruptLevel(uint64_t softint)
187 {
188 if (softint & 0x10000 || softint & 0x1)
189 return 14;
190
191 int level = 14;
192 while (level >= 0 && !(1 << (level + 1) & softint))
193 level--;
194 if (1 << (level + 1) & softint)
195 return level;
196 return 0;
197 }
198
199 void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
200 {
201
202 uint8_t tl = src->readMiscReg(MISCREG_TL);
203
204 // Read all the trap level dependent registers and save them off
205 for(int i = 1; i <= MaxTL; i++)
206 {
207 src->setMiscReg(MISCREG_TL, i);
208 dest->setMiscReg(MISCREG_TL, i);
209
210 dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT));
211 dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC));
212 dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC));
213 dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE));
214 }
215
216 // Save off the traplevel
217 dest->setMiscReg(MISCREG_TL, tl);
218 src->setMiscReg(MISCREG_TL, tl);
219
220
221 // ASRs
222 dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
223 dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
224 dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
225 dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
226 dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
227 dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT));
228 dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR));
229 dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK));
230 dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR));
231
232 // Priv Registers
233 dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
234 dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA));
235 dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
236 dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
237 dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
238 dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
239 dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
240 dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
241 dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
242 dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
243 dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
244
245 // Hyperprivilged registers
246 dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE));
247 dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP));
248 dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA));
249 dest->setMiscReg(MISCREG_STRAND_STS_REG,
250 src->readMiscReg(MISCREG_STRAND_STS_REG));
251 dest->setMiscReg(MISCREG_HSTICK_CMPR,
252 src->readMiscReg(MISCREG_HSTICK_CMPR));
253
254 // FSR
255 dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR));
256 }
257
258 void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
259 {
260 // First loop through the integer registers.
261 for (int i = 0; i < TheISA::NumIntRegs; ++i) {
262 dest->setIntReg(i, src->readIntReg(i));
263 }
264
265 // Then loop through the floating point registers.
266 for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
267 dest->setFloatRegBits(i, src->readFloatRegBits(i));
268 }
269
270 // Copy misc. registers
271 copyMiscRegs(src, dest);
272
273 // Lastly copy PC/NPC
274 dest->setPC(src->readPC());
275 dest->setNextPC(src->readNextPC());
276 dest->setNextNPC(src->readNextNPC());
277 }