Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/m5
[gem5.git] / cpu / o3 / alpha_dyn_inst.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 __CPU_O3_CPU_ALPHA_DYN_INST_HH__
30 #define __CPU_O3_CPU_ALPHA_DYN_INST_HH__
31
32 #include "cpu/base_dyn_inst.hh"
33 #include "cpu/o3/alpha_cpu.hh"
34 #include "cpu/o3/alpha_impl.hh"
35 #include "cpu/inst_seq.hh"
36
37 /**
38 * Mostly implementation specific AlphaDynInst. It is templated in case there
39 * are other implementations that are similar enough to be able to use this
40 * class without changes. This is mainly useful if there are multiple similar
41 * CPU implementations of the same ISA.
42 */
43
44 template <class Impl>
45 class AlphaDynInst : public BaseDynInst<Impl>
46 {
47 public:
48 /** Typedef for the CPU. */
49 typedef typename Impl::FullCPU FullCPU;
50
51 /** Binary machine instruction type. */
52 typedef TheISA::MachInst MachInst;
53 /** Logical register index type. */
54 typedef TheISA::RegIndex RegIndex;
55 /** Integer register index type. */
56 typedef TheISA::IntReg IntReg;
57
58 enum {
59 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
60 MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
61 };
62
63 public:
64 /** BaseDynInst constructor given a binary instruction. */
65 AlphaDynInst(MachInst inst, Addr PC, Addr Pred_PC, InstSeqNum seq_num,
66 FullCPU *cpu);
67
68 /** BaseDynInst constructor given a static inst pointer. */
69 AlphaDynInst(StaticInstPtr &_staticInst);
70
71 /** Executes the instruction.*/
72 Fault execute()
73 {
74 return this->fault = this->staticInst->execute(this, this->traceData);
75 }
76
77 public:
78 uint64_t readUniq();
79 void setUniq(uint64_t val);
80
81 uint64_t readFpcr();
82 void setFpcr(uint64_t val);
83
84 #if FULL_SYSTEM
85 uint64_t readIpr(int idx, Fault &fault);
86 Fault setIpr(int idx, uint64_t val);
87 Fault hwrei();
88 int readIntrFlag();
89 void setIntrFlag(int val);
90 bool inPalMode();
91 void trap(Fault fault);
92 bool simPalCheck(int palFunc);
93 #else
94 void syscall();
95 #endif
96
97
98
99 private:
100 /** Physical register index of the destination registers of this
101 * instruction.
102 */
103 PhysRegIndex _destRegIdx[MaxInstDestRegs];
104
105 /** Physical register index of the source registers of this
106 * instruction.
107 */
108 PhysRegIndex _srcRegIdx[MaxInstSrcRegs];
109
110 /** Physical register index of the previous producers of the
111 * architected destinations.
112 */
113 PhysRegIndex _prevDestRegIdx[MaxInstDestRegs];
114
115 public:
116
117 // The register accessor methods provide the index of the
118 // instruction's operand (e.g., 0 or 1), not the architectural
119 // register index, to simplify the implementation of register
120 // renaming. We find the architectural register index by indexing
121 // into the instruction's own operand index table. Note that a
122 // raw pointer to the StaticInst is provided instead of a
123 // ref-counted StaticInstPtr to redice overhead. This is fine as
124 // long as these methods don't copy the pointer into any long-term
125 // storage (which is pretty hard to imagine they would have reason
126 // to do).
127
128 uint64_t readIntReg(const StaticInst *si, int idx)
129 {
130 return this->cpu->readIntReg(_srcRegIdx[idx]);
131 }
132
133 float readFloatRegSingle(const StaticInst *si, int idx)
134 {
135 return this->cpu->readFloatRegSingle(_srcRegIdx[idx]);
136 }
137
138 double readFloatRegDouble(const StaticInst *si, int idx)
139 {
140 return this->cpu->readFloatRegDouble(_srcRegIdx[idx]);
141 }
142
143 uint64_t readFloatRegInt(const StaticInst *si, int idx)
144 {
145 return this->cpu->readFloatRegInt(_srcRegIdx[idx]);
146 }
147
148 /** @todo: Make results into arrays so they can handle multiple dest
149 * registers.
150 */
151 void setIntReg(const StaticInst *si, int idx, uint64_t val)
152 {
153 this->cpu->setIntReg(_destRegIdx[idx], val);
154 this->instResult.integer = val;
155 }
156
157 void setFloatRegSingle(const StaticInst *si, int idx, float val)
158 {
159 this->cpu->setFloatRegSingle(_destRegIdx[idx], val);
160 this->instResult.fp = val;
161 }
162
163 void setFloatRegDouble(const StaticInst *si, int idx, double val)
164 {
165 this->cpu->setFloatRegDouble(_destRegIdx[idx], val);
166 this->instResult.dbl = val;
167 }
168
169 void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
170 {
171 this->cpu->setFloatRegInt(_destRegIdx[idx], val);
172 this->instResult.integer = val;
173 }
174
175 /** Returns the physical register index of the i'th destination
176 * register.
177 */
178 PhysRegIndex renamedDestRegIdx(int idx) const
179 {
180 return _destRegIdx[idx];
181 }
182
183 /** Returns the physical register index of the i'th source register. */
184 PhysRegIndex renamedSrcRegIdx(int idx) const
185 {
186 return _srcRegIdx[idx];
187 }
188
189 /** Returns the physical register index of the previous physical register
190 * that remapped to the same logical register index.
191 */
192 PhysRegIndex prevDestRegIdx(int idx) const
193 {
194 return _prevDestRegIdx[idx];
195 }
196
197 /** Renames a destination register to a physical register. Also records
198 * the previous physical register that the logical register mapped to.
199 */
200 void renameDestReg(int idx,
201 PhysRegIndex renamed_dest,
202 PhysRegIndex previous_rename)
203 {
204 _destRegIdx[idx] = renamed_dest;
205 _prevDestRegIdx[idx] = previous_rename;
206 }
207
208 /** Renames a source logical register to the physical register which
209 * has/will produce that logical register's result.
210 * @todo: add in whether or not the source register is ready.
211 */
212 void renameSrcReg(int idx, PhysRegIndex renamed_src)
213 {
214 _srcRegIdx[idx] = renamed_src;
215 }
216
217 public:
218 Fault calcEA()
219 {
220 return this->staticInst->eaCompInst()->execute(this, this->traceData);
221 }
222
223 Fault memAccess()
224 {
225 return this->staticInst->memAccInst()->execute(this, this->traceData);
226 }
227 };
228
229 #endif // __CPU_O3_CPU_ALPHA_DYN_INST_HH__
230