2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
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.
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.
29 #ifndef __CPU_BASE_DYN_INST_CC__
30 #define __CPU_BASE_DYN_INST_CC__
36 #include "base/cprintf.hh"
37 #include "base/trace.hh"
39 #include "arch/faults.hh"
40 #include "cpu/exetrace.hh"
41 #include "mem/mem_req.hh"
43 #include "cpu/base_dyn_inst.hh"
44 #include "cpu/o3/alpha_impl.hh"
45 #include "cpu/o3/alpha_cpu.hh"
48 using namespace TheISA
;
53 #include "base/hashmap.hh"
55 unsigned int MyHashFunc(const BaseDynInst
*addr
)
57 unsigned a
= (unsigned)addr
;
58 unsigned hash
= (((a
>> 14) ^ ((a
>> 2) & 0xffff))) & 0x7FFFFFFF;
63 typedef m5::hash_map
<const BaseDynInst
*, const BaseDynInst
*, MyHashFunc
> my_hash_t
;
68 BaseDynInst
<Impl
>::BaseDynInst(MachInst machInst
, Addr inst_PC
,
69 Addr pred_PC
, InstSeqNum seq_num
,
71 : staticInst(machInst
), traceData(NULL
), cpu(cpu
), cpuXC(cpu
->cpuXCBase())
76 nextPC
= PC
+ sizeof(MachInst
);
83 BaseDynInst
<Impl
>::BaseDynInst(StaticInstPtr
&_staticInst
)
84 : staticInst(_staticInst
), traceData(NULL
)
91 BaseDynInst
<Impl
>::initVars()
93 effAddr
= MemReq::inval_addr
;
94 physEffAddr
= MemReq::inval_addr
;
104 squashedInIQ
= false;
107 blockingInst
= false;
110 // Eventually make this a parameter.
113 // Also make this a parameter, or perhaps get it from xc or cpu.
116 // Initialize the fault to be unimplemented opcode.
117 fault
= new UnimplementedOpcodeFault
;
121 DPRINTF(FullCPU
, "DynInst: Instruction created. Instcount=%i\n",
125 template <class Impl
>
126 BaseDynInst
<Impl
>::~BaseDynInst()
129 DPRINTF(FullCPU
, "DynInst: Instruction destroyed. Instcount=%i\n",
133 template <class Impl
>
135 BaseDynInst
<Impl
>::prefetch(Addr addr
, unsigned flags
)
137 // This is the "functional" implementation of prefetch. Not much
138 // happens here since prefetches don't affect the architectural
141 // Generate a MemReq so we can translate the effective address.
142 MemReqPtr req
= new MemReq(addr
, cpuXC
->getProxy(), 1, flags
);
145 // Prefetches never cause faults.
148 // note this is a local, not BaseDynInst::fault
149 Fault trans_fault
= cpuXC
->translateDataReadReq(req
);
151 if (trans_fault
== NoFault
&& !(req
->flags
& UNCACHEABLE
)) {
152 // It's a valid address to cacheable space. Record key MemReq
153 // parameters so we can generate another one just like it for
154 // the timing access without calling translate() again (which
155 // might mess up the TLB).
156 effAddr
= req
->vaddr
;
157 physEffAddr
= req
->paddr
;
158 memReqFlags
= req
->flags
;
160 // Bogus address (invalid or uncacheable space). Mark it by
161 // setting the eff_addr to InvalidAddr.
162 effAddr
= physEffAddr
= MemReq::inval_addr
;
167 * Replace the disjoint functional memory with a unified one and remove
171 req
->paddr
= req
->vaddr
;
175 traceData
->setAddr(addr
);
179 template <class Impl
>
181 BaseDynInst
<Impl
>::writeHint(Addr addr
, int size
, unsigned flags
)
183 // Need to create a MemReq here so we can do a translation. This
184 // will casue a TLB miss trap if necessary... not sure whether
185 // that's the best thing to do or not. We don't really need the
186 // MemReq otherwise, since wh64 has no functional effect.
187 MemReqPtr req
= new MemReq(addr
, cpuXC
->getProxy(), size
, flags
);
190 fault
= cpuXC
->translateDataWriteReq(req
);
192 if (fault
== NoFault
&& !(req
->flags
& UNCACHEABLE
)) {
193 // Record key MemReq parameters so we can generate another one
194 // just like it for the timing access without calling translate()
195 // again (which might mess up the TLB).
196 effAddr
= req
->vaddr
;
197 physEffAddr
= req
->paddr
;
198 memReqFlags
= req
->flags
;
200 // ignore faults & accesses to uncacheable space... treat as no-op
201 effAddr
= physEffAddr
= MemReq::inval_addr
;
209 * @todo Need to find a way to get the cache block size here.
211 template <class Impl
>
213 BaseDynInst
<Impl
>::copySrcTranslate(Addr src
)
215 MemReqPtr req
= new MemReq(src
, cpuXC
->getProxy(), 64);
218 // translate to physical address
219 Fault fault
= cpuXC
->translateDataReadReq(req
);
221 if (fault
== NoFault
) {
222 cpuXC
->copySrcAddr
= src
;
223 cpuXC
->copySrcPhysAddr
= req
->paddr
;
225 cpuXC
->copySrcAddr
= 0;
226 cpuXC
->copySrcPhysAddr
= 0;
232 * @todo Need to find a way to get the cache block size here.
234 template <class Impl
>
236 BaseDynInst
<Impl
>::copy(Addr dest
)
239 FunctionalMemory
*mem
= cpuXC
->mem
;
240 assert(cpuXC
->copySrcPhysAddr
|| cpuXC
->misspeculating());
241 MemReqPtr req
= new MemReq(dest
, cpuXC
->getProxy(), 64);
244 // translate to physical address
245 Fault fault
= cpuXC
->translateDataWriteReq(req
);
247 if (fault
== NoFault
) {
248 Addr dest_addr
= req
->paddr
;
249 // Need to read straight from memory since we have more than 8 bytes.
250 req
->paddr
= cpuXC
->copySrcPhysAddr
;
251 mem
->read(req
, data
);
252 req
->paddr
= dest_addr
;
253 mem
->write(req
, data
);
258 template <class Impl
>
260 BaseDynInst
<Impl
>::dump()
262 cprintf("T%d : %#08d `", threadNumber
, PC
);
263 cout
<< staticInst
->disassemble(PC
);
267 template <class Impl
>
269 BaseDynInst
<Impl
>::dump(std::string
&outstring
)
271 std::ostringstream s
;
272 s
<< "T" << threadNumber
<< " : 0x" << PC
<< " "
273 << staticInst
->disassemble(PC
);
280 template <class Impl
>
282 BaseDynInst
<Impl
>::mem_access(mem_cmd cmd
, Addr addr
, void *p
, int nbytes
)
286 // check alignments, even speculative this test should always pass
287 if ((nbytes
& nbytes
- 1) != 0 || (addr
& nbytes
- 1) != 0) {
288 for (int i
= 0; i
< nbytes
; i
++)
291 // I added the following because according to the comment above,
292 // we should never get here. The comment lies
294 panic("unaligned access. Cycle = %n", curTick
);
299 MemReqPtr req
= new MemReq(addr
, thread
, nbytes
);
302 fault
= spec_mem
->read(req
, (uint8_t *)p
);
306 fault
= spec_mem
->write(req
, (uint8_t *)p
);
307 if (fault
!= NoFault
)
313 case sizeof(uint8_t):
314 *(uint8_t)&storeData
= (uint8_t *)p
;
316 case sizeof(uint16_t):
317 *(uint16_t)&storeData
= (uint16_t *)p
;
319 case sizeof(uint32_t):
320 *(uint32_t)&storeData
= (uint32_t *)p
;
322 case sizeof(uint64_t):
323 *(uint64_t)&storeData
= (uint64_t *)p
;
329 fault
= genMachineCheckFault();
333 trace_mem(fault
, cmd
, addr
, p
, nbytes
);
340 template <class Impl
>
342 BaseDynInst
<Impl
>::eaSrcsReady()
344 // For now I am assuming that src registers 1..n-1 are the ones that the
345 // EA calc depends on. (i.e. src reg 0 is the source of the data to be
348 for (int i
= 1; i
< numSrcRegs(); ++i
)
350 if (!_readySrcRegIdx
[i
])
357 // Forward declaration
358 template class BaseDynInst
<AlphaSimpleImpl
>;
362 BaseDynInst
<AlphaSimpleImpl
>::instcount
= 0;
364 #endif // __CPU_BASE_DYN_INST_CC__